mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
Introduce importlib.util.ModuleManager which is a context manager to
handle providing (and cleaning up if needed) the module to be loaded. A future commit will use the context manager in Lib/importlib/_bootstrap.py and thus why the code is placed there instead of in Lib/importlib/util.py.
This commit is contained in:
parent
4dbae88131
commit
a3687f0d68
6 changed files with 3508 additions and 3341 deletions
|
@ -9,7 +9,7 @@ work. One should use importlib as the public-facing version of this module.
|
|||
#
|
||||
# IMPORTANT: Whenever making changes to this module, be sure to run
|
||||
# a top-level make in order to get the frozen version of the module
|
||||
# update. Not doing so, will result in the Makefile to fail for
|
||||
# update. Not doing so will result in the Makefile to fail for
|
||||
# all others who don't have a ./python around to freeze the module
|
||||
# in the early stages of compilation.
|
||||
#
|
||||
|
@ -20,10 +20,6 @@ work. One should use importlib as the public-facing version of this module.
|
|||
# reference any injected objects! This includes not only global code but also
|
||||
# anything specified at the class level.
|
||||
|
||||
# XXX Make sure all public names have no single leading underscore and all
|
||||
# others do.
|
||||
|
||||
|
||||
# Bootstrap-related code ######################################################
|
||||
|
||||
_CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'darwin'
|
||||
|
@ -498,6 +494,38 @@ def _verbose_message(message, *args, verbosity=1):
|
|||
print(message.format(*args), file=sys.stderr)
|
||||
|
||||
|
||||
class ModuleManager:
|
||||
|
||||
"""Context manager which returns the module to be loaded.
|
||||
|
||||
Does the proper unloading from sys.modules upon failure.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
|
||||
def __enter__(self):
|
||||
self._module = sys.modules.get(self._name)
|
||||
self._is_reload = self._module is not None
|
||||
if not self._is_reload:
|
||||
# This must be done before open() is called as the 'io' module
|
||||
# implicitly imports 'locale' and would otherwise trigger an
|
||||
# infinite loop.
|
||||
self._module = new_module(self._name)
|
||||
# This must be done before putting the module in sys.modules
|
||||
# (otherwise an optimization shortcut in import.c becomes wrong)
|
||||
self._module.__initializing__ = True
|
||||
sys.modules[self._name] = self._module
|
||||
return self._module
|
||||
|
||||
def __exit__(self, *args):
|
||||
self._module.__initializing__ = False
|
||||
del self._module
|
||||
if any(arg is not None for arg in args) and not self._is_reload:
|
||||
del sys.modules[self._name]
|
||||
|
||||
|
||||
def set_package(fxn):
|
||||
"""Set __package__ on the returned module."""
|
||||
def set_package_wrapper(*args, **kwargs):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue