mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Issue #23911: Move path-based bootstrap code to a separate frozen module.
This commit is contained in:
		
							parent
							
								
									6b4c63dea5
								
							
						
					
					
						commit
						32439d6eb6
					
				
					 27 changed files with 6192 additions and 5712 deletions
				
			
		|  | @ -59,8 +59,13 @@ class struct_frozen(Structure): | ||||||
|         items = [] |         items = [] | ||||||
|         # _frozen_importlib changes size whenever importlib._bootstrap |         # _frozen_importlib changes size whenever importlib._bootstrap | ||||||
|         # changes, so it gets a special case.  We should make sure it's |         # changes, so it gets a special case.  We should make sure it's | ||||||
|         # found, but don't worry about its size too much. |         # found, but don't worry about its size too much.  The same | ||||||
|         _fzn_implib_seen = False |         # applies to _frozen_importlib_external. | ||||||
|  |         bootstrap_seen = [] | ||||||
|  |         bootstrap_expected = ( | ||||||
|  |                 b'_frozen_importlib', | ||||||
|  |                 b'_frozen_importlib_external', | ||||||
|  |                 ) | ||||||
|         for entry in ft: |         for entry in ft: | ||||||
|             # This is dangerous. We *can* iterate over a pointer, but |             # This is dangerous. We *can* iterate over a pointer, but | ||||||
|             # the loop will not terminate (maybe with an access |             # the loop will not terminate (maybe with an access | ||||||
|  | @ -68,10 +73,10 @@ class struct_frozen(Structure): | ||||||
|             if entry.name is None: |             if entry.name is None: | ||||||
|                 break |                 break | ||||||
| 
 | 
 | ||||||
|             if entry.name == b'_frozen_importlib': |             if entry.name in bootstrap_expected: | ||||||
|                 _fzn_implib_seen = True |                 bootstrap_seen.append(entry.name) | ||||||
|                 self.assertTrue(entry.size, |                 self.assertTrue(entry.size, | ||||||
|                     "_frozen_importlib was reported as having no size") |                     "{} was reported as having no size".format(entry.name)) | ||||||
|                 continue |                 continue | ||||||
|             items.append((entry.name, entry.size)) |             items.append((entry.name, entry.size)) | ||||||
| 
 | 
 | ||||||
|  | @ -81,8 +86,8 @@ class struct_frozen(Structure): | ||||||
|                     ] |                     ] | ||||||
|         self.assertEqual(items, expected) |         self.assertEqual(items, expected) | ||||||
| 
 | 
 | ||||||
|         self.assertTrue(_fzn_implib_seen, |         self.assertEqual(sorted(bootstrap_seen), bootstrap_expected, | ||||||
|             "_frozen_importlib wasn't found in PyImport_FrozenModules") |             "frozen bootstrap modules did not match PyImport_FrozenModules") | ||||||
| 
 | 
 | ||||||
|         from ctypes import _pointer_type_cache |         from ctypes import _pointer_type_cache | ||||||
|         del _pointer_type_cache[struct_frozen] |         del _pointer_type_cache[struct_frozen] | ||||||
|  |  | ||||||
|  | @ -16,7 +16,8 @@ | ||||||
|     # Platform doesn't support dynamic loading. |     # Platform doesn't support dynamic loading. | ||||||
|     load_dynamic = None |     load_dynamic = None | ||||||
| 
 | 
 | ||||||
| from importlib._bootstrap import SourcelessFileLoader, _ERR_MSG, _exec, _load | from importlib._bootstrap import _ERR_MSG, _exec, _load | ||||||
|  | from importlib._bootstrap_external import SourcelessFileLoader | ||||||
| 
 | 
 | ||||||
| from importlib import machinery | from importlib import machinery | ||||||
| from importlib import util | from importlib import util | ||||||
|  |  | ||||||
|  | @ -30,9 +30,25 @@ | ||||||
|         pass |         pass | ||||||
|     sys.modules['importlib._bootstrap'] = _bootstrap |     sys.modules['importlib._bootstrap'] = _bootstrap | ||||||
| 
 | 
 | ||||||
|  | try: | ||||||
|  |     import _frozen_importlib_external as _bootstrap_external | ||||||
|  | except ImportError: | ||||||
|  |     from . import _bootstrap_external | ||||||
|  |     _bootstrap_external._setup(_bootstrap) | ||||||
|  | else: | ||||||
|  |     _bootstrap_external.__name__ = 'importlib._bootstrap_external' | ||||||
|  |     _bootstrap_external.__package__ = 'importlib' | ||||||
|  |     try: | ||||||
|  |         _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') | ||||||
|  |     except NameError: | ||||||
|  |         # __file__ is not guaranteed to be defined, e.g. if this code gets | ||||||
|  |         # frozen by a tool like cx_Freeze. | ||||||
|  |         pass | ||||||
|  |     sys.modules['importlib._bootstrap_external'] = _bootstrap_external | ||||||
|  | 
 | ||||||
| # To simplify imports in test code | # To simplify imports in test code | ||||||
| _w_long = _bootstrap._w_long | _w_long = _bootstrap_external._w_long | ||||||
| _r_long = _bootstrap._r_long | _r_long = _bootstrap_external._r_long | ||||||
| 
 | 
 | ||||||
| # Fully bootstrapped at this point, import whatever you like, circular | # Fully bootstrapped at this point, import whatever you like, circular | ||||||
| # dependencies and startup overhead minimisation permitting :) | # dependencies and startup overhead minimisation permitting :) | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1462
									
								
								Lib/importlib/_bootstrap_external.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1462
									
								
								Lib/importlib/_bootstrap_external.py
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,12 +1,17 @@ | ||||||
| """Abstract base classes related to import.""" | """Abstract base classes related to import.""" | ||||||
| from . import _bootstrap | from . import _bootstrap_external | ||||||
| from . import machinery | from . import machinery | ||||||
| try: | try: | ||||||
|     import _frozen_importlib |     import _frozen_importlib | ||||||
|  | #    import _frozen_importlib_external | ||||||
| except ImportError as exc: | except ImportError as exc: | ||||||
|     if exc.name != '_frozen_importlib': |     if exc.name != '_frozen_importlib': | ||||||
|         raise |         raise | ||||||
|     _frozen_importlib = None |     _frozen_importlib = None | ||||||
|  | try: | ||||||
|  |     import _frozen_importlib_external | ||||||
|  | except ImportError as exc: | ||||||
|  |     _frozen_importlib_external = _bootstrap_external | ||||||
| import abc | import abc | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -14,7 +19,10 @@ def _register(abstract_cls, *classes): | ||||||
|     for cls in classes: |     for cls in classes: | ||||||
|         abstract_cls.register(cls) |         abstract_cls.register(cls) | ||||||
|         if _frozen_importlib is not None: |         if _frozen_importlib is not None: | ||||||
|             frozen_cls = getattr(_frozen_importlib, cls.__name__) |             try: | ||||||
|  |                 frozen_cls = getattr(_frozen_importlib, cls.__name__) | ||||||
|  |             except AttributeError: | ||||||
|  |                 frozen_cls = getattr(_frozen_importlib_external, cls.__name__) | ||||||
|             abstract_cls.register(frozen_cls) |             abstract_cls.register(frozen_cls) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -102,7 +110,7 @@ def find_loader(self, fullname): | ||||||
|         else: |         else: | ||||||
|             return None, [] |             return None, [] | ||||||
| 
 | 
 | ||||||
|     find_module = _bootstrap._find_module_shim |     find_module = _bootstrap_external._find_module_shim | ||||||
| 
 | 
 | ||||||
|     def invalidate_caches(self): |     def invalidate_caches(self): | ||||||
|         """An optional method for clearing the finder's cache, if any. |         """An optional method for clearing the finder's cache, if any. | ||||||
|  | @ -144,7 +152,7 @@ def load_module(self, fullname): | ||||||
|         """ |         """ | ||||||
|         if not hasattr(self, 'exec_module'): |         if not hasattr(self, 'exec_module'): | ||||||
|             raise ImportError |             raise ImportError | ||||||
|         return _bootstrap._load_module_shim(self, fullname) |         return _bootstrap_external._load_module_shim(self, fullname) | ||||||
| 
 | 
 | ||||||
|     def module_repr(self, module): |     def module_repr(self, module): | ||||||
|         """Return a module's repr. |         """Return a module's repr. | ||||||
|  | @ -222,8 +230,8 @@ def source_to_code(data, path='<string>'): | ||||||
|         argument should be where the data was retrieved (when applicable).""" |         argument should be where the data was retrieved (when applicable).""" | ||||||
|         return compile(data, path, 'exec', dont_inherit=True) |         return compile(data, path, 'exec', dont_inherit=True) | ||||||
| 
 | 
 | ||||||
|     exec_module = _bootstrap._LoaderBasics.exec_module |     exec_module = _bootstrap_external._LoaderBasics.exec_module | ||||||
|     load_module = _bootstrap._LoaderBasics.load_module |     load_module = _bootstrap_external._LoaderBasics.load_module | ||||||
| 
 | 
 | ||||||
| _register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter) | _register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter) | ||||||
| 
 | 
 | ||||||
|  | @ -265,7 +273,7 @@ def get_code(self, fullname): | ||||||
| _register(ExecutionLoader, machinery.ExtensionFileLoader) | _register(ExecutionLoader, machinery.ExtensionFileLoader) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader): | class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader): | ||||||
| 
 | 
 | ||||||
|     """Abstract base class partially implementing the ResourceLoader and |     """Abstract base class partially implementing the ResourceLoader and | ||||||
|     ExecutionLoader ABCs.""" |     ExecutionLoader ABCs.""" | ||||||
|  | @ -274,7 +282,7 @@ class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader): | ||||||
|             machinery.SourcelessFileLoader) |             machinery.SourcelessFileLoader) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader): | class SourceLoader(_bootstrap_external.SourceLoader, ResourceLoader, ExecutionLoader): | ||||||
| 
 | 
 | ||||||
|     """Abstract base class for loading source code (and optionally any |     """Abstract base class for loading source code (and optionally any | ||||||
|     corresponding bytecode). |     corresponding bytecode). | ||||||
|  |  | ||||||
|  | @ -2,18 +2,18 @@ | ||||||
| 
 | 
 | ||||||
| import _imp | import _imp | ||||||
| 
 | 
 | ||||||
| from ._bootstrap import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, |  | ||||||
|                          OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, |  | ||||||
|                          EXTENSION_SUFFIXES) |  | ||||||
| from ._bootstrap import ModuleSpec | from ._bootstrap import ModuleSpec | ||||||
| from ._bootstrap import BuiltinImporter | from ._bootstrap import BuiltinImporter | ||||||
| from ._bootstrap import FrozenImporter | from ._bootstrap import FrozenImporter | ||||||
| from ._bootstrap import WindowsRegistryFinder | from ._bootstrap_external import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, | ||||||
| from ._bootstrap import PathFinder |                      OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, | ||||||
| from ._bootstrap import FileFinder |                      EXTENSION_SUFFIXES) | ||||||
| from ._bootstrap import SourceFileLoader | from ._bootstrap_external import WindowsRegistryFinder | ||||||
| from ._bootstrap import SourcelessFileLoader | from ._bootstrap_external import PathFinder | ||||||
| from ._bootstrap import ExtensionFileLoader | from ._bootstrap_external import FileFinder | ||||||
|  | from ._bootstrap_external import SourceFileLoader | ||||||
|  | from ._bootstrap_external import SourcelessFileLoader | ||||||
|  | from ._bootstrap_external import ExtensionFileLoader | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def all_suffixes(): | def all_suffixes(): | ||||||
|  |  | ||||||
|  | @ -1,14 +1,14 @@ | ||||||
| """Utility code for constructing importers, etc.""" | """Utility code for constructing importers, etc.""" | ||||||
| from . import abc | from . import abc | ||||||
| from ._bootstrap import MAGIC_NUMBER |  | ||||||
| from ._bootstrap import cache_from_source |  | ||||||
| from ._bootstrap import decode_source |  | ||||||
| from ._bootstrap import module_from_spec | from ._bootstrap import module_from_spec | ||||||
| from ._bootstrap import source_from_cache |  | ||||||
| from ._bootstrap import spec_from_loader |  | ||||||
| from ._bootstrap import spec_from_file_location |  | ||||||
| from ._bootstrap import _resolve_name | from ._bootstrap import _resolve_name | ||||||
|  | from ._bootstrap import spec_from_loader | ||||||
| from ._bootstrap import _find_spec | from ._bootstrap import _find_spec | ||||||
|  | from ._bootstrap_external import MAGIC_NUMBER | ||||||
|  | from ._bootstrap_external import cache_from_source | ||||||
|  | from ._bootstrap_external import decode_source | ||||||
|  | from ._bootstrap_external import source_from_cache | ||||||
|  | from ._bootstrap_external import spec_from_file_location | ||||||
| 
 | 
 | ||||||
| from contextlib import contextmanager | from contextlib import contextmanager | ||||||
| import functools | import functools | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| """Find modules used by a script, using introspection.""" | """Find modules used by a script, using introspection.""" | ||||||
| 
 | 
 | ||||||
| import dis | import dis | ||||||
| import importlib._bootstrap | import importlib._bootstrap_external | ||||||
| import importlib.machinery | import importlib.machinery | ||||||
| import marshal | import marshal | ||||||
| import os | import os | ||||||
|  | @ -289,7 +289,7 @@ def load_module(self, fqname, fp, pathname, file_info): | ||||||
|             co = compile(fp.read()+'\n', pathname, 'exec') |             co = compile(fp.read()+'\n', pathname, 'exec') | ||||||
|         elif type == imp.PY_COMPILED: |         elif type == imp.PY_COMPILED: | ||||||
|             try: |             try: | ||||||
|                 marshal_data = importlib._bootstrap._validate_bytecode_header(fp.read()) |                 marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read()) | ||||||
|             except ImportError as exc: |             except ImportError as exc: | ||||||
|                 self.msgout(2, "raise ImportError: " + str(exc), pathname) |                 self.msgout(2, "raise ImportError: " + str(exc), pathname) | ||||||
|                 raise |                 raise | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| This module has intimate knowledge of the format of .pyc files. | This module has intimate knowledge of the format of .pyc files. | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| import importlib._bootstrap | import importlib._bootstrap_external | ||||||
| import importlib.machinery | import importlib.machinery | ||||||
| import importlib.util | import importlib.util | ||||||
| import os | import os | ||||||
|  | @ -137,10 +137,10 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): | ||||||
|     except FileExistsError: |     except FileExistsError: | ||||||
|         pass |         pass | ||||||
|     source_stats = loader.path_stats(file) |     source_stats = loader.path_stats(file) | ||||||
|     bytecode = importlib._bootstrap._code_to_bytecode( |     bytecode = importlib._bootstrap_external._code_to_bytecode( | ||||||
|             code, source_stats['mtime'], source_stats['size']) |             code, source_stats['mtime'], source_stats['size']) | ||||||
|     mode = importlib._bootstrap._calc_mode(file) |     mode = importlib._bootstrap_external._calc_mode(file) | ||||||
|     importlib._bootstrap._write_atomic(cfile, bytecode, mode) |     importlib._bootstrap_external._write_atomic(cfile, bytecode, mode) | ||||||
|     return cfile |     return cfile | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -53,6 +53,7 @@ class or function within a module or module in a package.  If the | ||||||
| 
 | 
 | ||||||
| import builtins | import builtins | ||||||
| import importlib._bootstrap | import importlib._bootstrap | ||||||
|  | import importlib._bootstrap_external | ||||||
| import importlib.machinery | import importlib.machinery | ||||||
| import importlib.util | import importlib.util | ||||||
| import inspect | import inspect | ||||||
|  | @ -292,9 +293,9 @@ def importfile(path): | ||||||
|     filename = os.path.basename(path) |     filename = os.path.basename(path) | ||||||
|     name, ext = os.path.splitext(filename) |     name, ext = os.path.splitext(filename) | ||||||
|     if is_bytecode: |     if is_bytecode: | ||||||
|         loader = importlib._bootstrap.SourcelessFileLoader(name, path) |         loader = importlib._bootstrap_external.SourcelessFileLoader(name, path) | ||||||
|     else: |     else: | ||||||
|         loader = importlib._bootstrap.SourceFileLoader(name, path) |         loader = importlib._bootstrap_external.SourceFileLoader(name, path) | ||||||
|     # XXX We probably don't need to pass in the loader here. |     # XXX We probably don't need to pass in the loader here. | ||||||
|     spec = importlib.util.spec_from_file_location(name, path, loader=loader) |     spec = importlib.util.spec_from_file_location(name, path, loader=loader) | ||||||
|     try: |     try: | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ def __exit__(self, *args): | ||||||
|         self.value = self._sentinel |         self.value = self._sentinel | ||||||
|         sys.argv[0] = self._saved_value |         sys.argv[0] = self._saved_value | ||||||
| 
 | 
 | ||||||
| # TODO: Replace these helpers with importlib._bootstrap functions | # TODO: Replace these helpers with importlib._bootstrap_external functions. | ||||||
| def _run_code(code, run_globals, init_globals=None, | def _run_code(code, run_globals, init_globals=None, | ||||||
|               mod_name=None, mod_spec=None, |               mod_name=None, mod_spec=None, | ||||||
|               pkg_name=None, script_name=None): |               pkg_name=None, script_name=None): | ||||||
|  |  | ||||||
|  | @ -98,8 +98,8 @@ def makepath(*paths): | ||||||
| def abs_paths(): | def abs_paths(): | ||||||
|     """Set all module __file__ and __cached__ attributes to an absolute path""" |     """Set all module __file__ and __cached__ attributes to an absolute path""" | ||||||
|     for m in set(sys.modules.values()): |     for m in set(sys.modules.values()): | ||||||
|         if (getattr(getattr(m, '__loader__', None), '__module__', None) != |         if (getattr(getattr(m, '__loader__', None), '__module__', None) not in | ||||||
|                 '_frozen_importlib'): |                 ('_frozen_importlib', '_frozen_importlib_external')): | ||||||
|             continue   # don't mess with a PEP 302-supplied __file__ |             continue   # don't mess with a PEP 302-supplied __file__ | ||||||
|         try: |         try: | ||||||
|             m.__file__ = os.path.abspath(m.__file__) |             m.__file__ = os.path.abspath(m.__file__) | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| # We import importlib *ASAP* in order to test #15386 | # We import importlib *ASAP* in order to test #15386 | ||||||
| import importlib | import importlib | ||||||
| import importlib.util | import importlib.util | ||||||
| from importlib._bootstrap import _get_sourcefile | from importlib._bootstrap_external import _get_sourcefile | ||||||
| import builtins | import builtins | ||||||
| import marshal | import marshal | ||||||
| import os | import os | ||||||
|  | @ -845,19 +845,27 @@ def test_frozen_importlib_is_bootstrap(self): | ||||||
|         self.assertEqual(mod.__package__, 'importlib') |         self.assertEqual(mod.__package__, 'importlib') | ||||||
|         self.assertTrue(mod.__file__.endswith('_bootstrap.py'), mod.__file__) |         self.assertTrue(mod.__file__.endswith('_bootstrap.py'), mod.__file__) | ||||||
| 
 | 
 | ||||||
|  |     def test_frozen_importlib_external_is_bootstrap_external(self): | ||||||
|  |         from importlib import _bootstrap_external | ||||||
|  |         mod = sys.modules['_frozen_importlib_external'] | ||||||
|  |         self.assertIs(mod, _bootstrap_external) | ||||||
|  |         self.assertEqual(mod.__name__, 'importlib._bootstrap_external') | ||||||
|  |         self.assertEqual(mod.__package__, 'importlib') | ||||||
|  |         self.assertTrue(mod.__file__.endswith('_bootstrap_external.py'), mod.__file__) | ||||||
|  | 
 | ||||||
|     def test_there_can_be_only_one(self): |     def test_there_can_be_only_one(self): | ||||||
|         # Issue #15386 revealed a tricky loophole in the bootstrapping |         # Issue #15386 revealed a tricky loophole in the bootstrapping | ||||||
|         # This test is technically redundant, since the bug caused importing |         # This test is technically redundant, since the bug caused importing | ||||||
|         # this test module to crash completely, but it helps prove the point |         # this test module to crash completely, but it helps prove the point | ||||||
|         from importlib import machinery |         from importlib import machinery | ||||||
|         mod = sys.modules['_frozen_importlib'] |         mod = sys.modules['_frozen_importlib'] | ||||||
|         self.assertIs(machinery.FileFinder, mod.FileFinder) |         self.assertIs(machinery.ModuleSpec, mod.ModuleSpec) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @cpython_only | @cpython_only | ||||||
| class GetSourcefileTests(unittest.TestCase): | class GetSourcefileTests(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|     """Test importlib._bootstrap._get_sourcefile() as used by the C API. |     """Test importlib._bootstrap_external._get_sourcefile() as used by the C API. | ||||||
| 
 | 
 | ||||||
|     Because of the peculiarities of the need of this function, the tests are |     Because of the peculiarities of the need of this function, the tests are | ||||||
|     knowingly whitebox tests. |     knowingly whitebox tests. | ||||||
|  | @ -867,7 +875,7 @@ class GetSourcefileTests(unittest.TestCase): | ||||||
|     def test_get_sourcefile(self): |     def test_get_sourcefile(self): | ||||||
|         # Given a valid bytecode path, return the path to the corresponding |         # Given a valid bytecode path, return the path to the corresponding | ||||||
|         # source file if it exists. |         # source file if it exists. | ||||||
|         with mock.patch('importlib._bootstrap._path_isfile') as _path_isfile: |         with mock.patch('importlib._bootstrap_external._path_isfile') as _path_isfile: | ||||||
|             _path_isfile.return_value = True; |             _path_isfile.return_value = True; | ||||||
|             path = TESTFN + '.pyc' |             path = TESTFN + '.pyc' | ||||||
|             expect = TESTFN + '.py' |             expect = TESTFN + '.py' | ||||||
|  | @ -876,7 +884,7 @@ def test_get_sourcefile(self): | ||||||
|     def test_get_sourcefile_no_source(self): |     def test_get_sourcefile_no_source(self): | ||||||
|         # Given a valid bytecode path without a corresponding source path, |         # Given a valid bytecode path without a corresponding source path, | ||||||
|         # return the original bytecode path. |         # return the original bytecode path. | ||||||
|         with mock.patch('importlib._bootstrap._path_isfile') as _path_isfile: |         with mock.patch('importlib._bootstrap_external._path_isfile') as _path_isfile: | ||||||
|             _path_isfile.return_value = False; |             _path_isfile.return_value = False; | ||||||
|             path = TESTFN + '.pyc' |             path = TESTFN + '.pyc' | ||||||
|             self.assertEqual(_get_sourcefile(path), path) |             self.assertEqual(_get_sourcefile(path), path) | ||||||
|  | @ -1031,7 +1039,7 @@ def test_import_bug(self): | ||||||
|         # We simulate a bug in importlib and check that it's not stripped |         # We simulate a bug in importlib and check that it's not stripped | ||||||
|         # away from the traceback. |         # away from the traceback. | ||||||
|         self.create_module("foo", "") |         self.create_module("foo", "") | ||||||
|         importlib = sys.modules['_frozen_importlib'] |         importlib = sys.modules['_frozen_importlib_external'] | ||||||
|         if 'load_module' in vars(importlib.SourceLoader): |         if 'load_module' in vars(importlib.SourceLoader): | ||||||
|             old_exec_module = importlib.SourceLoader.exec_module |             old_exec_module = importlib.SourceLoader.exec_module | ||||||
|         else: |         else: | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| from importlib import _bootstrap | from importlib import _bootstrap_external | ||||||
| import sys | import sys | ||||||
| from test import support | from test import support | ||||||
| import unittest | import unittest | ||||||
|  | @ -26,7 +26,7 @@ def find_module(self): | ||||||
|     def test_case_sensitive(self): |     def test_case_sensitive(self): | ||||||
|         with support.EnvironmentVarGuard() as env: |         with support.EnvironmentVarGuard() as env: | ||||||
|             env.unset('PYTHONCASEOK') |             env.unset('PYTHONCASEOK') | ||||||
|             if b'PYTHONCASEOK' in _bootstrap._os.environ: |             if b'PYTHONCASEOK' in _bootstrap_external._os.environ: | ||||||
|                 self.skipTest('os.environ changes not reflected in ' |                 self.skipTest('os.environ changes not reflected in ' | ||||||
|                               '_os.environ') |                               '_os.environ') | ||||||
|             loader = self.find_module() |             loader = self.find_module() | ||||||
|  | @ -35,7 +35,7 @@ def test_case_sensitive(self): | ||||||
|     def test_case_insensitivity(self): |     def test_case_insensitivity(self): | ||||||
|         with support.EnvironmentVarGuard() as env: |         with support.EnvironmentVarGuard() as env: | ||||||
|             env.set('PYTHONCASEOK', '1') |             env.set('PYTHONCASEOK', '1') | ||||||
|             if b'PYTHONCASEOK' not in _bootstrap._os.environ: |             if b'PYTHONCASEOK' not in _bootstrap_external._os.environ: | ||||||
|                 self.skipTest('os.environ changes not reflected in ' |                 self.skipTest('os.environ changes not reflected in ' | ||||||
|                               '_os.environ') |                               '_os.environ') | ||||||
|             loader = self.find_module() |             loader = self.find_module() | ||||||
|  |  | ||||||
|  | @ -99,7 +99,7 @@ def test_None_on_sys_path(self): | ||||||
|         new_path_importer_cache.pop(None, None) |         new_path_importer_cache.pop(None, None) | ||||||
|         new_path_hooks = [zipimport.zipimporter, |         new_path_hooks = [zipimport.zipimporter, | ||||||
|                           self.machinery.FileFinder.path_hook( |                           self.machinery.FileFinder.path_hook( | ||||||
|                               *self.importlib._bootstrap._get_supported_file_loaders())] |                               *self.importlib._bootstrap_external._get_supported_file_loaders())] | ||||||
|         missing = object() |         missing = object() | ||||||
|         email = sys.modules.pop('email', missing) |         email = sys.modules.pop('email', missing) | ||||||
|         try: |         try: | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ def sensitivity_test(self): | ||||||
|     def test_sensitive(self): |     def test_sensitive(self): | ||||||
|         with test_support.EnvironmentVarGuard() as env: |         with test_support.EnvironmentVarGuard() as env: | ||||||
|             env.unset('PYTHONCASEOK') |             env.unset('PYTHONCASEOK') | ||||||
|             if b'PYTHONCASEOK' in self.importlib._bootstrap._os.environ: |             if b'PYTHONCASEOK' in self.importlib._bootstrap_external._os.environ: | ||||||
|                 self.skipTest('os.environ changes not reflected in ' |                 self.skipTest('os.environ changes not reflected in ' | ||||||
|                               '_os.environ') |                               '_os.environ') | ||||||
|             sensitive, insensitive = self.sensitivity_test() |             sensitive, insensitive = self.sensitivity_test() | ||||||
|  | @ -53,7 +53,7 @@ def test_sensitive(self): | ||||||
|     def test_insensitive(self): |     def test_insensitive(self): | ||||||
|         with test_support.EnvironmentVarGuard() as env: |         with test_support.EnvironmentVarGuard() as env: | ||||||
|             env.set('PYTHONCASEOK', '1') |             env.set('PYTHONCASEOK', '1') | ||||||
|             if b'PYTHONCASEOK' not in self.importlib._bootstrap._os.environ: |             if b'PYTHONCASEOK' not in self.importlib._bootstrap_external._os.environ: | ||||||
|                 self.skipTest('os.environ changes not reflected in ' |                 self.skipTest('os.environ changes not reflected in ' | ||||||
|                               '_os.environ') |                               '_os.environ') | ||||||
|             sensitive, insensitive = self.sensitivity_test() |             sensitive, insensitive = self.sensitivity_test() | ||||||
|  |  | ||||||
|  | @ -355,8 +355,10 @@ def test_abs_paths(self): | ||||||
|         stdout, stderr = proc.communicate() |         stdout, stderr = proc.communicate() | ||||||
|         self.assertEqual(proc.returncode, 0) |         self.assertEqual(proc.returncode, 0) | ||||||
|         os__file__, os__cached__ = stdout.splitlines()[:2] |         os__file__, os__cached__ = stdout.splitlines()[:2] | ||||||
|         self.assertTrue(os.path.isabs(os__file__)) |         self.assertTrue(os.path.isabs(os__file__), | ||||||
|         self.assertTrue(os.path.isabs(os__cached__)) |                         "expected absolute path, got {}".format(os__file__)) | ||||||
|  |         self.assertTrue(os.path.isabs(os__cached__), | ||||||
|  |                         "expected absolute path, got {}".format(os__cached__)) | ||||||
| 
 | 
 | ||||||
|     def test_no_duplicate_paths(self): |     def test_no_duplicate_paths(self): | ||||||
|         # No duplicate paths should exist in sys.path |         # No duplicate paths should exist in sys.path | ||||||
|  |  | ||||||
|  | @ -533,6 +533,7 @@ coverage-report: | ||||||
| 	: # force rebuilding of parser and importlib | 	: # force rebuilding of parser and importlib | ||||||
| 	@touch $(GRAMMAR_INPUT) | 	@touch $(GRAMMAR_INPUT) | ||||||
| 	@touch $(srcdir)/Lib/importlib/_bootstrap.py | 	@touch $(srcdir)/Lib/importlib/_bootstrap.py | ||||||
|  | 	@touch $(srcdir)/Lib/importlib/_bootstrap_external.py | ||||||
| 	: # build with coverage info | 	: # build with coverage info | ||||||
| 	$(MAKE) coverage | 	$(MAKE) coverage | ||||||
| 	: # run tests, ignore failures | 	: # run tests, ignore failures | ||||||
|  | @ -694,6 +695,10 @@ Programs/_freeze_importlib.o: Programs/_freeze_importlib.c Makefile | ||||||
| Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) | Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) | ||||||
| 	$(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) | 	$(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) | ||||||
| 
 | 
 | ||||||
|  | Python/importlib_external.h: $(srcdir)/Lib/importlib/_bootstrap_external.py Programs/_freeze_importlib | ||||||
|  | 	./Programs/_freeze_importlib \ | ||||||
|  | 		$(srcdir)/Lib/importlib/_bootstrap_external.py Python/importlib_external.h | ||||||
|  | 
 | ||||||
| Python/importlib.h: $(srcdir)/Lib/importlib/_bootstrap.py Programs/_freeze_importlib | Python/importlib.h: $(srcdir)/Lib/importlib/_bootstrap.py Programs/_freeze_importlib | ||||||
| 	./Programs/_freeze_importlib \ | 	./Programs/_freeze_importlib \ | ||||||
| 		$(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h | 		$(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h | ||||||
|  | @ -841,7 +846,7 @@ $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) | ||||||
| 
 | 
 | ||||||
| Python/ceval.o: $(OPCODETARGETS_H) $(srcdir)/Python/ceval_gil.h | Python/ceval.o: $(OPCODETARGETS_H) $(srcdir)/Python/ceval_gil.h | ||||||
| 
 | 
 | ||||||
| Python/frozen.o: Python/importlib.h | Python/frozen.o: Python/importlib.h Python/importlib_external.h | ||||||
| 
 | 
 | ||||||
| Objects/typeobject.o: Objects/typeslots.inc | Objects/typeobject.o: Objects/typeslots.inc | ||||||
| Objects/typeslots.inc: $(srcdir)/Include/typeslots.h $(srcdir)/Objects/typeslots.py | Objects/typeslots.inc: $(srcdir)/Include/typeslots.h $(srcdir)/Objects/typeslots.py | ||||||
|  |  | ||||||
|  | @ -15,6 +15,9 @@ Core and Builtins | ||||||
| 
 | 
 | ||||||
| - Issue #23910: Optimize property() getter calls.  Patch by Joe Jevnik. | - Issue #23910: Optimize property() getter calls.  Patch by Joe Jevnik. | ||||||
| 
 | 
 | ||||||
|  | - Issue #23911: Move path-based importlib bootstrap code to a separate | ||||||
|  |   frozen module. | ||||||
|  | 
 | ||||||
| - Issue #24022: Fix tokenizer crash when processing undecodable source code. | - Issue #24022: Fix tokenizer crash when processing undecodable source code. | ||||||
| 
 | 
 | ||||||
| - Issue #9951: Added a hex() method to bytes, bytearray, and memoryview. | - Issue #9951: Added a hex() method to bytes, bytearray, and memoryview. | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | int Py_FrozenFlag = 1;  /* Suppress errors from getpath.c */ | ||||||
| 
 | 
 | ||||||
| /* To avoid a circular dependency on frozen.o, we create our own structure
 | /* To avoid a circular dependency on frozen.o, we create our own structure
 | ||||||
|    of frozen modules instead, left deliberately blank so as to avoid |    of frozen modules instead, left deliberately blank so as to avoid | ||||||
|  | @ -33,13 +34,14 @@ const char header[] = "/* Auto-generated by Programs/_freeze_importlib.c */"; | ||||||
| int | int | ||||||
| main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||||
| { | { | ||||||
|     char *inpath, *outpath; |     char *inpath, *outpath, *code_name; | ||||||
|     FILE *infile = NULL, *outfile = NULL; |     FILE *infile = NULL, *outfile = NULL; | ||||||
|     struct _Py_stat_struct status; |     struct _Py_stat_struct status; | ||||||
|     size_t text_size, data_size, n; |     size_t text_size, data_size, n; | ||||||
|     char *text = NULL; |     char *text = NULL; | ||||||
|     unsigned char *data; |     unsigned char *data; | ||||||
|     PyObject *code = NULL, *marshalled = NULL; |     PyObject *code = NULL, *marshalled = NULL; | ||||||
|  |     int is_bootstrap = 1; | ||||||
| 
 | 
 | ||||||
|     PyImport_FrozenModules = _PyImport_FrozenModules; |     PyImport_FrozenModules = _PyImport_FrozenModules; | ||||||
| 
 | 
 | ||||||
|  | @ -82,8 +84,14 @@ main(int argc, char *argv[]) | ||||||
|     /* Don't install importlib, since it could execute outdated bytecode. */ |     /* Don't install importlib, since it could execute outdated bytecode. */ | ||||||
|     _Py_InitializeEx_Private(1, 0); |     _Py_InitializeEx_Private(1, 0); | ||||||
| 
 | 
 | ||||||
|     code = Py_CompileStringExFlags(text, "<frozen importlib._bootstrap>", |     if (strstr(inpath, "_external") != NULL) { | ||||||
|                                    Py_file_input, NULL, 0); |         is_bootstrap = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     code_name = is_bootstrap ? | ||||||
|  |         "<frozen importlib._bootstrap>" : | ||||||
|  |         "<frozen importlib._bootstrap_external>"; | ||||||
|  |     code = Py_CompileStringExFlags(text, code_name, Py_file_input, NULL, 0); | ||||||
|     if (code == NULL) |     if (code == NULL) | ||||||
|         goto error; |         goto error; | ||||||
|     free(text); |     free(text); | ||||||
|  | @ -106,7 +114,11 @@ main(int argc, char *argv[]) | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
|     fprintf(outfile, "%s\n", header); |     fprintf(outfile, "%s\n", header); | ||||||
|     fprintf(outfile, "const unsigned char _Py_M__importlib[] = {\n"); |     if (is_bootstrap) | ||||||
|  |         fprintf(outfile, "const unsigned char _Py_M__importlib[] = {\n"); | ||||||
|  |     else | ||||||
|  |         fprintf(outfile, | ||||||
|  |                 "const unsigned char _Py_M__importlib_external[] = {\n"); | ||||||
|     for (n = 0; n < data_size; n += 16) { |     for (n = 0; n < data_size; n += 16) { | ||||||
|         size_t i, end = Py_MIN(n + 16, data_size); |         size_t i, end = Py_MIN(n + 16, data_size); | ||||||
|         fprintf(outfile, "    "); |         fprintf(outfile, "    "); | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "Python.h" | #include "Python.h" | ||||||
| #include "importlib.h" | #include "importlib.h" | ||||||
|  | #include "importlib_external.h" | ||||||
| 
 | 
 | ||||||
| /* In order to test the support for frozen modules, by default we
 | /* In order to test the support for frozen modules, by default we
 | ||||||
|    define a single frozen module, __hello__.  Loading it will print |    define a single frozen module, __hello__.  Loading it will print | ||||||
|  | @ -31,6 +32,8 @@ static unsigned char M___hello__[] = { | ||||||
| static const struct _frozen _PyImport_FrozenModules[] = { | static const struct _frozen _PyImport_FrozenModules[] = { | ||||||
|     /* importlib */ |     /* importlib */ | ||||||
|     {"_frozen_importlib", _Py_M__importlib, (int)sizeof(_Py_M__importlib)}, |     {"_frozen_importlib", _Py_M__importlib, (int)sizeof(_Py_M__importlib)}, | ||||||
|  |     {"_frozen_importlib_external", _Py_M__importlib_external, | ||||||
|  |         (int)sizeof(_Py_M__importlib_external)}, | ||||||
|     /* Test module */ |     /* Test module */ | ||||||
|     {"__hello__", M___hello__, SIZE}, |     {"__hello__", M___hello__, SIZE}, | ||||||
|     /* Test package (negative size indicates package-ness) */ |     /* Test package (negative size indicates package-ness) */ | ||||||
|  |  | ||||||
|  | @ -491,8 +491,13 @@ PyImport_GetMagicNumber(void) | ||||||
| { | { | ||||||
|     long res; |     long res; | ||||||
|     PyInterpreterState *interp = PyThreadState_Get()->interp; |     PyInterpreterState *interp = PyThreadState_Get()->interp; | ||||||
|     PyObject *pyc_magic = PyObject_GetAttrString(interp->importlib, |     PyObject *external, *pyc_magic; | ||||||
|                                                  "_RAW_MAGIC_NUMBER"); | 
 | ||||||
|  |     external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); | ||||||
|  |     if (external == NULL) | ||||||
|  |         return -1; | ||||||
|  |     pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); | ||||||
|  |     Py_DECREF(external); | ||||||
|     if (pyc_magic == NULL) |     if (pyc_magic == NULL) | ||||||
|         return -1; |         return -1; | ||||||
|     res = PyLong_AsLong(pyc_magic); |     res = PyLong_AsLong(pyc_magic); | ||||||
|  | @ -737,7 +742,7 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, | ||||||
|                                      const char *cpathname) |                                      const char *cpathname) | ||||||
| { | { | ||||||
|     PyObject *m = NULL; |     PyObject *m = NULL; | ||||||
|     PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL; |     PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; | ||||||
| 
 | 
 | ||||||
|     nameobj = PyUnicode_FromString(name); |     nameobj = PyUnicode_FromString(name); | ||||||
|     if (nameobj == NULL) |     if (nameobj == NULL) | ||||||
|  | @ -765,9 +770,14 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, | ||||||
|                           "no interpreter!"); |                           "no interpreter!"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pathobj = _PyObject_CallMethodIdObjArgs(interp->importlib, |         external= PyObject_GetAttrString(interp->importlib, | ||||||
|                                                 &PyId__get_sourcefile, cpathobj, |                                          "_bootstrap_external"); | ||||||
|                                                 NULL); |         if (external != NULL) { | ||||||
|  |             pathobj = _PyObject_CallMethodIdObjArgs(external, | ||||||
|  |                                                     &PyId__get_sourcefile, cpathobj, | ||||||
|  |                                                     NULL); | ||||||
|  |             Py_DECREF(external); | ||||||
|  |         } | ||||||
|         if (pathobj == NULL) |         if (pathobj == NULL) | ||||||
|             PyErr_Clear(); |             PyErr_Clear(); | ||||||
|     } |     } | ||||||
|  | @ -833,7 +843,7 @@ PyObject* | ||||||
| PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, | PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, | ||||||
|                               PyObject *cpathname) |                               PyObject *cpathname) | ||||||
| { | { | ||||||
|     PyObject *d, *res; |     PyObject *d, *external, *res; | ||||||
|     PyInterpreterState *interp = PyThreadState_GET()->interp; |     PyInterpreterState *interp = PyThreadState_GET()->interp; | ||||||
|     _Py_IDENTIFIER(_fix_up_module); |     _Py_IDENTIFIER(_fix_up_module); | ||||||
| 
 | 
 | ||||||
|  | @ -845,9 +855,13 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, | ||||||
|     if (pathname == NULL) { |     if (pathname == NULL) { | ||||||
|         pathname = ((PyCodeObject *)co)->co_filename; |         pathname = ((PyCodeObject *)co)->co_filename; | ||||||
|     } |     } | ||||||
|     res = _PyObject_CallMethodIdObjArgs(interp->importlib, |     external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); | ||||||
|  |     if (external == NULL) | ||||||
|  |         return NULL; | ||||||
|  |     res = _PyObject_CallMethodIdObjArgs(external, | ||||||
|                                         &PyId__fix_up_module, |                                         &PyId__fix_up_module, | ||||||
|                                         d, name, pathname, cpathname, NULL); |                                         d, name, pathname, cpathname, NULL); | ||||||
|  |     Py_DECREF(external); | ||||||
|     if (res != NULL) { |     if (res != NULL) { | ||||||
|         Py_DECREF(res); |         Py_DECREF(res); | ||||||
|         res = exec_code_in_module(name, d, co); |         res = exec_code_in_module(name, d, co); | ||||||
|  | @ -1245,6 +1259,7 @@ static void | ||||||
| remove_importlib_frames(void) | remove_importlib_frames(void) | ||||||
| { | { | ||||||
|     const char *importlib_filename = "<frozen importlib._bootstrap>"; |     const char *importlib_filename = "<frozen importlib._bootstrap>"; | ||||||
|  |     const char *external_filename = "<frozen importlib._bootstrap_external>"; | ||||||
|     const char *remove_frames = "_call_with_frames_removed"; |     const char *remove_frames = "_call_with_frames_removed"; | ||||||
|     int always_trim = 0; |     int always_trim = 0; | ||||||
|     int in_importlib = 0; |     int in_importlib = 0; | ||||||
|  | @ -1274,7 +1289,10 @@ remove_importlib_frames(void) | ||||||
|         assert(PyTraceBack_Check(tb)); |         assert(PyTraceBack_Check(tb)); | ||||||
|         now_in_importlib = (PyUnicode_CompareWithASCIIString( |         now_in_importlib = (PyUnicode_CompareWithASCIIString( | ||||||
|                                 code->co_filename, |                                 code->co_filename, | ||||||
|                                 importlib_filename) == 0); |                                 importlib_filename) == 0) || | ||||||
|  |                            (PyUnicode_CompareWithASCIIString( | ||||||
|  |                                 code->co_filename, | ||||||
|  |                                 external_filename) == 0); | ||||||
|         if (now_in_importlib && !in_importlib) { |         if (now_in_importlib && !in_importlib) { | ||||||
|             /* This is the link to this chunk of importlib tracebacks */ |             /* This is the link to this chunk of importlib tracebacks */ | ||||||
|             outer_link = prev_link; |             outer_link = prev_link; | ||||||
|  |  | ||||||
							
								
								
									
										6227
									
								
								Python/importlib.h
									
										
									
									
									
								
							
							
						
						
									
										6227
									
								
								Python/importlib.h
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										2633
									
								
								Python/importlib_external.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2633
									
								
								Python/importlib_external.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -304,7 +304,7 @@ set_main_loader(PyObject *d, const char *filename, const char *loader_name) | ||||||
| { | { | ||||||
|     PyInterpreterState *interp; |     PyInterpreterState *interp; | ||||||
|     PyThreadState *tstate; |     PyThreadState *tstate; | ||||||
|     PyObject *filename_obj, *loader_type, *loader; |     PyObject *filename_obj, *bootstrap, *loader_type = NULL, *loader; | ||||||
|     int result = 0; |     int result = 0; | ||||||
| 
 | 
 | ||||||
|     filename_obj = PyUnicode_DecodeFSDefault(filename); |     filename_obj = PyUnicode_DecodeFSDefault(filename); | ||||||
|  | @ -313,7 +313,12 @@ set_main_loader(PyObject *d, const char *filename, const char *loader_name) | ||||||
|     /* Get current thread state and interpreter pointer */ |     /* Get current thread state and interpreter pointer */ | ||||||
|     tstate = PyThreadState_GET(); |     tstate = PyThreadState_GET(); | ||||||
|     interp = tstate->interp; |     interp = tstate->interp; | ||||||
|     loader_type = PyObject_GetAttrString(interp->importlib, loader_name); |     bootstrap = PyObject_GetAttrString(interp->importlib, | ||||||
|  |                                        "_bootstrap_external"); | ||||||
|  |     if (bootstrap != NULL) { | ||||||
|  |         loader_type = PyObject_GetAttrString(bootstrap, loader_name); | ||||||
|  |         Py_DECREF(bootstrap); | ||||||
|  |     } | ||||||
|     if (loader_type == NULL) { |     if (loader_type == NULL) { | ||||||
|         Py_DECREF(filename_obj); |         Py_DECREF(filename_obj); | ||||||
|         return -1; |         return -1; | ||||||
|  |  | ||||||
|  | @ -366,8 +366,10 @@ def main(): | ||||||
|             mf.load_file(mod) |             mf.load_file(mod) | ||||||
| 
 | 
 | ||||||
|     # Alias "importlib._bootstrap" to "_frozen_importlib" so that the |     # Alias "importlib._bootstrap" to "_frozen_importlib" so that the | ||||||
|     # import machinery can bootstrap. |     # import machinery can bootstrap.  Do the same for | ||||||
|  |     # importlib._bootstrap_external. | ||||||
|     mf.modules["_frozen_importlib"] = mf.modules["importlib._bootstrap"] |     mf.modules["_frozen_importlib"] = mf.modules["importlib._bootstrap"] | ||||||
|  |     mf.modules["_frozen_importlib_external"] = mf.modules["importlib._bootstrap_external"] | ||||||
| 
 | 
 | ||||||
|     # Add the main script as either __main__, or the actual module name. |     # Add the main script as either __main__, or the actual module name. | ||||||
|     if python_entry_is_main: |     if python_entry_is_main: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric Snow
						Eric Snow