Add support to the ihooks module for relative imports.

This commit is contained in:
Neil Schemenauer 2009-10-14 19:23:53 +00:00
parent 04437ebadd
commit e6039f0978
2 changed files with 55 additions and 21 deletions

View File

@ -49,7 +49,7 @@ by the way the __import__ hook is used by the Python interpreter.) It
would also do wise to install a different version of reload().
"""
from warnings import warnpy3k
from warnings import warnpy3k, warn
warnpy3k("the ihooks module has been removed in Python 3.0", stacklevel=2)
del warnpy3k
@ -401,8 +401,9 @@ class ModuleImporter(BasicModuleImporter):
"""A module importer that supports packages."""
def import_module(self, name, globals=None, locals=None, fromlist=None):
parent = self.determine_parent(globals)
def import_module(self, name, globals=None, locals=None, fromlist=None,
level=-1):
parent = self.determine_parent(globals, level)
q, tail = self.find_head_package(parent, str(name))
m = self.load_tail(q, tail)
if not fromlist:
@ -411,21 +412,50 @@ class ModuleImporter(BasicModuleImporter):
self.ensure_fromlist(m, fromlist)
return m
def determine_parent(self, globals):
if not globals or not "__name__" in globals:
def determine_parent(self, globals, level=-1):
if not globals or not level:
return None
pname = globals['__name__']
if "__path__" in globals:
parent = self.modules[pname]
assert globals is parent.__dict__
return parent
if '.' in pname:
i = pname.rfind('.')
pname = pname[:i]
parent = self.modules[pname]
assert parent.__name__ == pname
return parent
return None
pkgname = globals.get('__package__')
if pkgname is not None:
if not pkgname and level > 0:
raise ValueError, 'Attempted relative import in non-package'
else:
# __package__ not set, figure it out and set it
modname = globals.get('__name__')
if modname is None:
return None
if "__path__" in globals:
# __path__ is set so modname is already the package name
pkgname = modname
else:
# normal module, work out package name if any
if '.' not in modname:
if level > 0:
raise ValueError, ('Attempted relative import in '
'non-package')
globals['__package__'] = None
return None
pkgname = modname.rpartition('.')[0]
globals['__package__'] = pkgname
if level > 0:
dot = len(pkgname)
for x in range(level, 1, -1):
try:
dot = pkgname.rindex('.', 0, dot)
except ValueError:
raise ValueError('attempted relative import beyond '
'top-level package')
pkgname = pkgname[:dot]
try:
return sys.modules[pkgname]
except KeyError:
if level < 1:
warn("Parent module '%s' not found while handling "
"absolute import" % pkgname, RuntimeWarning, 1)
return None
else:
raise SystemError, ("Parent module '%s' not loaded, cannot "
"perform relative import" % pkgname)
def find_head_package(self, parent, name):
if '.' in name:
@ -446,7 +476,7 @@ class ModuleImporter(BasicModuleImporter):
parent = None
q = self.import_it(head, qname, parent)
if q: return q, tail
raise ImportError, "No module named " + qname
raise ImportError, "No module named '%s'" % qname
def load_tail(self, q, tail):
m = q
@ -457,7 +487,7 @@ class ModuleImporter(BasicModuleImporter):
mname = "%s.%s" % (m.__name__, head)
m = self.import_it(head, mname, m)
if not m:
raise ImportError, "No module named " + mname
raise ImportError, "No module named '%s'" % mname
return m
def ensure_fromlist(self, m, fromlist, recursive=0):
@ -475,11 +505,13 @@ class ModuleImporter(BasicModuleImporter):
subname = "%s.%s" % (m.__name__, sub)
submod = self.import_it(sub, subname, m)
if not submod:
raise ImportError, "No module named " + subname
raise ImportError, "No module named '%s'" % subname
def import_it(self, partname, fqname, parent, force_load=0):
if not partname:
raise ValueError, "Empty module name"
# completely empty module name should only happen in
# 'from . import' or __import__("")
return parent
if not force_load:
try:
return self.modules[fqname]

View File

@ -405,6 +405,8 @@ Core and Builtins
Library
-------
- Add support to the `ihooks` module for relative imports.
- Issue #6894: Fixed the issue urllib2 doesn't respect "no_proxy" environment
- Issue #7086: Added TCP support to SysLogHandler, and tidied up some