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

Issue #24192: Fix namespace package imports.

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