summaryrefslogtreecommitdiffstats
path: root/Lib/importlib
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2024-03-19 12:36:19 (GMT)
committerGitHub <noreply@github.com>2024-03-19 12:36:19 (GMT)
commit408e127159e54d87bb3464fd8bd60219dc527fac (patch)
tree055bc39042521f314a7d225a22b3ca8ce403d453 /Lib/importlib
parenta5574789876987b2b9aa19294c735fe795a5b5c4 (diff)
downloadcpython-408e127159e54d87bb3464fd8bd60219dc527fac.zip
cpython-408e127159e54d87bb3464fd8bd60219dc527fac.tar.gz
cpython-408e127159e54d87bb3464fd8bd60219dc527fac.tar.bz2
gh-114099 - Add iOS framework loading machinery. (GH-116454)
Co-authored-by: Malcolm Smith <smith@chaquo.com> Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
Diffstat (limited to 'Lib/importlib')
-rw-r--r--Lib/importlib/_bootstrap_external.py53
-rw-r--r--Lib/importlib/abc.py6
-rw-r--r--Lib/importlib/machinery.py1
3 files changed, 56 insertions, 4 deletions
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index b26be85..4749a62 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -52,7 +52,7 @@ _pathseps_with_colon = {f':{s}' for s in path_separators}
# Bootstrap-related code ######################################################
_CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win',
-_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin'
+_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin', 'ios', 'tvos', 'watchos'
_CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY
+ _CASE_INSENSITIVE_PLATFORMS_STR_KEY)
@@ -1714,6 +1714,46 @@ class FileFinder:
return f'FileFinder({self.path!r})'
+class AppleFrameworkLoader(ExtensionFileLoader):
+ """A loader for modules that have been packaged as frameworks for
+ compatibility with Apple's iOS App Store policies.
+ """
+ def create_module(self, spec):
+ # If the ModuleSpec has been created by the FileFinder, it will have
+ # been created with an origin pointing to the .fwork file. We need to
+ # redirect this to the location in the Frameworks folder, using the
+ # content of the .fwork file.
+ if spec.origin.endswith(".fwork"):
+ with _io.FileIO(spec.origin, 'r') as file:
+ framework_binary = file.read().decode().strip()
+ bundle_path = _path_split(sys.executable)[0]
+ spec.origin = _path_join(bundle_path, framework_binary)
+
+ # If the loader is created based on the spec for a loaded module, the
+ # path will be pointing at the Framework location. If this occurs,
+ # get the original .fwork location to use as the module's __file__.
+ if self.path.endswith(".fwork"):
+ path = self.path
+ else:
+ with _io.FileIO(self.path + ".origin", 'r') as file:
+ origin = file.read().decode().strip()
+ bundle_path = _path_split(sys.executable)[0]
+ path = _path_join(bundle_path, origin)
+
+ module = _bootstrap._call_with_frames_removed(_imp.create_dynamic, spec)
+
+ _bootstrap._verbose_message(
+ "Apple framework extension module {!r} loaded from {!r} (path {!r})",
+ spec.name,
+ spec.origin,
+ path,
+ )
+
+ # Ensure that the __file__ points at the .fwork location
+ module.__file__ = path
+
+ return module
+
# Import setup ###############################################################
def _fix_up_module(ns, name, pathname, cpathname=None):
@@ -1746,10 +1786,17 @@ def _get_supported_file_loaders():
Each item is a tuple (loader, suffixes).
"""
- extensions = ExtensionFileLoader, _imp.extension_suffixes()
+ if sys.platform in {"ios", "tvos", "watchos"}:
+ extension_loaders = [(AppleFrameworkLoader, [
+ suffix.replace(".so", ".fwork")
+ for suffix in _imp.extension_suffixes()
+ ])]
+ else:
+ extension_loaders = []
+ extension_loaders.append((ExtensionFileLoader, _imp.extension_suffixes()))
source = SourceFileLoader, SOURCE_SUFFIXES
bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
- return [extensions, source, bytecode]
+ return extension_loaders + [source, bytecode]
def _set_bootstrap_module(_bootstrap_module):
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index b56fa94..37fef35 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -180,7 +180,11 @@ class ExecutionLoader(InspectLoader):
else:
return self.source_to_code(source, path)
-_register(ExecutionLoader, machinery.ExtensionFileLoader)
+_register(
+ ExecutionLoader,
+ machinery.ExtensionFileLoader,
+ machinery.AppleFrameworkLoader,
+)
class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader):
diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py
index d9a19a1..fbd30b1 100644
--- a/Lib/importlib/machinery.py
+++ b/Lib/importlib/machinery.py
@@ -12,6 +12,7 @@ from ._bootstrap_external import FileFinder
from ._bootstrap_external import SourceFileLoader
from ._bootstrap_external import SourcelessFileLoader
from ._bootstrap_external import ExtensionFileLoader
+from ._bootstrap_external import AppleFrameworkLoader
from ._bootstrap_external import NamespaceLoader