-
-
Notifications
You must be signed in to change notification settings - Fork 276
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "Use importlib instead of pkg_resources for determining namesp…
- Loading branch information
1 parent
a62f37d
commit a5bd030
Showing
1 changed file
with
8 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,70 +3,15 @@ | |
# Copyright (c) 2021 Daniël van Noord <[email protected]> | ||
# Copyright (c) 2021 Neil Girdhar <[email protected]> | ||
|
||
try: | ||
import pkg_resources | ||
except ImportError: | ||
pkg_resources = None # type: ignore[assignment] | ||
|
||
from importlib import abc, util | ||
|
||
from astroid.const import PY36 | ||
|
||
|
||
def _is_old_setuptools_namespace_package(modname: str) -> bool: | ||
"""Check for old types of setuptools namespace packages. | ||
See https://setuptools.pypa.io/en/latest/pkg_resources.html and | ||
https://packaging.python.org/en/latest/guides/packaging-namespace-packages/ | ||
Because pkg_resources is slow to import we only do so if explicitly necessary. | ||
""" | ||
try: | ||
import pkg_resources # pylint: disable=import-outside-toplevel | ||
except ImportError: | ||
return False | ||
|
||
def is_namespace(modname): | ||
return ( | ||
hasattr(pkg_resources, "_namespace_packages") | ||
and modname in pkg_resources._namespace_packages # type: ignore[attr-defined] | ||
) | ||
|
||
|
||
def is_namespace(modname: str) -> bool: | ||
"""Determine whether we encounter a namespace package.""" | ||
if PY36: | ||
# On Python 3.6 an AttributeError is raised when a package | ||
# is lacking a __path__ attribute and thus is not a | ||
# package. | ||
try: | ||
spec = util.find_spec(modname) | ||
except (AttributeError, ValueError): | ||
return _is_old_setuptools_namespace_package(modname) | ||
else: | ||
try: | ||
spec = util.find_spec(modname) | ||
except ValueError: | ||
return _is_old_setuptools_namespace_package(modname) | ||
|
||
# If there is no spec or origin this is a namespace package | ||
# See: https://docs.python.org/3/library/importlib.html#importlib.machinery.ModuleSpec.origin | ||
# We assume builtin packages are never namespace | ||
if not spec or not spec.origin or spec.origin == "built-in": | ||
return False | ||
|
||
# If there is no loader the package is namespace | ||
# See https://docs.python.org/3/library/importlib.html#importlib.abc.PathEntryFinder.find_loader | ||
if not spec.loader: | ||
return True | ||
# This checks for _frozen_importlib.FrozenImporter, which does not inherit from InspectLoader | ||
if hasattr(spec.loader, "_ORIGIN") and spec.loader._ORIGIN == "frozen": | ||
return False | ||
# Other loaders are namespace packages | ||
if not isinstance(spec.loader, abc.InspectLoader): | ||
return True | ||
|
||
# Lastly we check if the package declares itself a namespace package | ||
try: | ||
source = spec.loader.get_source(spec.origin) | ||
# If the loader can't handle the spec, we're dealing with a namespace package | ||
except ImportError: | ||
return False | ||
return bool( | ||
source and "pkg_resources" in source and "declare_namespace(__name__)" in source | ||
pkg_resources is not None | ||
and hasattr(pkg_resources, "_namespace_packages") | ||
and modname in pkg_resources._namespace_packages | ||
) |