summaryrefslogtreecommitdiffstats
path: root/Lib/importlib/_bootstrap.py
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2015-05-23 12:24:10 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2015-05-23 12:24:10 (GMT)
commitd5cacbb1d9c3edc02bf0ba01702e7c06da5bc318 (patch)
treee92dda9e119e043482b0aa0ad1fdefff785d54c0 /Lib/importlib/_bootstrap.py
parentec219ba1c04c4514b8b004239b1a0eac914dde4a (diff)
downloadcpython-d5cacbb1d9c3edc02bf0ba01702e7c06da5bc318.zip
cpython-d5cacbb1d9c3edc02bf0ba01702e7c06da5bc318.tar.gz
cpython-d5cacbb1d9c3edc02bf0ba01702e7c06da5bc318.tar.bz2
PEP 489: Multi-phase extension module initialization
Known limitations of the current implementation: - documentation changes are incomplete - there's a reference leak I haven't tracked down yet The leak is most visible by running: ./python -m test -R3:3 test_importlib However, you can also see it by running: ./python -X showrefcount Importing the array or _testmultiphase modules, and then deleting them from both sys.modules and the local namespace shows significant increases in the total number of active references each cycle. By contrast, with _testcapi (which continues to use single-phase initialisation) the global refcounts stabilise after a couple of cycles.
Diffstat (limited to 'Lib/importlib/_bootstrap.py')
-rw-r--r--Lib/importlib/_bootstrap.py23
1 files changed, 13 insertions, 10 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 860703c..931754e 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -735,16 +735,17 @@ class BuiltinImporter:
return spec.loader if spec is not None else None
@classmethod
- @_requires_builtin
- def load_module(cls, fullname):
- """Load a built-in module."""
- # Once an exec_module() implementation is added we can also
- # add a deprecation warning here.
- with _ManageReload(fullname):
- module = _call_with_frames_removed(_imp.init_builtin, fullname)
- module.__loader__ = cls
- module.__package__ = ''
- return module
+ def create_module(self, spec):
+ """Create a built-in module"""
+ if spec.name not in sys.builtin_module_names:
+ raise ImportError('{!r} is not a built-in module'.format(spec.name),
+ name=spec.name)
+ return _call_with_frames_removed(_imp.create_builtin, spec)
+
+ @classmethod
+ def exec_module(self, module):
+ """Exec a built-in module"""
+ _call_with_frames_removed(_imp.exec_dynamic, module)
@classmethod
@_requires_builtin
@@ -764,6 +765,8 @@ class BuiltinImporter:
"""Return False as built-in modules are never packages."""
return False
+ load_module = classmethod(_load_module_shim)
+
class FrozenImporter: