Commit 183a941b authored by Eric Snow's avatar Eric Snow

Issue #24192: Fix namespace package imports.

parent 188c18d4
......@@ -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
......
"""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.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment