mirror of
https://github.com/python/cpython.git
synced 2025-07-30 14:44:10 +00:00
Add support to the ihooks module for relative imports.
This commit is contained in:
parent
04437ebadd
commit
e6039f0978
2 changed files with 55 additions and 21 deletions
|
@ -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().
|
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)
|
warnpy3k("the ihooks module has been removed in Python 3.0", stacklevel=2)
|
||||||
del warnpy3k
|
del warnpy3k
|
||||||
|
|
||||||
|
@ -401,8 +401,9 @@ class ModuleImporter(BasicModuleImporter):
|
||||||
|
|
||||||
"""A module importer that supports packages."""
|
"""A module importer that supports packages."""
|
||||||
|
|
||||||
def import_module(self, name, globals=None, locals=None, fromlist=None):
|
def import_module(self, name, globals=None, locals=None, fromlist=None,
|
||||||
parent = self.determine_parent(globals)
|
level=-1):
|
||||||
|
parent = self.determine_parent(globals, level)
|
||||||
q, tail = self.find_head_package(parent, str(name))
|
q, tail = self.find_head_package(parent, str(name))
|
||||||
m = self.load_tail(q, tail)
|
m = self.load_tail(q, tail)
|
||||||
if not fromlist:
|
if not fromlist:
|
||||||
|
@ -411,21 +412,50 @@ class ModuleImporter(BasicModuleImporter):
|
||||||
self.ensure_fromlist(m, fromlist)
|
self.ensure_fromlist(m, fromlist)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def determine_parent(self, globals):
|
def determine_parent(self, globals, level=-1):
|
||||||
if not globals or not "__name__" in globals:
|
if not globals or not level:
|
||||||
|
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
|
return None
|
||||||
pname = globals['__name__']
|
|
||||||
if "__path__" in globals:
|
if "__path__" in globals:
|
||||||
parent = self.modules[pname]
|
# __path__ is set so modname is already the package name
|
||||||
assert globals is parent.__dict__
|
pkgname = modname
|
||||||
return parent
|
else:
|
||||||
if '.' in pname:
|
# normal module, work out package name if any
|
||||||
i = pname.rfind('.')
|
if '.' not in modname:
|
||||||
pname = pname[:i]
|
if level > 0:
|
||||||
parent = self.modules[pname]
|
raise ValueError, ('Attempted relative import in '
|
||||||
assert parent.__name__ == pname
|
'non-package')
|
||||||
return parent
|
globals['__package__'] = None
|
||||||
return 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):
|
def find_head_package(self, parent, name):
|
||||||
if '.' in name:
|
if '.' in name:
|
||||||
|
@ -446,7 +476,7 @@ class ModuleImporter(BasicModuleImporter):
|
||||||
parent = None
|
parent = None
|
||||||
q = self.import_it(head, qname, parent)
|
q = self.import_it(head, qname, parent)
|
||||||
if q: return q, tail
|
if q: return q, tail
|
||||||
raise ImportError, "No module named " + qname
|
raise ImportError, "No module named '%s'" % qname
|
||||||
|
|
||||||
def load_tail(self, q, tail):
|
def load_tail(self, q, tail):
|
||||||
m = q
|
m = q
|
||||||
|
@ -457,7 +487,7 @@ class ModuleImporter(BasicModuleImporter):
|
||||||
mname = "%s.%s" % (m.__name__, head)
|
mname = "%s.%s" % (m.__name__, head)
|
||||||
m = self.import_it(head, mname, m)
|
m = self.import_it(head, mname, m)
|
||||||
if not m:
|
if not m:
|
||||||
raise ImportError, "No module named " + mname
|
raise ImportError, "No module named '%s'" % mname
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def ensure_fromlist(self, m, fromlist, recursive=0):
|
def ensure_fromlist(self, m, fromlist, recursive=0):
|
||||||
|
@ -475,11 +505,13 @@ class ModuleImporter(BasicModuleImporter):
|
||||||
subname = "%s.%s" % (m.__name__, sub)
|
subname = "%s.%s" % (m.__name__, sub)
|
||||||
submod = self.import_it(sub, subname, m)
|
submod = self.import_it(sub, subname, m)
|
||||||
if not submod:
|
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):
|
def import_it(self, partname, fqname, parent, force_load=0):
|
||||||
if not partname:
|
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:
|
if not force_load:
|
||||||
try:
|
try:
|
||||||
return self.modules[fqname]
|
return self.modules[fqname]
|
||||||
|
|
|
@ -405,6 +405,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Add support to the `ihooks` module for relative imports.
|
||||||
|
|
||||||
- Issue #6894: Fixed the issue urllib2 doesn't respect "no_proxy" environment
|
- Issue #6894: Fixed the issue urllib2 doesn't respect "no_proxy" environment
|
||||||
|
|
||||||
- Issue #7086: Added TCP support to SysLogHandler, and tidied up some
|
- Issue #7086: Added TCP support to SysLogHandler, and tidied up some
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue