]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-135966: Modify iOS testbed to make app_packages a site directory (GH-135967...
authorRussell Keith-Magee <russell@keith-magee.com>
Fri, 27 Jun 2025 05:37:05 +0000 (13:37 +0800)
committerGitHub <noreply@github.com>
Fri, 27 Jun 2025 05:37:05 +0000 (13:37 +0800)
The iOS testbed now treats the app_packages folder as a site folder. This ensures it is
on the path, but also ensures any .pth files are processed on app startup.
(cherry picked from commit b38810bab76c11ea09260a817b3354aebc2af580)

Doc/using/ios.rst
Misc/NEWS.d/next/Tests/2025-06-26-15-15-35.gh-issue-135966.EBpF8Y.rst [new file with mode: 0644]
iOS/testbed/iOSTestbedTests/iOSTestbedTests.m

index dff694941d0aebc0f5cb04d49267155fe5350074..685d8e81add26c612408427e83fce0de73ef47ef 100644 (file)
@@ -296,9 +296,9 @@ To add Python to an iOS Xcode project:
    * Buffered stdio (:c:member:`PyConfig.buffered_stdio`) is *disabled*;
    * Writing bytecode (:c:member:`PyConfig.write_bytecode`) is *disabled*;
    * Signal handlers (:c:member:`PyConfig.install_signal_handlers`) are *enabled*;
-   * ``PYTHONHOME`` for the interpreter is configured to point at the
+   * :envvar:`PYTHONHOME` for the interpreter is configured to point at the
      ``python`` subfolder of your app's bundle; and
-   * The ``PYTHONPATH`` for the interpreter includes:
+   * The :envvar:`PYTHONPATH` for the interpreter includes:
 
      - the ``python/lib/python3.X`` subfolder of your app's bundle,
      - the ``python/lib/python3.X/lib-dynload`` subfolder of your app's bundle, and
@@ -322,7 +322,12 @@ modules in your app, some additional steps will be required:
   the ``lib-dynload`` folder can be copied and adapted for this purpose.
 
 * If you're using a separate folder for third-party packages, ensure that folder
-  is included as part of the ``PYTHONPATH`` configuration in step 10.
+  is included as part of the :envvar:`PYTHONPATH` configuration in step 10.
+
+* If any of the folders that contain third-party packages will contain ``.pth``
+  files, you should add that folder as a *site directory* (using
+  :meth:`site.addsitedir`), rather than adding to :envvar:`PYTHONPATH` or
+  :attr:`sys.path` directly.
 
 Testing a Python package
 ------------------------
diff --git a/Misc/NEWS.d/next/Tests/2025-06-26-15-15-35.gh-issue-135966.EBpF8Y.rst b/Misc/NEWS.d/next/Tests/2025-06-26-15-15-35.gh-issue-135966.EBpF8Y.rst
new file mode 100644 (file)
index 0000000..8dc0074
--- /dev/null
@@ -0,0 +1 @@
+The iOS testbed now handles the ``app_packages`` folder as a site directory.
index d417b4cd63e2d49bd64df1706bea4745cf8e750c..294a06f530501c0b53dd45697815e17c5bebf009 100644 (file)
     PyStatus status;
     PyPreConfig preconfig;
     PyConfig config;
+    PyObject *app_packages_path;
+    PyObject *method_args;
+    PyObject *result;
+    PyObject *site_module;
+    PyObject *site_addsitedir_attr;
     PyObject *sys_module;
     PyObject *sys_path_attr;
     NSArray *test_args;
         return;
     }
 
-    sys_module = PyImport_ImportModule("sys");
-    if (sys_module == NULL) {
-        XCTFail(@"Could not import sys module");
+    // Add app_packages as a site directory. This both adds to sys.path,
+    // and ensures that any .pth files in that directory will be executed.
+    site_module = PyImport_ImportModule("site");
+    if (site_module == NULL) {
+        XCTFail(@"Could not import site module");
         return;
     }
 
-    sys_path_attr = PyObject_GetAttrString(sys_module, "path");
-    if (sys_path_attr == NULL) {
-        XCTFail(@"Could not access sys.path");
+    site_addsitedir_attr = PyObject_GetAttrString(site_module, "addsitedir");
+    if (site_addsitedir_attr == NULL || !PyCallable_Check(site_addsitedir_attr)) {
+        XCTFail(@"Could not access site.addsitedir");
         return;
     }
 
-    // Add the app packages path
     path = [NSString stringWithFormat:@"%@/app_packages", resourcePath, nil];
     NSLog(@"App packages path: %@", path);
     wtmp_str = Py_DecodeLocale([path UTF8String], NULL);
-    failed = PyList_Insert(sys_path_attr, 0, PyUnicode_FromString([path UTF8String]));
-    if (failed) {
-        XCTFail(@"Unable to add app packages to sys.path");
+    app_packages_path = PyUnicode_FromWideChar(wtmp_str, wcslen(wtmp_str));
+    if (app_packages_path == NULL) {
+        XCTFail(@"Could not convert app_packages path to unicode");
         return;
     }
     PyMem_RawFree(wtmp_str);
 
+    method_args = Py_BuildValue("(O)", app_packages_path);
+    if (method_args == NULL) {
+        XCTFail(@"Could not create arguments for site.addsitedir");
+        return;
+    }
+
+    result = PyObject_CallObject(site_addsitedir_attr, method_args);
+    if (result == NULL) {
+        XCTFail(@"Could not add app_packages directory using site.addsitedir");
+        return;
+    }
+
+    // Add test code to sys.path
+    sys_module = PyImport_ImportModule("sys");
+    if (sys_module == NULL) {
+        XCTFail(@"Could not import sys module");
+        return;
+    }
+
+    sys_path_attr = PyObject_GetAttrString(sys_module, "path");
+    if (sys_path_attr == NULL) {
+        XCTFail(@"Could not access sys.path");
+        return;
+    }
+
     path = [NSString stringWithFormat:@"%@/app", resourcePath, nil];
     NSLog(@"App path: %@", path);
     wtmp_str = Py_DecodeLocale([path UTF8String], NULL);