2012-02-28 00:15:42 +01:00
|
|
|
"""A pure Python implementation of import."""
|
2013-06-14 21:04:26 +02:00
|
|
|
__all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload']
|
2009-03-12 23:01:40 +01:00
|
|
|
|
2012-06-17 22:33:38 +02:00
|
|
|
# Bootstrap help #####################################################
|
2012-07-20 15:40:09 +02:00
|
|
|
|
|
|
|
# Until bootstrapping is complete, DO NOT import any modules that attempt
|
|
|
|
# to import importlib._bootstrap (directly or indirectly). Since this
|
|
|
|
# partially initialised package would be present in sys.modules, those
|
|
|
|
# modules would get an uninitialised copy of the source version, instead
|
|
|
|
# of a fully initialised version (either the frozen one or the one
|
|
|
|
# initialised below if the frozen one is not available).
|
|
|
|
import _imp # Just the builtin component, NOT the full Python module
|
2012-06-17 22:33:38 +02:00
|
|
|
import sys
|
2009-01-18 01:24:28 +01:00
|
|
|
|
2012-06-17 22:33:38 +02:00
|
|
|
try:
|
2012-07-04 20:03:40 +02:00
|
|
|
import _frozen_importlib as _bootstrap
|
2013-07-04 23:43:24 +02:00
|
|
|
except ImportError:
|
2012-06-17 22:33:38 +02:00
|
|
|
from . import _bootstrap
|
2012-07-20 15:40:09 +02:00
|
|
|
_bootstrap._setup(sys, _imp)
|
2012-06-17 22:33:38 +02:00
|
|
|
else:
|
|
|
|
# importlib._bootstrap is the built-in import, ensure we don't create
|
|
|
|
# a second copy of the module.
|
|
|
|
_bootstrap.__name__ = 'importlib._bootstrap'
|
|
|
|
_bootstrap.__package__ = 'importlib'
|
2014-03-21 15:58:33 +01:00
|
|
|
try:
|
|
|
|
_bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py')
|
|
|
|
except NameError:
|
|
|
|
# __file__ is not guaranteed to be defined, e.g. if this code gets
|
|
|
|
# frozen by a tool like cx_Freeze.
|
|
|
|
pass
|
2012-06-17 22:33:38 +02:00
|
|
|
sys.modules['importlib._bootstrap'] = _bootstrap
|
2009-01-18 01:24:28 +01:00
|
|
|
|
2015-05-03 03:15:18 +02:00
|
|
|
try:
|
|
|
|
import _frozen_importlib_external as _bootstrap_external
|
|
|
|
except ImportError:
|
|
|
|
from . import _bootstrap_external
|
2020-11-19 13:43:43 +01:00
|
|
|
_bootstrap_external._set_bootstrap_module(_bootstrap)
|
2015-05-16 05:54:59 +02:00
|
|
|
_bootstrap._bootstrap_external = _bootstrap_external
|
2015-05-03 03:15:18 +02:00
|
|
|
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
|
|
|
|
|
2012-01-26 00:58:03 +01:00
|
|
|
# To simplify imports in test code
|
2018-09-18 21:22:29 +02:00
|
|
|
_pack_uint32 = _bootstrap_external._pack_uint32
|
|
|
|
_unpack_uint32 = _bootstrap_external._unpack_uint32
|
2012-01-26 00:58:03 +01:00
|
|
|
|
2012-07-20 15:40:09 +02:00
|
|
|
# Fully bootstrapped at this point, import whatever you like, circular
|
|
|
|
# dependencies and startup overhead minimisation permitting :)
|
2012-01-26 00:58:03 +01:00
|
|
|
|
2014-01-25 23:32:46 +01:00
|
|
|
|
2009-01-22 23:44:04 +01:00
|
|
|
# Public API #########################################################
|
|
|
|
|
2012-02-28 00:15:42 +01:00
|
|
|
from ._bootstrap import __import__
|
|
|
|
|
|
|
|
|
|
|
|
def invalidate_caches():
|
2012-08-10 18:21:12 +02:00
|
|
|
"""Call the invalidate_caches() method on all meta path finders stored in
|
|
|
|
sys.meta_path (where implemented)."""
|
|
|
|
for finder in sys.meta_path:
|
2012-02-28 00:15:42 +01:00
|
|
|
if hasattr(finder, 'invalidate_caches'):
|
|
|
|
finder.invalidate_caches()
|
2009-01-20 03:21:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
def import_module(name, package=None):
|
|
|
|
"""Import a module.
|
|
|
|
|
|
|
|
The 'package' argument is required when performing a relative import. It
|
|
|
|
specifies the package to use as the anchor point from which to resolve the
|
|
|
|
relative import to an absolute import.
|
|
|
|
|
|
|
|
"""
|
2009-02-07 02:15:27 +01:00
|
|
|
level = 0
|
2009-01-20 03:21:27 +01:00
|
|
|
if name.startswith('.'):
|
|
|
|
if not package:
|
2022-10-07 03:27:51 +02:00
|
|
|
raise TypeError("the 'package' argument is required to perform a "
|
|
|
|
f"relative import for {name!r}")
|
2009-01-20 03:21:27 +01:00
|
|
|
for character in name:
|
|
|
|
if character != '.':
|
|
|
|
break
|
|
|
|
level += 1
|
2009-02-07 02:15:27 +01:00
|
|
|
return _bootstrap._gcd_import(name[level:], package, level)
|
2013-06-14 21:04:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
_RELOADING = {}
|
|
|
|
|
|
|
|
|
|
|
|
def reload(module):
|
|
|
|
"""Reload the module and return it.
|
|
|
|
|
|
|
|
The module must have been successfully imported before.
|
|
|
|
|
|
|
|
"""
|
2013-11-22 17:05:39 +01:00
|
|
|
try:
|
|
|
|
name = module.__spec__.name
|
|
|
|
except AttributeError:
|
2020-06-05 21:56:32 +02:00
|
|
|
try:
|
|
|
|
name = module.__name__
|
|
|
|
except AttributeError:
|
2024-10-21 08:53:21 +02:00
|
|
|
raise TypeError("reload() argument must be a module") from None
|
2013-11-22 17:05:39 +01:00
|
|
|
|
2013-11-01 05:22:15 +01:00
|
|
|
if sys.modules.get(name) is not module:
|
2022-10-07 03:27:51 +02:00
|
|
|
raise ImportError(f"module {name} not in sys.modules", name=name)
|
2013-06-14 21:04:26 +02:00
|
|
|
if name in _RELOADING:
|
|
|
|
return _RELOADING[name]
|
|
|
|
_RELOADING[name] = module
|
|
|
|
try:
|
|
|
|
parent_name = name.rpartition('.')[0]
|
2013-12-10 03:59:10 +01:00
|
|
|
if parent_name:
|
|
|
|
try:
|
|
|
|
parent = sys.modules[parent_name]
|
|
|
|
except KeyError:
|
2022-10-07 03:27:51 +02:00
|
|
|
raise ImportError(f"parent {parent_name!r} not in sys.modules",
|
2014-11-21 19:33:57 +01:00
|
|
|
name=parent_name) from None
|
2013-12-10 03:59:10 +01:00
|
|
|
else:
|
|
|
|
pkgpath = parent.__path__
|
|
|
|
else:
|
|
|
|
pkgpath = None
|
2014-01-25 23:32:46 +01:00
|
|
|
target = module
|
|
|
|
spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target)
|
2017-05-25 00:19:50 +02:00
|
|
|
if spec is None:
|
|
|
|
raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
|
2014-05-30 20:55:29 +02:00
|
|
|
_bootstrap._exec(spec, module)
|
2013-08-15 02:11:09 +02:00
|
|
|
# The module may have replaced itself in sys.modules!
|
2013-11-22 17:05:39 +01:00
|
|
|
return sys.modules[name]
|
2013-06-14 21:04:26 +02:00
|
|
|
finally:
|
|
|
|
try:
|
|
|
|
del _RELOADING[name]
|
|
|
|
except KeyError:
|
|
|
|
pass
|