summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/importlib.rst10
-rw-r--r--Lib/importlib/NOTES4
-rw-r--r--Lib/importlib/_bootstrap.py18
-rw-r--r--Lib/importlib/test/builtin/test_loader.py3
-rw-r--r--Lib/importlib/test/extension/test_loader.py2
-rw-r--r--Lib/importlib/test/frozen/test_loader.py8
-rw-r--r--Lib/importlib/util.py1
7 files changed, 34 insertions, 12 deletions
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index c1874f6..4610b57 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -348,7 +348,15 @@ an :term:`importer`.
loader should initialize as specified by :pep:`302`.
-.. function:: set_package(method)
+.. function:: set_loader(fxn)
+
+ A :term:`decorator` for a :term:`loader` to set the :attr:`__loader__`
+ attribute on loaded modules. If the attribute is already set the decorator
+ does nothing. It is assumed that the first positional argument to the
+ wrapped method is what :attr:`__loader__` should be set to.
+
+
+.. function:: set_package(fxn)
A :term:`decorator` for a :term:`loader` to set the :attr:`__package__`
attribute on the module returned by the loader. If :attr:`__package__` is
diff --git a/Lib/importlib/NOTES b/Lib/importlib/NOTES
index f738419..8d05a16 100644
--- a/Lib/importlib/NOTES
+++ b/Lib/importlib/NOTES
@@ -1,10 +1,6 @@
to do
/////
-* Public API left to expose (w/ docs!)
-
- + util.set_loader
-
* Implement InspectLoader for BuiltinImporter and FrozenImporter.
+ Expose function to see if a frozen module is a package.
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 73f6513..1b46006 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -110,6 +110,17 @@ def set_package(fxn):
return wrapper
+def set_loader(fxn):
+ """Set __loader__ on the returned module."""
+ def wrapper(self, *args, **kwargs):
+ module = fxn(self, *args, **kwargs)
+ if not hasattr(module, '__loader__'):
+ module.__loader__ = self
+ return module
+ wrap(wrapper, fxn)
+ return wrapper
+
+
class BuiltinImporter:
"""Meta path loader for built-in modules.
@@ -132,6 +143,7 @@ class BuiltinImporter:
@classmethod
@set_package
+ @set_loader
def load_module(cls, fullname):
"""Load a built-in module."""
if fullname not in sys.builtin_module_names:
@@ -161,6 +173,7 @@ class FrozenImporter:
@classmethod
@set_package
+ @set_loader
def load_module(cls, fullname):
"""Load a frozen module."""
if cls.find_module(fullname) is None:
@@ -249,13 +262,12 @@ class _ExtensionFileLoader:
@check_name
@set_package
+ @set_loader
def load_module(self, fullname):
"""Load an extension module."""
is_reload = fullname in sys.modules
try:
- module = imp.load_dynamic(fullname, self._path)
- module.__loader__ = self
- return module
+ return imp.load_dynamic(fullname, self._path)
except:
if not is_reload and fullname in sys.modules:
del sys.modules[fullname]
diff --git a/Lib/importlib/test/builtin/test_loader.py b/Lib/importlib/test/builtin/test_loader.py
index 1171960..8a69d04 100644
--- a/Lib/importlib/test/builtin/test_loader.py
+++ b/Lib/importlib/test/builtin/test_loader.py
@@ -15,7 +15,8 @@ class LoaderTests(abc.LoaderTests):
assert 'errno' in sys.builtin_module_names
name = 'errno'
- verification = {'__name__': 'errno', '__package__': ''}
+ verification = {'__name__': 'errno', '__package__': '',
+ '__loader__': machinery.BuiltinImporter}
def verify(self, module):
"""Verify that the module matches against what it should have."""
diff --git a/Lib/importlib/test/extension/test_loader.py b/Lib/importlib/test/extension/test_loader.py
index ca9f2a7..f961a63 100644
--- a/Lib/importlib/test/extension/test_loader.py
+++ b/Lib/importlib/test/extension/test_loader.py
@@ -24,6 +24,8 @@ class LoaderTests(abc.LoaderTests):
('__package__', '')]:
self.assertEqual(getattr(module, attr), value)
self.assert_(ext_util.NAME in sys.modules)
+ self.assert_(isinstance(module.__loader__,
+ importlib._ExtensionFileLoader))
def test_package(self):
# Extensions are not found in packages.
diff --git a/Lib/importlib/test/frozen/test_loader.py b/Lib/importlib/test/frozen/test_loader.py
index 9032b0b..54d805d 100644
--- a/Lib/importlib/test/frozen/test_loader.py
+++ b/Lib/importlib/test/frozen/test_loader.py
@@ -9,7 +9,7 @@ class LoaderTests(abc.LoaderTests):
with util.uncache('__hello__'):
module = machinery.FrozenImporter.load_module('__hello__')
check = {'__name__': '__hello__', '__file__': '<frozen>',
- '__package__': ''}
+ '__package__': '', '__loader__': machinery.FrozenImporter}
for attr, value in check.items():
self.assertEqual(getattr(module, attr), value)
@@ -17,7 +17,8 @@ class LoaderTests(abc.LoaderTests):
with util.uncache('__phello__'):
module = machinery.FrozenImporter.load_module('__phello__')
check = {'__name__': '__phello__', '__file__': '<frozen>',
- '__package__': '__phello__', '__path__': ['__phello__']}
+ '__package__': '__phello__', '__path__': ['__phello__'],
+ '__loader__': machinery.FrozenImporter}
for attr, value in check.items():
attr_value = getattr(module, attr)
self.assertEqual(attr_value, value,
@@ -28,7 +29,8 @@ class LoaderTests(abc.LoaderTests):
with util.uncache('__phello__', '__phello__.spam'):
module = machinery.FrozenImporter.load_module('__phello__.spam')
check = {'__name__': '__phello__.spam', '__file__': '<frozen>',
- '__package__': '__phello__'}
+ '__package__': '__phello__',
+ '__loader__': machinery.FrozenImporter}
for attr, value in check.items():
attr_value = getattr(module, attr)
self.assertEqual(attr_value, value,
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 9022ab8..3abc6a9 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -1,3 +1,4 @@
"""Utility code for constructing importers, etc."""
from ._bootstrap import module_for_loader
+from ._bootstrap import set_loader
from ._bootstrap import set_package