Issue #24192: Fix namespace package imports.
This commit is contained in:
parent
188c18d48f
commit
183a941bc1
|
@ -35,6 +35,7 @@ try:
|
|||
except ImportError:
|
||||
from . import _bootstrap_external
|
||||
_bootstrap_external._setup(_bootstrap)
|
||||
_bootstrap._bootstrap_external = _bootstrap_external
|
||||
else:
|
||||
_bootstrap_external.__name__ = 'importlib._bootstrap_external'
|
||||
_bootstrap_external.__package__ = 'importlib'
|
||||
|
|
|
@ -22,6 +22,8 @@ work. One should use importlib as the public-facing version of this module.
|
|||
|
||||
# Bootstrap-related code ######################################################
|
||||
|
||||
_bootstrap_external = None
|
||||
|
||||
def _wrap(new, old):
|
||||
"""Simple substitute for functools.update_wrapper."""
|
||||
for replace in ['__module__', '__name__', '__qualname__', '__doc__']:
|
||||
|
@ -405,7 +407,8 @@ class ModuleSpec:
|
|||
def cached(self):
|
||||
if self._cached is None:
|
||||
if self.origin is not None and self._set_fileattr:
|
||||
import _frozen_importlib_external as _bootstrap_external # XXX yuck
|
||||
if _bootstrap_external is None:
|
||||
raise NotImplementedError
|
||||
self._cached = _bootstrap_external._get_cached(self.origin)
|
||||
return self._cached
|
||||
|
||||
|
@ -433,7 +436,10 @@ class ModuleSpec:
|
|||
def spec_from_loader(name, loader, *, origin=None, is_package=None):
|
||||
"""Return a module spec based on various loader methods."""
|
||||
if hasattr(loader, 'get_filename'):
|
||||
from ._bootstrap_external import spec_from_file_location # XXX yuck
|
||||
if _bootstrap_external is None:
|
||||
raise NotImplementedError
|
||||
spec_from_file_location = _bootstrap_external.spec_from_file_location
|
||||
|
||||
if is_package is None:
|
||||
return spec_from_file_location(name, loader=loader)
|
||||
search = [] if is_package else None
|
||||
|
@ -516,7 +522,10 @@ def _init_module_attrs(spec, module, *, override=False):
|
|||
if loader is None:
|
||||
# A backward compatibility hack.
|
||||
if spec.submodule_search_locations is not None:
|
||||
from ._bootstrap_external import _NamespaceLoader # XXX yuck
|
||||
if _bootstrap_external is None:
|
||||
raise NotImplementedError
|
||||
_NamespaceLoader = _bootstrap_external._NamespaceLoader
|
||||
|
||||
loader = _NamespaceLoader.__new__(_NamespaceLoader)
|
||||
loader._path = spec.submodule_search_locations
|
||||
try:
|
||||
|
@ -810,7 +819,6 @@ class FrozenImporter:
|
|||
This method is deprecated. Use exec_module() instead.
|
||||
|
||||
"""
|
||||
from ._bootstrap_external import _load_module_shim # XXX yuck
|
||||
return _load_module_shim(cls, fullname)
|
||||
|
||||
@classmethod
|
||||
|
@ -1125,6 +1133,7 @@ def _install(sys_module, _imp_module):
|
|||
sys.meta_path.append(BuiltinImporter)
|
||||
sys.meta_path.append(FrozenImporter)
|
||||
|
||||
global _bootstrap_external
|
||||
import _frozen_importlib_external
|
||||
_bootstrap_external = _frozen_importlib_external
|
||||
_frozen_importlib_external._install(sys.modules[__name__])
|
||||
sys.modules[__name__]._bootstrap_external = _frozen_importlib_external
|
||||
|
|
|
@ -410,22 +410,6 @@ def _find_module_shim(self, fullname):
|
|||
return loader
|
||||
|
||||
|
||||
# Typically used by loader classes as a method replacement.
|
||||
def _load_module_shim(self, fullname):
|
||||
"""Load the specified module into sys.modules and return it.
|
||||
|
||||
This method is deprecated. Use loader.exec_module instead.
|
||||
|
||||
"""
|
||||
spec = spec_from_loader(fullname, self)
|
||||
if fullname in sys.modules:
|
||||
module = sys.modules[fullname]
|
||||
_bootstrap._exec(spec, module)
|
||||
return sys.modules[fullname]
|
||||
else:
|
||||
return _bootstrap._load(spec)
|
||||
|
||||
|
||||
def _validate_bytecode_header(data, source_stats=None, name=None, path=None):
|
||||
"""Validate the header of the passed-in bytecode against source_stats (if
|
||||
given) and returning the bytecode that can be compiled by compile().
|
||||
|
@ -517,28 +501,6 @@ def decode_source(source_bytes):
|
|||
|
||||
# Module specifications #######################################################
|
||||
|
||||
def spec_from_loader(name, loader, *, origin=None, is_package=None):
|
||||
"""Return a module spec based on various loader methods."""
|
||||
if hasattr(loader, 'get_filename'):
|
||||
if is_package is None:
|
||||
return spec_from_file_location(name, loader=loader)
|
||||
search = [] if is_package else None
|
||||
return spec_from_file_location(name, loader=loader,
|
||||
submodule_search_locations=search)
|
||||
|
||||
if is_package is None:
|
||||
if hasattr(loader, 'is_package'):
|
||||
try:
|
||||
is_package = loader.is_package(name)
|
||||
except ImportError:
|
||||
is_package = None # aka, undefined
|
||||
else:
|
||||
# the default
|
||||
is_package = False
|
||||
|
||||
return _bootstrap.ModuleSpec(name, loader, origin=origin, is_package=is_package)
|
||||
|
||||
|
||||
_POPULATE = object()
|
||||
|
||||
|
||||
|
@ -653,8 +615,9 @@ class WindowsRegistryFinder:
|
|||
return None
|
||||
for loader, suffixes in _get_supported_file_loaders():
|
||||
if filepath.endswith(tuple(suffixes)):
|
||||
spec = spec_from_loader(fullname, loader(fullname, filepath),
|
||||
origin=filepath)
|
||||
spec = _bootstrap.spec_from_loader(fullname,
|
||||
loader(fullname, filepath),
|
||||
origin=filepath)
|
||||
return spec
|
||||
|
||||
@classmethod
|
||||
|
@ -695,7 +658,8 @@ class _LoaderBasics:
|
|||
'returns None'.format(module.__name__))
|
||||
_bootstrap._call_with_frames_removed(exec, code, module.__dict__)
|
||||
|
||||
load_module = _load_module_shim
|
||||
def load_module(self, fullname):
|
||||
return _bootstrap._load_module_shim(self, fullname)
|
||||
|
||||
|
||||
class SourceLoader(_LoaderBasics):
|
||||
|
@ -1061,7 +1025,7 @@ class _NamespaceLoader:
|
|||
"""
|
||||
# The import system never calls this method.
|
||||
_verbose_message('namespace module loaded with path {!r}', self._path)
|
||||
return _load_module_shim(self, fullname)
|
||||
return _bootstrap._load_module_shim(self, fullname)
|
||||
|
||||
|
||||
# Finders #####################################################################
|
||||
|
@ -1127,7 +1091,7 @@ class PathFinder:
|
|||
loader = finder.find_module(fullname)
|
||||
portions = []
|
||||
if loader is not None:
|
||||
return spec_from_loader(fullname, loader)
|
||||
return _bootstrap.spec_from_loader(fullname, loader)
|
||||
spec = _bootstrap.ModuleSpec(fullname, None)
|
||||
spec.submodule_search_locations = portions
|
||||
return spec
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Abstract base classes related to import."""
|
||||
from . import _bootstrap
|
||||
from . import _bootstrap_external
|
||||
from . import machinery
|
||||
try:
|
||||
|
@ -152,7 +153,7 @@ class Loader(metaclass=abc.ABCMeta):
|
|||
"""
|
||||
if not hasattr(self, 'exec_module'):
|
||||
raise ImportError
|
||||
return _bootstrap_external._load_module_shim(self, fullname)
|
||||
return _bootstrap._load_module_shim(self, fullname)
|
||||
|
||||
def module_repr(self, module):
|
||||
"""Return a module's repr.
|
||||
|
|
|
@ -49,7 +49,7 @@ def import_importlib(module_name):
|
|||
fresh = ('importlib',) if '.' in module_name else ()
|
||||
frozen = support.import_fresh_module(module_name)
|
||||
source = support.import_fresh_module(module_name, fresh=fresh,
|
||||
blocked=('_frozen_importlib',))
|
||||
blocked=('_frozen_importlib', '_frozen_importlib_external'))
|
||||
return {'Frozen': frozen, 'Source': source}
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ Core and Builtins
|
|||
- Issue #23911: Move path-based importlib bootstrap code to a separate
|
||||
frozen module.
|
||||
|
||||
- Issue #24192: Fix namespace package imports.
|
||||
|
||||
- Issue #24022: Fix tokenizer crash when processing undecodable source code.
|
||||
|
||||
- Issue #9951: Added a hex() method to bytes, bytearray, and memoryview.
|
||||
|
|
3902
Python/importlib.h
3902
Python/importlib.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue