diff options
author | Brett Cannon <brett@python.org> | 2013-06-16 21:23:06 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2013-06-16 21:23:06 (GMT) |
commit | 01b0475b08ab694e2eb0610d03b629afe22bb2a1 (patch) | |
tree | a36f19dcaae3d255d1ce3f8abc43cf2c3b846705 /Lib | |
parent | 6d26eba186655be245af90c4a7c2aec6a1e14fc6 (diff) | |
download | cpython-01b0475b08ab694e2eb0610d03b629afe22bb2a1.zip cpython-01b0475b08ab694e2eb0610d03b629afe22bb2a1.tar.gz cpython-01b0475b08ab694e2eb0610d03b629afe22bb2a1.tar.bz2 |
Issue #18115: Abstract out managing the cleanup of modules to use in
loaders where C code provides the loaded module.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index e32afec..f855e90 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -475,8 +475,24 @@ def _verbose_message(message, *args, verbosity=1): print(message.format(*args), file=sys.stderr) +class _ManageReload: + + def __init__(self, name): + self._name = name + + def __enter__(self): + self._is_reload = self._name in sys.modules + + def __exit__(self, *args): + if any(arg is not None for arg in args) and not self._is_reload: + try: + del sys.modules[self._name] + except KeyError: + pass + + # Written as a class only because contextlib is not available. -class _ModuleManager: +class _ModuleManager(_ManageReload): """Context manager which returns the module to be loaded. @@ -490,12 +506,12 @@ class _ModuleManager: The reset_name argument specifies whether to unconditionally reset the __name__ attribute if the module is found to be a reload. """ - self._name = name + super().__init__(name) self._reset_name = reset_name def __enter__(self): + super().__enter__() 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 @@ -510,14 +526,12 @@ class _ModuleManager: self._module.__name__ = self._name except AttributeError: pass - 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] + super().__exit__(*args) def module_to_load(name, *, reset_name=True): @@ -741,13 +755,8 @@ class BuiltinImporter: @_requires_builtin def load_module(cls, fullname): """Load a built-in module.""" - is_reload = fullname in sys.modules - try: + with _ManageReload(fullname): return _call_with_frames_removed(_imp.init_builtin, fullname) - except: - if not is_reload and fullname in sys.modules: - del sys.modules[fullname] - raise @classmethod @_requires_builtin @@ -792,16 +801,11 @@ class FrozenImporter: @_requires_frozen def load_module(cls, fullname): """Load a frozen module.""" - is_reload = fullname in sys.modules - try: + with _ManageReload(fullname): m = _call_with_frames_removed(_imp.init_frozen, fullname) # Let our own module_repr() method produce a suitable repr. del m.__file__ return m - except: - if not is_reload and fullname in sys.modules: - del sys.modules[fullname] - raise @classmethod @_requires_frozen @@ -1147,18 +1151,13 @@ class ExtensionFileLoader: @set_loader def load_module(self, fullname): """Load an extension module.""" - is_reload = fullname in sys.modules - try: + with _ManageReload(fullname): module = _call_with_frames_removed(_imp.load_dynamic, fullname, self.path) _verbose_message('extension module loaded from {!r}', self.path) if self.is_package(fullname) and not hasattr(module, '__path__'): module.__path__ = [_path_split(self.path)[0]] return module - except: - if not is_reload and fullname in sys.modules: - del sys.modules[fullname] - raise def is_package(self, fullname): """Return True if the extension module is a package.""" |