Issue #23911: Move path-based bootstrap code to a separate frozen module.
This commit is contained in:
parent
6b4c63dea5
commit
32439d6eb6
|
@ -59,8 +59,13 @@ class Win_ValuesTestCase(unittest.TestCase):
|
|||
items = []
|
||||
# _frozen_importlib changes size whenever importlib._bootstrap
|
||||
# changes, so it gets a special case. We should make sure it's
|
||||
# found, but don't worry about its size too much.
|
||||
_fzn_implib_seen = False
|
||||
# found, but don't worry about its size too much. The same
|
||||
# applies to _frozen_importlib_external.
|
||||
bootstrap_seen = []
|
||||
bootstrap_expected = (
|
||||
b'_frozen_importlib',
|
||||
b'_frozen_importlib_external',
|
||||
)
|
||||
for entry in ft:
|
||||
# This is dangerous. We *can* iterate over a pointer, but
|
||||
# the loop will not terminate (maybe with an access
|
||||
|
@ -68,10 +73,10 @@ class Win_ValuesTestCase(unittest.TestCase):
|
|||
if entry.name is None:
|
||||
break
|
||||
|
||||
if entry.name == b'_frozen_importlib':
|
||||
_fzn_implib_seen = True
|
||||
if entry.name in bootstrap_expected:
|
||||
bootstrap_seen.append(entry.name)
|
||||
self.assertTrue(entry.size,
|
||||
"_frozen_importlib was reported as having no size")
|
||||
"{} was reported as having no size".format(entry.name))
|
||||
continue
|
||||
items.append((entry.name, entry.size))
|
||||
|
||||
|
@ -81,8 +86,8 @@ class Win_ValuesTestCase(unittest.TestCase):
|
|||
]
|
||||
self.assertEqual(items, expected)
|
||||
|
||||
self.assertTrue(_fzn_implib_seen,
|
||||
"_frozen_importlib wasn't found in PyImport_FrozenModules")
|
||||
self.assertEqual(sorted(bootstrap_seen), bootstrap_expected,
|
||||
"frozen bootstrap modules did not match PyImport_FrozenModules")
|
||||
|
||||
from ctypes import _pointer_type_cache
|
||||
del _pointer_type_cache[struct_frozen]
|
||||
|
|
|
@ -16,7 +16,8 @@ except ImportError:
|
|||
# Platform doesn't support dynamic loading.
|
||||
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 util
|
||||
|
|
|
@ -30,9 +30,25 @@ else:
|
|||
pass
|
||||
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
|
||||
_w_long = _bootstrap._w_long
|
||||
_r_long = _bootstrap._r_long
|
||||
_w_long = _bootstrap_external._w_long
|
||||
_r_long = _bootstrap_external._r_long
|
||||
|
||||
# Fully bootstrapped at this point, import whatever you like, circular
|
||||
# dependencies and startup overhead minimisation permitting :)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,17 @@
|
|||
"""Abstract base classes related to import."""
|
||||
from . import _bootstrap
|
||||
from . import _bootstrap_external
|
||||
from . import machinery
|
||||
try:
|
||||
import _frozen_importlib
|
||||
# import _frozen_importlib_external
|
||||
except ImportError as exc:
|
||||
if exc.name != '_frozen_importlib':
|
||||
raise
|
||||
_frozen_importlib = None
|
||||
try:
|
||||
import _frozen_importlib_external
|
||||
except ImportError as exc:
|
||||
_frozen_importlib_external = _bootstrap_external
|
||||
import abc
|
||||
|
||||
|
||||
|
@ -14,7 +19,10 @@ def _register(abstract_cls, *classes):
|
|||
for cls in classes:
|
||||
abstract_cls.register(cls)
|
||||
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)
|
||||
|
||||
|
||||
|
@ -102,7 +110,7 @@ class PathEntryFinder(Finder):
|
|||
else:
|
||||
return None, []
|
||||
|
||||
find_module = _bootstrap._find_module_shim
|
||||
find_module = _bootstrap_external._find_module_shim
|
||||
|
||||
def invalidate_caches(self):
|
||||
"""An optional method for clearing the finder's cache, if any.
|
||||
|
@ -144,7 +152,7 @@ class Loader(metaclass=abc.ABCMeta):
|
|||
"""
|
||||
if not hasattr(self, 'exec_module'):
|
||||
raise ImportError
|
||||
return _bootstrap._load_module_shim(self, fullname)
|
||||
return _bootstrap_external._load_module_shim(self, fullname)
|
||||
|
||||
def module_repr(self, module):
|
||||
"""Return a module's repr.
|
||||
|
@ -222,8 +230,8 @@ class InspectLoader(Loader):
|
|||
argument should be where the data was retrieved (when applicable)."""
|
||||
return compile(data, path, 'exec', dont_inherit=True)
|
||||
|
||||
exec_module = _bootstrap._LoaderBasics.exec_module
|
||||
load_module = _bootstrap._LoaderBasics.load_module
|
||||
exec_module = _bootstrap_external._LoaderBasics.exec_module
|
||||
load_module = _bootstrap_external._LoaderBasics.load_module
|
||||
|
||||
_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter)
|
||||
|
||||
|
@ -265,7 +273,7 @@ class ExecutionLoader(InspectLoader):
|
|||
_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
|
||||
ExecutionLoader ABCs."""
|
||||
|
@ -274,7 +282,7 @@ _register(FileLoader, machinery.SourceFileLoader,
|
|||
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
|
||||
corresponding bytecode).
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
import _imp
|
||||
|
||||
from ._bootstrap import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES,
|
||||
OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES,
|
||||
EXTENSION_SUFFIXES)
|
||||
from ._bootstrap import ModuleSpec
|
||||
from ._bootstrap import BuiltinImporter
|
||||
from ._bootstrap import FrozenImporter
|
||||
from ._bootstrap import WindowsRegistryFinder
|
||||
from ._bootstrap import PathFinder
|
||||
from ._bootstrap import FileFinder
|
||||
from ._bootstrap import SourceFileLoader
|
||||
from ._bootstrap import SourcelessFileLoader
|
||||
from ._bootstrap import ExtensionFileLoader
|
||||
from ._bootstrap_external import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES,
|
||||
OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES,
|
||||
EXTENSION_SUFFIXES)
|
||||
from ._bootstrap_external import WindowsRegistryFinder
|
||||
from ._bootstrap_external import PathFinder
|
||||
from ._bootstrap_external import FileFinder
|
||||
from ._bootstrap_external import SourceFileLoader
|
||||
from ._bootstrap_external import SourcelessFileLoader
|
||||
from ._bootstrap_external import ExtensionFileLoader
|
||||
|
||||
|
||||
def all_suffixes():
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
"""Utility code for constructing importers, etc."""
|
||||
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 source_from_cache
|
||||
from ._bootstrap import spec_from_loader
|
||||
from ._bootstrap import spec_from_file_location
|
||||
from ._bootstrap import _resolve_name
|
||||
from ._bootstrap import spec_from_loader
|
||||
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
|
||||
import functools
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Find modules used by a script, using introspection."""
|
||||
|
||||
import dis
|
||||
import importlib._bootstrap
|
||||
import importlib._bootstrap_external
|
||||
import importlib.machinery
|
||||
import marshal
|
||||
import os
|
||||
|
@ -289,7 +289,7 @@ class ModuleFinder:
|
|||
co = compile(fp.read()+'\n', pathname, 'exec')
|
||||
elif type == imp.PY_COMPILED:
|
||||
try:
|
||||
marshal_data = importlib._bootstrap._validate_bytecode_header(fp.read())
|
||||
marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
|
||||
except ImportError as exc:
|
||||
self.msgout(2, "raise ImportError: " + str(exc), pathname)
|
||||
raise
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
This module has intimate knowledge of the format of .pyc files.
|
||||
"""
|
||||
|
||||
import importlib._bootstrap
|
||||
import importlib._bootstrap_external
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
import os
|
||||
|
@ -137,10 +137,10 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1):
|
|||
except FileExistsError:
|
||||
pass
|
||||
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'])
|
||||
mode = importlib._bootstrap._calc_mode(file)
|
||||
importlib._bootstrap._write_atomic(cfile, bytecode, mode)
|
||||
mode = importlib._bootstrap_external._calc_mode(file)
|
||||
importlib._bootstrap_external._write_atomic(cfile, bytecode, mode)
|
||||
return cfile
|
||||
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ Richard Chamberlain, for the first implementation of textdoc.
|
|||
|
||||
import builtins
|
||||
import importlib._bootstrap
|
||||
import importlib._bootstrap_external
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
import inspect
|
||||
|
@ -292,9 +293,9 @@ def importfile(path):
|
|||
filename = os.path.basename(path)
|
||||
name, ext = os.path.splitext(filename)
|
||||
if is_bytecode:
|
||||
loader = importlib._bootstrap.SourcelessFileLoader(name, path)
|
||||
loader = importlib._bootstrap_external.SourcelessFileLoader(name, path)
|
||||
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.
|
||||
spec = importlib.util.spec_from_file_location(name, path, loader=loader)
|
||||
try:
|
||||
|
|
|
@ -58,7 +58,7 @@ class _ModifiedArgv0(object):
|
|||
self.value = self._sentinel
|
||||
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,
|
||||
mod_name=None, mod_spec=None,
|
||||
pkg_name=None, script_name=None):
|
||||
|
|
|
@ -98,8 +98,8 @@ def makepath(*paths):
|
|||
def abs_paths():
|
||||
"""Set all module __file__ and __cached__ attributes to an absolute path"""
|
||||
for m in set(sys.modules.values()):
|
||||
if (getattr(getattr(m, '__loader__', None), '__module__', None) !=
|
||||
'_frozen_importlib'):
|
||||
if (getattr(getattr(m, '__loader__', None), '__module__', None) not in
|
||||
('_frozen_importlib', '_frozen_importlib_external')):
|
||||
continue # don't mess with a PEP 302-supplied __file__
|
||||
try:
|
||||
m.__file__ = os.path.abspath(m.__file__)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# We import importlib *ASAP* in order to test #15386
|
||||
import importlib
|
||||
import importlib.util
|
||||
from importlib._bootstrap import _get_sourcefile
|
||||
from importlib._bootstrap_external import _get_sourcefile
|
||||
import builtins
|
||||
import marshal
|
||||
import os
|
||||
|
@ -845,19 +845,27 @@ class ImportlibBootstrapTests(unittest.TestCase):
|
|||
self.assertEqual(mod.__package__, 'importlib')
|
||||
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):
|
||||
# Issue #15386 revealed a tricky loophole in the bootstrapping
|
||||
# This test is technically redundant, since the bug caused importing
|
||||
# this test module to crash completely, but it helps prove the point
|
||||
from importlib import machinery
|
||||
mod = sys.modules['_frozen_importlib']
|
||||
self.assertIs(machinery.FileFinder, mod.FileFinder)
|
||||
self.assertIs(machinery.ModuleSpec, mod.ModuleSpec)
|
||||
|
||||
|
||||
@cpython_only
|
||||
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
|
||||
knowingly whitebox tests.
|
||||
|
@ -867,7 +875,7 @@ class GetSourcefileTests(unittest.TestCase):
|
|||
def test_get_sourcefile(self):
|
||||
# Given a valid bytecode path, return the path to the corresponding
|
||||
# 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 = TESTFN + '.pyc'
|
||||
expect = TESTFN + '.py'
|
||||
|
@ -876,7 +884,7 @@ class GetSourcefileTests(unittest.TestCase):
|
|||
def test_get_sourcefile_no_source(self):
|
||||
# Given a valid bytecode path without a corresponding source 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 = TESTFN + '.pyc'
|
||||
self.assertEqual(_get_sourcefile(path), path)
|
||||
|
@ -1031,7 +1039,7 @@ class ImportTracebackTests(unittest.TestCase):
|
|||
# We simulate a bug in importlib and check that it's not stripped
|
||||
# away from the traceback.
|
||||
self.create_module("foo", "")
|
||||
importlib = sys.modules['_frozen_importlib']
|
||||
importlib = sys.modules['_frozen_importlib_external']
|
||||
if 'load_module' in vars(importlib.SourceLoader):
|
||||
old_exec_module = importlib.SourceLoader.exec_module
|
||||
else:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from importlib import _bootstrap
|
||||
from importlib import _bootstrap_external
|
||||
import sys
|
||||
from test import support
|
||||
import unittest
|
||||
|
@ -26,7 +26,7 @@ class ExtensionModuleCaseSensitivityTest:
|
|||
def test_case_sensitive(self):
|
||||
with support.EnvironmentVarGuard() as env:
|
||||
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 '
|
||||
'_os.environ')
|
||||
loader = self.find_module()
|
||||
|
@ -35,7 +35,7 @@ class ExtensionModuleCaseSensitivityTest:
|
|||
def test_case_insensitivity(self):
|
||||
with support.EnvironmentVarGuard() as env:
|
||||
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 '
|
||||
'_os.environ')
|
||||
loader = self.find_module()
|
||||
|
|
|
@ -99,7 +99,7 @@ class FinderTests:
|
|||
new_path_importer_cache.pop(None, None)
|
||||
new_path_hooks = [zipimport.zipimporter,
|
||||
self.machinery.FileFinder.path_hook(
|
||||
*self.importlib._bootstrap._get_supported_file_loaders())]
|
||||
*self.importlib._bootstrap_external._get_supported_file_loaders())]
|
||||
missing = object()
|
||||
email = sys.modules.pop('email', missing)
|
||||
try:
|
||||
|
|
|
@ -42,7 +42,7 @@ class CaseSensitivityTest:
|
|||
def test_sensitive(self):
|
||||
with test_support.EnvironmentVarGuard() as env:
|
||||
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 '
|
||||
'_os.environ')
|
||||
sensitive, insensitive = self.sensitivity_test()
|
||||
|
@ -53,7 +53,7 @@ class CaseSensitivityTest:
|
|||
def test_insensitive(self):
|
||||
with test_support.EnvironmentVarGuard() as env:
|
||||
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 '
|
||||
'_os.environ')
|
||||
sensitive, insensitive = self.sensitivity_test()
|
||||
|
|
|
@ -355,8 +355,10 @@ class ImportSideEffectTests(unittest.TestCase):
|
|||
stdout, stderr = proc.communicate()
|
||||
self.assertEqual(proc.returncode, 0)
|
||||
os__file__, os__cached__ = stdout.splitlines()[:2]
|
||||
self.assertTrue(os.path.isabs(os__file__))
|
||||
self.assertTrue(os.path.isabs(os__cached__))
|
||||
self.assertTrue(os.path.isabs(os__file__),
|
||||
"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):
|
||||
# No duplicate paths should exist in sys.path
|
||||
|
|
|
@ -533,6 +533,7 @@ coverage-report:
|
|||
: # force rebuilding of parser and importlib
|
||||
@touch $(GRAMMAR_INPUT)
|
||||
@touch $(srcdir)/Lib/importlib/_bootstrap.py
|
||||
@touch $(srcdir)/Lib/importlib/_bootstrap_external.py
|
||||
: # build with coverage info
|
||||
$(MAKE) coverage
|
||||
: # 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)
|
||||
$(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
|
||||
./Programs/_freeze_importlib \
|
||||
$(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/frozen.o: Python/importlib.h
|
||||
Python/frozen.o: Python/importlib.h Python/importlib_external.h
|
||||
|
||||
Objects/typeobject.o: Objects/typeslots.inc
|
||||
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 #23911: Move path-based importlib bootstrap code to a separate
|
||||
frozen module.
|
||||
|
||||
- Issue #24022: Fix tokenizer crash when processing undecodable source code.
|
||||
|
||||
- Issue #9951: Added a hex() method to bytes, bytearray, and memoryview.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
|
||||
|
||||
/* To avoid a circular dependency on frozen.o, we create our own structure
|
||||
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
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *inpath, *outpath;
|
||||
char *inpath, *outpath, *code_name;
|
||||
FILE *infile = NULL, *outfile = NULL;
|
||||
struct _Py_stat_struct status;
|
||||
size_t text_size, data_size, n;
|
||||
char *text = NULL;
|
||||
unsigned char *data;
|
||||
PyObject *code = NULL, *marshalled = NULL;
|
||||
int is_bootstrap = 1;
|
||||
|
||||
PyImport_FrozenModules = _PyImport_FrozenModules;
|
||||
|
||||
|
@ -82,8 +84,14 @@ main(int argc, char *argv[])
|
|||
/* Don't install importlib, since it could execute outdated bytecode. */
|
||||
_Py_InitializeEx_Private(1, 0);
|
||||
|
||||
code = Py_CompileStringExFlags(text, "<frozen importlib._bootstrap>",
|
||||
Py_file_input, NULL, 0);
|
||||
if (strstr(inpath, "_external") != NULL) {
|
||||
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)
|
||||
goto error;
|
||||
free(text);
|
||||
|
@ -106,7 +114,11 @@ main(int argc, char *argv[])
|
|||
goto error;
|
||||
}
|
||||
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) {
|
||||
size_t i, end = Py_MIN(n + 16, data_size);
|
||||
fprintf(outfile, " ");
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "Python.h"
|
||||
#include "importlib.h"
|
||||
#include "importlib_external.h"
|
||||
|
||||
/* In order to test the support for frozen modules, by default we
|
||||
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[] = {
|
||||
/* 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 */
|
||||
{"__hello__", M___hello__, SIZE},
|
||||
/* Test package (negative size indicates package-ness) */
|
||||
|
|
|
@ -491,8 +491,13 @@ PyImport_GetMagicNumber(void)
|
|||
{
|
||||
long res;
|
||||
PyInterpreterState *interp = PyThreadState_Get()->interp;
|
||||
PyObject *pyc_magic = PyObject_GetAttrString(interp->importlib,
|
||||
"_RAW_MAGIC_NUMBER");
|
||||
PyObject *external, *pyc_magic;
|
||||
|
||||
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)
|
||||
return -1;
|
||||
res = PyLong_AsLong(pyc_magic);
|
||||
|
@ -737,7 +742,7 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
|
|||
const char *cpathname)
|
||||
{
|
||||
PyObject *m = NULL;
|
||||
PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL;
|
||||
PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL;
|
||||
|
||||
nameobj = PyUnicode_FromString(name);
|
||||
if (nameobj == NULL)
|
||||
|
@ -765,9 +770,14 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
|
|||
"no interpreter!");
|
||||
}
|
||||
|
||||
pathobj = _PyObject_CallMethodIdObjArgs(interp->importlib,
|
||||
&PyId__get_sourcefile, cpathobj,
|
||||
NULL);
|
||||
external= PyObject_GetAttrString(interp->importlib,
|
||||
"_bootstrap_external");
|
||||
if (external != NULL) {
|
||||
pathobj = _PyObject_CallMethodIdObjArgs(external,
|
||||
&PyId__get_sourcefile, cpathobj,
|
||||
NULL);
|
||||
Py_DECREF(external);
|
||||
}
|
||||
if (pathobj == NULL)
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -833,7 +843,7 @@ PyObject*
|
|||
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
|
||||
PyObject *cpathname)
|
||||
{
|
||||
PyObject *d, *res;
|
||||
PyObject *d, *external, *res;
|
||||
PyInterpreterState *interp = PyThreadState_GET()->interp;
|
||||
_Py_IDENTIFIER(_fix_up_module);
|
||||
|
||||
|
@ -845,9 +855,13 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
|
|||
if (pathname == NULL) {
|
||||
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,
|
||||
d, name, pathname, cpathname, NULL);
|
||||
Py_DECREF(external);
|
||||
if (res != NULL) {
|
||||
Py_DECREF(res);
|
||||
res = exec_code_in_module(name, d, co);
|
||||
|
@ -1245,6 +1259,7 @@ static void
|
|||
remove_importlib_frames(void)
|
||||
{
|
||||
const char *importlib_filename = "<frozen importlib._bootstrap>";
|
||||
const char *external_filename = "<frozen importlib._bootstrap_external>";
|
||||
const char *remove_frames = "_call_with_frames_removed";
|
||||
int always_trim = 0;
|
||||
int in_importlib = 0;
|
||||
|
@ -1274,7 +1289,10 @@ remove_importlib_frames(void)
|
|||
assert(PyTraceBack_Check(tb));
|
||||
now_in_importlib = (PyUnicode_CompareWithASCIIString(
|
||||
code->co_filename,
|
||||
importlib_filename) == 0);
|
||||
importlib_filename) == 0) ||
|
||||
(PyUnicode_CompareWithASCIIString(
|
||||
code->co_filename,
|
||||
external_filename) == 0);
|
||||
if (now_in_importlib && !in_importlib) {
|
||||
/* This is the link to this chunk of importlib tracebacks */
|
||||
outer_link = prev_link;
|
||||
|
|
6227
Python/importlib.h
6227
Python/importlib.h
File diff suppressed because it is too large
Load Diff
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;
|
||||
PyThreadState *tstate;
|
||||
PyObject *filename_obj, *loader_type, *loader;
|
||||
PyObject *filename_obj, *bootstrap, *loader_type = NULL, *loader;
|
||||
int result = 0;
|
||||
|
||||
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 */
|
||||
tstate = PyThreadState_GET();
|
||||
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) {
|
||||
Py_DECREF(filename_obj);
|
||||
return -1;
|
||||
|
|
|
@ -366,8 +366,10 @@ def main():
|
|||
mf.load_file(mod)
|
||||
|
||||
# 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_external"] = mf.modules["importlib._bootstrap_external"]
|
||||
|
||||
# Add the main script as either __main__, or the actual module name.
|
||||
if python_entry_is_main:
|
||||
|
|
Loading…
Reference in New Issue