mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
bpo-32946: Speed up "from ... import ..." from non-packages. (GH-5873)
This commit is contained in:
parent
b931bd0a2f
commit
4e2442505c
4 changed files with 302 additions and 288 deletions
|
@ -1016,31 +1016,30 @@ def _handle_fromlist(module, fromlist, import_, *, recursive=False):
|
|||
"""
|
||||
# The hell that is fromlist ...
|
||||
# If a package was imported, try to import stuff from fromlist.
|
||||
if hasattr(module, '__path__'):
|
||||
for x in fromlist:
|
||||
if not isinstance(x, str):
|
||||
if recursive:
|
||||
where = module.__name__ + '.__all__'
|
||||
else:
|
||||
where = "``from list''"
|
||||
raise TypeError(f"Item in {where} must be str, "
|
||||
f"not {type(x).__name__}")
|
||||
elif x == '*':
|
||||
if not recursive and hasattr(module, '__all__'):
|
||||
_handle_fromlist(module, module.__all__, import_,
|
||||
recursive=True)
|
||||
elif not hasattr(module, x):
|
||||
from_name = '{}.{}'.format(module.__name__, x)
|
||||
try:
|
||||
_call_with_frames_removed(import_, from_name)
|
||||
except ModuleNotFoundError as exc:
|
||||
# Backwards-compatibility dictates we ignore failed
|
||||
# imports triggered by fromlist for modules that don't
|
||||
# exist.
|
||||
if (exc.name == from_name and
|
||||
sys.modules.get(from_name, _NEEDS_LOADING) is not None):
|
||||
continue
|
||||
raise
|
||||
for x in fromlist:
|
||||
if not isinstance(x, str):
|
||||
if recursive:
|
||||
where = module.__name__ + '.__all__'
|
||||
else:
|
||||
where = "``from list''"
|
||||
raise TypeError(f"Item in {where} must be str, "
|
||||
f"not {type(x).__name__}")
|
||||
elif x == '*':
|
||||
if not recursive and hasattr(module, '__all__'):
|
||||
_handle_fromlist(module, module.__all__, import_,
|
||||
recursive=True)
|
||||
elif not hasattr(module, x):
|
||||
from_name = '{}.{}'.format(module.__name__, x)
|
||||
try:
|
||||
_call_with_frames_removed(import_, from_name)
|
||||
except ModuleNotFoundError as exc:
|
||||
# Backwards-compatibility dictates we ignore failed
|
||||
# imports triggered by fromlist for modules that don't
|
||||
# exist.
|
||||
if (exc.name == from_name and
|
||||
sys.modules.get(from_name, _NEEDS_LOADING) is not None):
|
||||
continue
|
||||
raise
|
||||
return module
|
||||
|
||||
|
||||
|
@ -1102,8 +1101,10 @@ def __import__(name, globals=None, locals=None, fromlist=(), level=0):
|
|||
# Slice end needs to be positive to alleviate need to special-case
|
||||
# when ``'.' not in name``.
|
||||
return sys.modules[module.__name__[:len(module.__name__)-cut_off]]
|
||||
else:
|
||||
elif hasattr(module, '__path__'):
|
||||
return _handle_fromlist(module, fromlist, _gcd_import)
|
||||
else:
|
||||
return module
|
||||
|
||||
|
||||
def _builtin_from_name(name):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue