summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-02-22 23:33:05 (GMT)
committerBrett Cannon <brett@python.org>2012-02-22 23:33:05 (GMT)
commit34d8e41a474f43dabca4096e5f945ca67e69a5b8 (patch)
treeb4c23a69a55c1831c758c0bf24caffaa38a683aa
parentb429d3b09c1f57a42d0cc218a7235383091ce317 (diff)
downloadcpython-34d8e41a474f43dabca4096e5f945ca67e69a5b8.zip
cpython-34d8e41a474f43dabca4096e5f945ca67e69a5b8.tar.gz
cpython-34d8e41a474f43dabca4096e5f945ca67e69a5b8.tar.bz2
Refactor importlib to make it easier to re-implement in C.
-rw-r--r--Lib/importlib/_bootstrap.py76
1 files changed, 31 insertions, 45 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index d10ab2f..6c4367f 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -918,20 +918,12 @@ def _find_module(name, path):
return None
-def _set___package__(module):
- """Set __package__ on a module."""
- # Watch out for what comes out of sys.modules to not be a module,
- # e.g. an int.
- try:
- module.__package__ = module.__name__
- if not hasattr(module, '__path__'):
- module.__package__ = module.__package__.rpartition('.')[0]
- except AttributeError:
- pass
-
-
def _sanity_check(name, package, level):
"""Verify arguments are "sane"."""
+ if not hasattr(name, 'rpartition'):
+ raise TypeError("module name must be str, not {}".format(type(name)))
+ if level < 0:
+ raise ValueError('level must be >= 0')
if package:
if not hasattr(package, 'rindex'):
raise ValueError("__package__ not set to a string")
@@ -943,13 +935,12 @@ def _sanity_check(name, package, level):
raise ValueError("Empty module name")
-def _find_search_path(name, import_):
- """Find the search path for a module.
+_IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder]
- import_ is expected to be a callable which takes the name of a module to
- import. It is required to decouple the function from importlib.
+_ERR_MSG = 'No module named {!r}'
- """
+def _find_and_load(name, import_):
+ """Find and load the module."""
path = None
parent = name.rpartition('.')[0]
if parent:
@@ -962,13 +953,28 @@ def _find_search_path(name, import_):
except AttributeError:
msg = (_ERR_MSG + '; {} is not a package').format(name, parent)
raise ImportError(msg)
- return parent, path
-
-
-
-_IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder]
+ loader = _find_module(name, path)
+ if loader is None:
+ raise ImportError(_ERR_MSG.format(name))
+ elif name not in sys.modules:
+ # The parent import may have already imported this module.
+ loader.load_module(name)
+ # Backwards-compatibility; be nicer to skip the dict lookup.
+ module = sys.modules[name]
+ if parent:
+ # Set the module as an attribute on its parent.
+ parent_module = sys.modules[parent]
+ setattr(parent_module, name.rpartition('.')[2], module)
+ # Set __package__ if the loader did not.
+ if not hasattr(module, '__package__') or module.__package__ is None:
+ try:
+ module.__package__ = module.__name__
+ if not hasattr(module, '__path__'):
+ module.__package__ = module.__package__.rpartition('.')[0]
+ except AttributeError:
+ pass
+ return module
-_ERR_MSG = 'No module named {!r}'
def _gcd_import(name, package=None, level=0):
"""Import and return the module based on its name, the package the call is
@@ -991,24 +997,8 @@ def _gcd_import(name, package=None, level=0):
raise ImportError(message)
return module
except KeyError:
- pass
- parent, path = _find_search_path(name, _gcd_import)
- loader = _find_module(name, path)
- if loader is None:
- raise ImportError(_ERR_MSG.format(name))
- elif name not in sys.modules:
- # The parent import may have already imported this module.
- loader.load_module(name)
- # Backwards-compatibility; be nicer to skip the dict lookup.
- module = sys.modules[name]
- if parent:
- # Set the module as an attribute on its parent.
- parent_module = sys.modules[parent]
- setattr(parent_module, name.rpartition('.')[2], module)
- # Set __package__ if the loader did not.
- if not hasattr(module, '__package__') or module.__package__ is None:
- _set___package__(module)
- return module
+ pass # Don't want to chain the exception
+ return _find_and_load(name, _gcd_import)
def _return_module(module, name, fromlist, level, import_):
@@ -1071,12 +1061,8 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0):
import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
"""
- if not hasattr(name, 'rpartition'):
- raise TypeError("module name must be str, not {}".format(type(name)))
if level == 0:
module = _gcd_import(name)
- elif level < 0:
- raise ValueError('level must be >= 0')
else:
package = _calc___package__(globals)
module = _gcd_import(name, package, level)