Skip to content

Commit

Permalink
Fix issue with importing of frozen submodules
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielNoord committed Dec 23, 2024
1 parent 50916d6 commit 5306ff5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 23 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ What's New in astroid 3.3.8?
============================
Release date: TBA

* Fix inability to import `collections.abc` in python 3.13.1. The reported fixes in astroid 3.3.6
and 3.3.7 did not actually fix this issue.

Closes pylint-dev/pylint#10112


What's New in astroid 3.3.7?
============================
Release date: 2024-12-20

This release was yanked.

* Fix inability to import `collections.abc` in python 3.13.1. The reported fix in astroid 3.3.6
did not actually fix this issue.

Expand Down
58 changes: 35 additions & 23 deletions astroid/interpreter/_import/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,31 @@ def find_module(
type=ModuleType.C_BUILTIN,
)

if submodule_path is not None:
search_paths = list(submodule_path)
else:
search_paths = sys.path

# First try to find the module using normal search paths. If that fails, fall back to
# the frozen module finder.
suffixes = (".py", ".pyi", importlib.machinery.BYTECODE_SUFFIXES[0])
for entry in search_paths:
package_directory = os.path.join(entry, modname)
for suffix in suffixes:
package_file_name = "__init__" + suffix
file_path = os.path.join(package_directory, package_file_name)
if os.path.isfile(file_path):
return ModuleSpec(
name=modname,
location=package_directory,
type=ModuleType.PKG_DIRECTORY,
)
for suffix, type_ in ImportlibFinder._SUFFIXES:
file_name = modname + suffix
file_path = os.path.join(entry, file_name)
if os.path.isfile(file_path):
return ModuleSpec(name=modname, location=file_path, type=type_)

# sys.stdlib_module_names was added in Python 3.10
if PY310_PLUS:
# If the module is a stdlib module, check whether this is a frozen module. Note that
Expand All @@ -150,7 +175,16 @@ def find_module(
if modname in sys.stdlib_module_names or (
processed and processed[0] in sys.stdlib_module_names
):
spec = importlib.util.find_spec(".".join((*processed, modname)))
try:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=Warning)
spec = importlib.util.find_spec(".".join((*processed, modname)))
except ValueError:
# `find_spec` raises a ValueError for modules that are missing their `__spec__`
# attributes. We don't really understand why, but this is likely caused by
# us re-implementing the import behaviour but not correctly.
spec = None

if (
spec
and spec.loader # type: ignore[comparison-overlap] # noqa: E501
Expand Down Expand Up @@ -186,28 +220,6 @@ def find_module(
except ValueError:
pass

if submodule_path is not None:
search_paths = list(submodule_path)
else:
search_paths = sys.path

suffixes = (".py", ".pyi", importlib.machinery.BYTECODE_SUFFIXES[0])
for entry in search_paths:
package_directory = os.path.join(entry, modname)
for suffix in suffixes:
package_file_name = "__init__" + suffix
file_path = os.path.join(package_directory, package_file_name)
if os.path.isfile(file_path):
return ModuleSpec(
name=modname,
location=package_directory,
type=ModuleType.PKG_DIRECTORY,
)
for suffix, type_ in ImportlibFinder._SUFFIXES:
file_name = modname + suffix
file_path = os.path.join(entry, file_name)
if os.path.isfile(file_path):
return ModuleSpec(name=modname, location=file_path, type=type_)
return None

def contribute_to_path(
Expand Down

0 comments on commit 5306ff5

Please sign in to comment.