def _import(name, globals=None, locals=None, fromlist=None, level=_default_level):
"""__import__() replacement function that tracks module dependencies."""
# Track our current parent module. This is used to find our current place
# in the dependency graph.
global _parent
parent = _parent
_parent = name
# Perform the actual import work using the base import function.
base = _baseimport(name, globals, locals, fromlist, level)
if base is not None and parent is not None:
m = base
# We manually walk through the imported hierarchy because the import
# function only returns the top-level package reference for a nested
# import statement (e.g. 'package' for `import package.module`) when
# no fromlist has been specified. It's possible that the package
# might not have all of its descendents as attributes, in which case
# we fall back to using the immediate ancestor of the module instead.
if fromlist is None:
for component in name.split('.')[1:]:
try:
m = getattr(m, component)
except AttributeError:
m = sys.modules[m.__name__ + '.' + component]
# If this is a nested import for a reloadable (source-based) module,
# we append ourself to our parent's dependency list.
if hasattr(m, '__file__'):
l = _dependencies.setdefault(parent, [])
l.append(m)
# Lastly, we always restore our global _parent pointer.
_parent = parent
return base
评论列表
文章目录