diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-03-11 08:52:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-11 08:52:37 (GMT) |
commit | 4e2442505c5e9eec396dcef4d2e6bdd2b6f92fc9 (patch) | |
tree | ac8cbbdae9d8772f84254b79d8da9f6df1a2e2b6 /Lib/importlib | |
parent | b931bd0a2fe7e9293339019352baf3317166b769 (diff) | |
download | cpython-4e2442505c5e9eec396dcef4d2e6bdd2b6f92fc9.zip cpython-4e2442505c5e9eec396dcef4d2e6bdd2b6f92fc9.tar.gz cpython-4e2442505c5e9eec396dcef4d2e6bdd2b6f92fc9.tar.bz2 |
bpo-32946: Speed up "from ... import ..." from non-packages. (GH-5873)
Diffstat (limited to 'Lib/importlib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 2bdd192..ba5a053 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -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): |