diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2021-10-01 00:38:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-01 00:38:52 (GMT) |
commit | 7e5c107541726b90d3f2e6e69ef37180cf58335d (patch) | |
tree | a6f6a4000b9217be777e8f680e0ec9c2f107eaf3 | |
parent | ec4d917a6a68824f1895f75d113add9410283da7 (diff) | |
download | cpython-7e5c107541726b90d3f2e6e69ef37180cf58335d.zip cpython-7e5c107541726b90d3f2e6e69ef37180cf58335d.tar.gz cpython-7e5c107541726b90d3f2e6e69ef37180cf58335d.tar.bz2 |
bpo-45020: Add more test cases for frozen modules. (gh-28664)
I've added a number of test-only modules. Some of those cases are covered by the recently frozen stdlib modules (and some will be once we add encodings back in). However, I figured we'd play it safe by having a set of modules guaranteed to be there during tests.
https://bugs.python.org/issue45020
-rw-r--r-- | Lib/__phello__.foo.py | 1 | ||||
-rw-r--r-- | Lib/__phello__/__init__.py | 7 | ||||
-rw-r--r-- | Lib/__phello__/ham/__init__.py | 0 | ||||
-rw-r--r-- | Lib/__phello__/ham/eggs.py | 0 | ||||
-rw-r--r-- | Lib/__phello__/spam.py | 7 | ||||
-rw-r--r-- | Lib/test/test_frozen.py | 28 | ||||
-rw-r--r-- | Lib/test/test_importlib/frozen/test_finder.py | 79 | ||||
-rw-r--r-- | Makefile.pre.in | 29 | ||||
-rw-r--r-- | PCbuild/_freeze_module.vcxproj | 25 | ||||
-rw-r--r-- | PCbuild/_freeze_module.vcxproj.filters | 15 | ||||
-rw-r--r-- | Python/frozen.c | 20 | ||||
-rw-r--r-- | Tools/scripts/freeze_modules.py | 15 | ||||
-rw-r--r-- | Tools/scripts/generate_stdlib_module_names.py | 3 |
13 files changed, 205 insertions, 24 deletions
diff --git a/Lib/__phello__.foo.py b/Lib/__phello__.foo.py deleted file mode 100644 index 8e8623e..0000000 --- a/Lib/__phello__.foo.py +++ /dev/null @@ -1 +0,0 @@ -# This file exists as a helper for the test.test_frozen module. diff --git a/Lib/__phello__/__init__.py b/Lib/__phello__/__init__.py new file mode 100644 index 0000000..d37bd27 --- /dev/null +++ b/Lib/__phello__/__init__.py @@ -0,0 +1,7 @@ +initialized = True + +def main(): + print("Hello world!") + +if __name__ == '__main__': + main() diff --git a/Lib/__phello__/ham/__init__.py b/Lib/__phello__/ham/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Lib/__phello__/ham/__init__.py diff --git a/Lib/__phello__/ham/eggs.py b/Lib/__phello__/ham/eggs.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Lib/__phello__/ham/eggs.py diff --git a/Lib/__phello__/spam.py b/Lib/__phello__/spam.py new file mode 100644 index 0000000..d37bd27 --- /dev/null +++ b/Lib/__phello__/spam.py @@ -0,0 +1,7 @@ +initialized = True + +def main(): + print("Hello world!") + +if __name__ == '__main__': + main() diff --git a/Lib/test/test_frozen.py b/Lib/test/test_frozen.py index 3d212b9..029fd06 100644 --- a/Lib/test/test_frozen.py +++ b/Lib/test/test_frozen.py @@ -10,6 +10,7 @@ # Invalid marshalled data in frozen.c could case the interpreter to # crash when __hello__ is imported. +import importlib.machinery import sys import unittest from test.support import captured_stdout, import_helper @@ -26,6 +27,33 @@ class TestFrozen(unittest.TestCase): __hello__.main() self.assertEqual(out.getvalue(), 'Hello world!\n') + def test_frozen_submodule_in_unfrozen_package(self): + with import_helper.CleanImport('__phello__', '__phello__.spam'): + with import_helper.frozen_modules(enabled=False): + import __phello__ + with import_helper.frozen_modules(enabled=True): + import __phello__.spam as spam + self.assertIs(spam, __phello__.spam) + self.assertIsNot(__phello__.__spec__.loader, + importlib.machinery.FrozenImporter) + self.assertIs(spam.__spec__.loader, + importlib.machinery.FrozenImporter) + + # This is not possible until frozen packages have __path__ set properly. + # See https://bugs.python.org/issue21736. + @unittest.expectedFailure + def test_unfrozen_submodule_in_frozen_package(self): + with import_helper.CleanImport('__phello__', '__phello__.spam'): + with import_helper.frozen_modules(enabled=True): + import __phello__ + with import_helper.frozen_modules(enabled=False): + import __phello__.spam as spam + self.assertIs(spam, __phello__.spam) + self.assertIs(__phello__.__spec__.loader, + importlib.machinery.FrozenImporter) + self.assertIsNot(spam.__spec__.loader, + importlib.machinery.FrozenImporter) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py index fbc3fc0..7d43fb0 100644 --- a/Lib/test/test_importlib/frozen/test_finder.py +++ b/Lib/test/test_importlib/frozen/test_finder.py @@ -1,4 +1,5 @@ from .. import abc +import os.path from .. import util machinery = util.import_importlib('importlib.machinery') @@ -13,34 +14,86 @@ class FindSpecTests(abc.FinderTests): """Test finding frozen modules.""" - def find(self, name, path=None): + def find(self, name, **kwargs): finder = self.machinery.FrozenImporter with import_helper.frozen_modules(): - return finder.find_spec(name, path) + return finder.find_spec(name, **kwargs) - def test_module(self): - name = '__hello__' - spec = self.find(name) + def check(self, spec, name): + self.assertEqual(spec.name, name) + self.assertIs(spec.loader, self.machinery.FrozenImporter) self.assertEqual(spec.origin, 'frozen') + self.assertFalse(spec.has_location) - def test_package(self): - spec = self.find('__phello__') - self.assertIsNotNone(spec) - - def test_module_in_package(self): - spec = self.find('__phello__.spam', ['__phello__']) - self.assertIsNotNone(spec) + def test_module(self): + names = [ + '__hello__', + '__hello_alias__', + '__hello_only__', + '__phello__.__init__', + '__phello__.spam', + '__phello__.ham.__init__', + '__phello__.ham.eggs', + ] + for name in names: + with self.subTest(name): + spec = self.find(name) + self.check(spec, name) + self.assertEqual(spec.submodule_search_locations, None) - # No frozen package within another package to test with. + def test_package(self): + names = [ + '__phello__', + '__phello__.ham', + '__phello_alias__', + ] + for name in names: + with self.subTest(name): + spec = self.find(name) + self.check(spec, name) + self.assertEqual(spec.submodule_search_locations, []) + + # These are covered by test_module() and test_package(). + test_module_in_package = None test_package_in_package = None # No easy way to test. test_package_over_module = None + def test_path_ignored(self): + for name in ('__hello__', '__phello__', '__phello__.spam'): + actual = self.find(name) + for path in (None, object(), '', 'eggs', [], [''], ['eggs']): + with self.subTest((name, path)): + spec = self.find(name, path=path) + self.assertEqual(spec, actual) + + def test_target_ignored(self): + imported = ('__hello__', '__phello__') + with import_helper.CleanImport(*imported, usefrozen=True): + import __hello__ as match + import __phello__ as nonmatch + name = '__hello__' + actual = self.find(name) + for target in (None, match, nonmatch, object(), 'not-a-module-object'): + with self.subTest(target): + spec = self.find(name, target=target) + self.assertEqual(spec, actual) + def test_failure(self): spec = self.find('<not real>') self.assertIsNone(spec) + def test_not_using_frozen(self): + finder = self.machinery.FrozenImporter + with import_helper.frozen_modules(enabled=False): + # both frozen and not frozen + spec1 = finder.find_spec('__hello__') + # only frozen + spec2 = finder.find_spec('__hello_only__') + self.assertIsNone(spec1) + self.assertIsNone(spec2) + (Frozen_FindSpecTests, Source_FindSpecTests diff --git a/Makefile.pre.in b/Makefile.pre.in index 5564c1b..7ad634a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -752,7 +752,12 @@ FROZEN_FILES_IN = \ Lib/os.py \ Lib/site.py \ Lib/stat.py \ - Lib/__hello__.py + Lib/__hello__.py \ + Lib/__phello__/__init__.py \ + Lib/__phello__/ham/__init__.py \ + Lib/__phello__/ham/eggs.py \ + Lib/__phello__/spam.py \ + Tools/freeze/flag.py # End FROZEN_FILES_IN FROZEN_FILES_OUT = \ Python/frozen_modules/importlib._bootstrap.h \ @@ -769,7 +774,12 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/os.h \ Python/frozen_modules/site.h \ Python/frozen_modules/stat.h \ - Python/frozen_modules/__hello__.h + Python/frozen_modules/__hello__.h \ + Python/frozen_modules/__phello__.h \ + Python/frozen_modules/__phello__.ham.h \ + Python/frozen_modules/__phello__.ham.eggs.h \ + Python/frozen_modules/__phello__.spam.h \ + Python/frozen_modules/frozen_only.h # End FROZEN_FILES_OUT Programs/_freeze_module.o: Programs/_freeze_module.c Makefile @@ -824,6 +834,21 @@ Python/frozen_modules/stat.h: Programs/_freeze_module Lib/stat.py Python/frozen_modules/__hello__.h: Programs/_freeze_module Lib/__hello__.py Programs/_freeze_module __hello__ $(srcdir)/Lib/__hello__.py $(srcdir)/Python/frozen_modules/__hello__.h +Python/frozen_modules/__phello__.h: Programs/_freeze_module Lib/__phello__/__init__.py + Programs/_freeze_module __phello__ $(srcdir)/Lib/__phello__/__init__.py $(srcdir)/Python/frozen_modules/__phello__.h + +Python/frozen_modules/__phello__.ham.h: Programs/_freeze_module Lib/__phello__/ham/__init__.py + Programs/_freeze_module __phello__.ham $(srcdir)/Lib/__phello__/ham/__init__.py $(srcdir)/Python/frozen_modules/__phello__.ham.h + +Python/frozen_modules/__phello__.ham.eggs.h: Programs/_freeze_module Lib/__phello__/ham/eggs.py + Programs/_freeze_module __phello__.ham.eggs $(srcdir)/Lib/__phello__/ham/eggs.py $(srcdir)/Python/frozen_modules/__phello__.ham.eggs.h + +Python/frozen_modules/__phello__.spam.h: Programs/_freeze_module Lib/__phello__/spam.py + Programs/_freeze_module __phello__.spam $(srcdir)/Lib/__phello__/spam.py $(srcdir)/Python/frozen_modules/__phello__.spam.h + +Python/frozen_modules/frozen_only.h: Programs/_freeze_module Tools/freeze/flag.py + Programs/_freeze_module frozen_only $(srcdir)/Tools/freeze/flag.py $(srcdir)/Python/frozen_modules/frozen_only.h + # END: freezing modules Tools/scripts/freeze_modules.py: Programs/_freeze_module diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index ea6532d..12bdde2 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -305,6 +305,31 @@ <IntFile>$(IntDir)__hello__.g.h</IntFile> <OutFile>$(PySourcePath)Python\frozen_modules\__hello__.h</OutFile> </None> + <None Include="..\Lib\__phello__\__init__.py"> + <ModName>__phello__</ModName> + <IntFile>$(IntDir)__phello__.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.h</OutFile> + </None> + <None Include="..\Lib\__phello__\ham\__init__.py"> + <ModName>__phello__.ham</ModName> + <IntFile>$(IntDir)__phello__.ham.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.ham.h</OutFile> + </None> + <None Include="..\Lib\__phello__\ham\eggs.py"> + <ModName>__phello__.ham.eggs</ModName> + <IntFile>$(IntDir)__phello__.ham.eggs.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.ham.eggs.h</OutFile> + </None> + <None Include="..\Lib\__phello__\spam.py"> + <ModName>__phello__.spam</ModName> + <IntFile>$(IntDir)__phello__.spam.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.spam.h</OutFile> + </None> + <None Include="..\Tools\freeze\flag.py"> + <ModName>frozen_only</ModName> + <IntFile>$(IntDir)frozen_only.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\frozen_only.h</OutFile> + </None> <!-- END frozen modules --> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 4a1c90f..5894909 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -61,6 +61,21 @@ <None Include="..\Lib\__hello__.py"> <Filter>Python Files</Filter> </None> + <None Include="..\Lib\__phello__\__init__.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\ham\__init__.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\ham\eggs.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\spam.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Tools\freeze\flag.py"> + <Filter>Python Files</Filter> + </None> <!-- END frozen modules --> </ItemGroup> </Project> diff --git a/Python/frozen.c b/Python/frozen.c index f9ad07c..b4f7121 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -53,6 +53,11 @@ #include "frozen_modules/site.h" #include "frozen_modules/stat.h" #include "frozen_modules/__hello__.h" +#include "frozen_modules/__phello__.h" +#include "frozen_modules/__phello__.ham.h" +#include "frozen_modules/__phello__.ham.eggs.h" +#include "frozen_modules/__phello__.spam.h" +#include "frozen_modules/frozen_only.h" /* End includes */ /* Note that a negative size indicates a package. */ @@ -84,8 +89,19 @@ static const struct _frozen _PyImport_FrozenModules[] = { /* Test module */ {"__hello__", _Py_M____hello__, (int)sizeof(_Py_M____hello__)}, - {"__phello__", _Py_M____hello__, -(int)sizeof(_Py_M____hello__)}, - {"__phello__.spam", _Py_M____hello__, (int)sizeof(_Py_M____hello__)}, + {"__hello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__)}, + {"__phello_alias__", _Py_M____hello__, -(int)sizeof(_Py_M____hello__)}, + {"__phello_alias__.spam", _Py_M____hello__, (int)sizeof(_Py_M____hello__)}, + {"__phello__", _Py_M____phello__, -(int)sizeof(_Py_M____phello__)}, + {"__phello__.__init__", _Py_M____phello__, (int)sizeof(_Py_M____phello__)}, + {"__phello__.ham", _Py_M____phello___ham, -(int)sizeof(_Py_M____phello___ham)}, + {"__phello__.ham.__init__", _Py_M____phello___ham, + (int)sizeof(_Py_M____phello___ham)}, + {"__phello__.ham.eggs", _Py_M____phello___ham_eggs, + (int)sizeof(_Py_M____phello___ham_eggs)}, + {"__phello__.spam", _Py_M____phello___spam, + (int)sizeof(_Py_M____phello___spam)}, + {"__hello_only__", _Py_M__frozen_only, (int)sizeof(_Py_M__frozen_only)}, {0, 0, 0} /* sentinel */ }; diff --git a/Tools/scripts/freeze_modules.py b/Tools/scripts/freeze_modules.py index ea96253..6091d83 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/scripts/freeze_modules.py @@ -19,6 +19,7 @@ from update_file import updating_file_with_tmpfile, update_file_with_tmpfile ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ROOT_DIR = os.path.abspath(ROOT_DIR) +FROZEN_ONLY = os.path.join(ROOT_DIR, 'Tools', 'freeze', 'flag.py') STDLIB_DIR = os.path.join(ROOT_DIR, 'Lib') # If MODULES_DIR is changed then the .gitattributes and .gitignore files @@ -53,7 +54,6 @@ FROZEN_FILE = os.path.join(ROOT_DIR, 'Python', 'frozen.c') MAKEFILE = os.path.join(ROOT_DIR, 'Makefile.pre.in') PCBUILD_PROJECT = os.path.join(ROOT_DIR, 'PCbuild', '_freeze_module.vcxproj') PCBUILD_FILTERS = os.path.join(ROOT_DIR, 'PCbuild', '_freeze_module.vcxproj.filters') -TEST_CTYPES = os.path.join(STDLIB_DIR, 'ctypes', 'test', 'test_values.py') OS_PATH = 'ntpath' if os.name == 'nt' else 'posixpath' @@ -95,8 +95,11 @@ FROZEN = [ ]), ('Test module', [ '__hello__', - '__hello__ : <__phello__>', - '__hello__ : __phello__.spam', + '__hello__ : __hello_alias__', + '__hello__ : <__phello_alias__>', + '__hello__ : __phello_alias__.spam', + '<__phello__.**.*>', + f'frozen_only : __hello_only__ = {FROZEN_ONLY}', ]), ] ESSENTIAL = { @@ -135,14 +138,15 @@ def parse_frozen_specs(sectionalspecs=FROZEN, destdir=None): seen = {} for section, specs in sectionalspecs: parsed = _parse_specs(specs, section, seen) - for frozenid, pyfile, modname, ispkg, section in parsed: + for item in parsed: + frozenid, pyfile, modname, ispkg, section = item try: source = seen[frozenid] except KeyError: source = FrozenSource.from_id(frozenid, pyfile, destdir) seen[frozenid] = source else: - assert not pyfile + assert not pyfile or pyfile == source.pyfile, item yield FrozenModule(modname, ispkg, section, source) @@ -224,7 +228,6 @@ def _parse_spec(spec, knownids=None, section=None): pkgfiles = {pyfile: pkgid} def iter_subs(): for frozenid, pyfile, ispkg in resolved: - assert not knownids or frozenid not in knownids, (frozenid, spec) if pkgname: modname = frozenid.replace(pkgid, pkgname, 1) else: diff --git a/Tools/scripts/generate_stdlib_module_names.py b/Tools/scripts/generate_stdlib_module_names.py index 325ae20..50042f1 100644 --- a/Tools/scripts/generate_stdlib_module_names.py +++ b/Tools/scripts/generate_stdlib_module_names.py @@ -21,6 +21,9 @@ IGNORE = { # Test modules and packages '__hello__', '__phello__', + '__hello_alias__', + '__phello_alias__', + '__hello_only__', '_ctypes_test', '_testbuffer', '_testcapi', |