aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_importlib
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2024-03-19 20:36:19 +0800
committerGitHub <noreply@github.com>2024-03-19 08:36:19 -0400
commit408e127159e54d87bb3464fd8bd60219dc527fac (patch)
tree055bc39042521f314a7d225a22b3ca8ce403d453 /Lib/test/test_importlib
parenta5574789876987b2b9aa19294c735fe795a5b5c4 (diff)
downloadcpython-408e127159e54d87bb3464fd8bd60219dc527fac.tar.gz
cpython-408e127159e54d87bb3464fd8bd60219dc527fac.zip
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/test/test_importlib')
-rw-r--r--Lib/test/test_importlib/extension/test_finder.py25
-rw-r--r--Lib/test/test_importlib/extension/test_loader.py56
-rw-r--r--Lib/test/test_importlib/test_util.py11
-rw-r--r--Lib/test/test_importlib/util.py6
4 files changed, 74 insertions, 24 deletions
diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py
index 3de120958fd..cdc8884d668 100644
--- a/Lib/test/test_importlib/extension/test_finder.py
+++ b/Lib/test/test_importlib/extension/test_finder.py
@@ -1,3 +1,4 @@
+from test.support import is_apple_mobile
from test.test_importlib import abc, util
machinery = util.import_importlib('importlib.machinery')
@@ -19,9 +20,27 @@ class FinderTests(abc.FinderTests):
)
def find_spec(self, fullname):
- importer = self.machinery.FileFinder(util.EXTENSIONS.path,
- (self.machinery.ExtensionFileLoader,
- self.machinery.EXTENSION_SUFFIXES))
+ if is_apple_mobile:
+ # Apple mobile platforms require a specialist loader that uses
+ # .fwork files as placeholders for the true `.so` files.
+ loaders = [
+ (
+ self.machinery.AppleFrameworkLoader,
+ [
+ ext.replace(".so", ".fwork")
+ for ext in self.machinery.EXTENSION_SUFFIXES
+ ]
+ )
+ ]
+ else:
+ loaders = [
+ (
+ self.machinery.ExtensionFileLoader,
+ self.machinery.EXTENSION_SUFFIXES
+ )
+ ]
+
+ importer = self.machinery.FileFinder(util.EXTENSIONS.path, *loaders)
return importer.find_spec(fullname)
diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py
index f4879e75847..7607f0e0857 100644
--- a/Lib/test/test_importlib/extension/test_loader.py
+++ b/Lib/test/test_importlib/extension/test_loader.py
@@ -1,3 +1,4 @@
+from test.support import is_apple_mobile
from test.test_importlib import abc, util
machinery = util.import_importlib('importlib.machinery')
@@ -23,8 +24,15 @@ class LoaderTests:
raise unittest.SkipTest(
f"{util.EXTENSIONS.name} is a builtin module"
)
- self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
- util.EXTENSIONS.file_path)
+
+ # Apple extensions must be distributed as frameworks. This requires
+ # a specialist loader.
+ if is_apple_mobile:
+ self.LoaderClass = self.machinery.AppleFrameworkLoader
+ else:
+ self.LoaderClass = self.machinery.ExtensionFileLoader
+
+ self.loader = self.LoaderClass(util.EXTENSIONS.name, util.EXTENSIONS.file_path)
def load_module(self, fullname):
with warnings.catch_warnings():
@@ -32,13 +40,11 @@ class LoaderTests:
return self.loader.load_module(fullname)
def test_equality(self):
- other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
- util.EXTENSIONS.file_path)
+ other = self.LoaderClass(util.EXTENSIONS.name, util.EXTENSIONS.file_path)
self.assertEqual(self.loader, other)
def test_inequality(self):
- other = self.machinery.ExtensionFileLoader('_' + util.EXTENSIONS.name,
- util.EXTENSIONS.file_path)
+ other = self.LoaderClass('_' + util.EXTENSIONS.name, util.EXTENSIONS.file_path)
self.assertNotEqual(self.loader, other)
def test_load_module_API(self):
@@ -58,8 +64,7 @@ class LoaderTests:
('__package__', '')]:
self.assertEqual(getattr(module, attr), value)
self.assertIn(util.EXTENSIONS.name, sys.modules)
- self.assertIsInstance(module.__loader__,
- self.machinery.ExtensionFileLoader)
+ self.assertIsInstance(module.__loader__, self.LoaderClass)
# No extension module as __init__ available for testing.
test_package = None
@@ -86,7 +91,7 @@ class LoaderTests:
self.assertFalse(self.loader.is_package(util.EXTENSIONS.name))
for suffix in self.machinery.EXTENSION_SUFFIXES:
path = os.path.join('some', 'path', 'pkg', '__init__' + suffix)
- loader = self.machinery.ExtensionFileLoader('pkg', path)
+ loader = self.LoaderClass('pkg', path)
self.assertTrue(loader.is_package('pkg'))
@@ -101,6 +106,14 @@ class SinglePhaseExtensionModuleTests(abc.LoaderTests):
def setUp(self):
if not self.machinery.EXTENSION_SUFFIXES or not util.EXTENSIONS:
raise unittest.SkipTest("Requires dynamic loading support.")
+
+ # Apple extensions must be distributed as frameworks. This requires
+ # a specialist loader.
+ if is_apple_mobile:
+ self.LoaderClass = self.machinery.AppleFrameworkLoader
+ else:
+ self.LoaderClass = self.machinery.ExtensionFileLoader
+
self.name = '_testsinglephase'
if self.name in sys.builtin_module_names:
raise unittest.SkipTest(
@@ -109,8 +122,8 @@ class SinglePhaseExtensionModuleTests(abc.LoaderTests):
finder = self.machinery.FileFinder(None)
self.spec = importlib.util.find_spec(self.name)
assert self.spec
- self.loader = self.machinery.ExtensionFileLoader(
- self.name, self.spec.origin)
+
+ self.loader = self.LoaderClass(self.name, self.spec.origin)
def load_module(self):
with warnings.catch_warnings():
@@ -120,7 +133,7 @@ class SinglePhaseExtensionModuleTests(abc.LoaderTests):
def load_module_by_name(self, fullname):
# Load a module from the test extension by name.
origin = self.spec.origin
- loader = self.machinery.ExtensionFileLoader(fullname, origin)
+ loader = self.LoaderClass(fullname, origin)
spec = importlib.util.spec_from_loader(fullname, loader)
module = importlib.util.module_from_spec(spec)
loader.exec_module(module)
@@ -137,8 +150,7 @@ class SinglePhaseExtensionModuleTests(abc.LoaderTests):
with self.assertRaises(AttributeError):
module.__path__
self.assertIs(module, sys.modules[self.name])
- self.assertIsInstance(module.__loader__,
- self.machinery.ExtensionFileLoader)
+ self.assertIsInstance(module.__loader__, self.LoaderClass)
# No extension module as __init__ available for testing.
test_package = None
@@ -182,6 +194,14 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
def setUp(self):
if not self.machinery.EXTENSION_SUFFIXES or not util.EXTENSIONS:
raise unittest.SkipTest("Requires dynamic loading support.")
+
+ # Apple extensions must be distributed as frameworks. This requires
+ # a specialist loader.
+ if is_apple_mobile:
+ self.LoaderClass = self.machinery.AppleFrameworkLoader
+ else:
+ self.LoaderClass = self.machinery.ExtensionFileLoader
+
self.name = '_testmultiphase'
if self.name in sys.builtin_module_names:
raise unittest.SkipTest(
@@ -190,8 +210,7 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
finder = self.machinery.FileFinder(None)
self.spec = importlib.util.find_spec(self.name)
assert self.spec
- self.loader = self.machinery.ExtensionFileLoader(
- self.name, self.spec.origin)
+ self.loader = self.LoaderClass(self.name, self.spec.origin)
def load_module(self):
# Load the module from the test extension.
@@ -202,7 +221,7 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
def load_module_by_name(self, fullname):
# Load a module from the test extension by name.
origin = self.spec.origin
- loader = self.machinery.ExtensionFileLoader(fullname, origin)
+ loader = self.LoaderClass(fullname, origin)
spec = importlib.util.spec_from_loader(fullname, loader)
module = importlib.util.module_from_spec(spec)
loader.exec_module(module)
@@ -228,8 +247,7 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
with self.assertRaises(AttributeError):
module.__path__
self.assertIs(module, sys.modules[self.name])
- self.assertIsInstance(module.__loader__,
- self.machinery.ExtensionFileLoader)
+ self.assertIsInstance(module.__loader__, self.LoaderClass)
def test_functionality(self):
# Test basic functionality of stuff defined in an extension module.
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index a09286806e5..a6a76e58976 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -707,13 +707,20 @@ class IncompatibleExtensionModuleRestrictionsTests(unittest.TestCase):
@unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module")
def test_incomplete_multi_phase_init_module(self):
+ # Apple extensions must be distributed as frameworks. This requires
+ # a specialist loader.
+ if support.is_apple_mobile:
+ loader = "AppleFrameworkLoader"
+ else:
+ loader = "ExtensionFileLoader"
+
prescript = textwrap.dedent(f'''
from importlib.util import spec_from_loader, module_from_spec
- from importlib.machinery import ExtensionFileLoader
+ from importlib.machinery import {loader}
name = '_test_shared_gil_only'
filename = {_testmultiphase.__file__!r}
- loader = ExtensionFileLoader(name, filename)
+ loader = {loader}(name, filename)
spec = spec_from_loader(name, loader)
''')
diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py
index a900cc1dddf..89272484009 100644
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -8,6 +8,7 @@ import os
import os.path
from test import support
from test.support import import_helper
+from test.support import is_apple_mobile
from test.support import os_helper
import unittest
import sys
@@ -43,6 +44,11 @@ else:
global EXTENSIONS
for path in sys.path:
for ext in machinery.EXTENSION_SUFFIXES:
+ # Apple mobile platforms mechanically load .so files,
+ # but the findable files are labelled .fwork
+ if is_apple_mobile:
+ ext = ext.replace(".so", ".fwork")
+
filename = EXTENSIONS.name + ext
file_path = os.path.join(path, filename)
if os.path.exists(file_path):