summaryrefslogtreecommitdiffstats
path: root/Lib/importlib/_bootstrap.py
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-04-27 21:27:14 (GMT)
committerBrett Cannon <brett@python.org>2012-04-27 21:27:14 (GMT)
commitefad00d52041fedbff5d7cfadd163e228b4af519 (patch)
tree33c9cc54a62a114eeaffdcfe3e2b31fa6a0b1166 /Lib/importlib/_bootstrap.py
parentfea73efc9ea2a65d73a55f8bab1adfbbca62e38b (diff)
downloadcpython-efad00d52041fedbff5d7cfadd163e228b4af519.zip
cpython-efad00d52041fedbff5d7cfadd163e228b4af519.tar.gz
cpython-efad00d52041fedbff5d7cfadd163e228b4af519.tar.bz2
Issue #14646: __import__() now sets __loader__ if need be.
importlib.util.module_for_loader also will set __loader__ along with __package__. This is in conjunction to a forthcoming update to PEP 302 which will make these two attributes required for loaders to set.
Diffstat (limited to 'Lib/importlib/_bootstrap.py')
-rw-r--r--Lib/importlib/_bootstrap.py28
1 files changed, 25 insertions, 3 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 2b26003..3153f21 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -257,9 +257,14 @@ def module_for_loader(fxn):
The decorated function is passed the module to use instead of the module
name. The module passed in to the function is either from sys.modules if
- it already exists or is a new module which has __name__ set and is inserted
- into sys.modules. If an exception is raised and the decorator created the
- module it is subsequently removed from sys.modules.
+ it already exists or is a new module. If the module is new, then __name__
+ is set the first argument to the method, __loader__ is set to self, and
+ __package__ is set accordingly (if self.is_package() is defined) will be set
+ before it is passed to the decorated function (if self.is_package() does
+ not work for the module it will be set post-load).
+
+ If an exception is raised and the decorator created the module it is
+ subsequently removed from sys.modules.
The decorator assumes that the decorated function takes the module name as
the second argument.
@@ -274,7 +279,18 @@ def module_for_loader(fxn):
# infinite loop.
module = _new_module(fullname)
sys.modules[fullname] = module
+ module.__loader__ = self
+ try:
+ is_package = self.is_package(fullname)
+ except (ImportError, AttributeError):
+ pass
+ else:
+ if is_package:
+ module.__package__ = fullname
+ else:
+ module.__package__ = fullname.rpartition('.')[0]
try:
+ # If __package__ was not set above, __import__() will do it later.
return fxn(self, module, *args, **kwargs)
except:
if not is_reload:
@@ -1012,6 +1028,12 @@ def _find_and_load(name, import_):
module.__package__ = module.__package__.rpartition('.')[0]
except AttributeError:
pass
+ # Set loader if need be.
+ if not hasattr(module, '__loader__'):
+ try:
+ module.__loader__ = loader
+ except AttributeError:
+ pass
return module