summaryrefslogtreecommitdiffstats
path: root/Lib/importlib/_bootstrap.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/importlib/_bootstrap.py')
-rw-r--r--Lib/importlib/_bootstrap.py28
1 files changed, 25 insertions, 3 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 1b3b430..fa99f56 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -878,13 +878,20 @@ def _find_spec_legacy(finder, name, path):
def _find_spec(name, path, target=None):
"""Find a module's loader."""
- if sys.meta_path is not None and not sys.meta_path:
+ meta_path = sys.meta_path
+ if meta_path is None:
+ # PyImport_Cleanup() is running or has been called.
+ raise ImportError("sys.meta_path is None, Python is likely "
+ "shutting down")
+
+ if not meta_path:
_warnings.warn('sys.meta_path is empty', ImportWarning)
+
# We check sys.modules here for the reload case. While a passed-in
# target will usually indicate a reload there is no guarantee, whereas
# sys.modules provides one.
is_reload = name in sys.modules
- for finder in sys.meta_path:
+ for finder in meta_path:
with _ImportLockContext():
try:
find_spec = finder.find_spec
@@ -925,6 +932,9 @@ def _sanity_check(name, package, level):
if level > 0:
if not isinstance(package, str):
raise TypeError('__package__ not set to a string')
+ elif not package:
+ raise ImportError('attempted relative import with no known parent '
+ 'package')
elif package not in sys.modules:
msg = ('Parent module {!r} not loaded, cannot perform relative '
'import')
@@ -1033,7 +1043,19 @@ def _calc___package__(globals):
"""
package = globals.get('__package__')
- if package is None:
+ spec = globals.get('__spec__')
+ if package is not None:
+ if spec is not None and package != spec.parent:
+ _warnings.warn("__package__ != __spec__.parent "
+ f"({package!r} != {spec.parent!r})",
+ ImportWarning, stacklevel=3)
+ return package
+ elif spec is not None:
+ return spec.parent
+ else:
+ _warnings.warn("can't resolve package from __spec__ or __package__, "
+ "falling back on __name__ and __path__",
+ ImportWarning, stacklevel=3)
package = globals['__name__']
if '__path__' not in globals:
package = package.rpartition('.')[0]