diff --git a/.gitignore b/.gitignore index d807609565..3cb5148179 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ build-stamp .pytest_cache/ .mypy_cache/ .benchmarks/ +venv/ diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index 83435efabd..749e3b912a 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -1033,6 +1033,26 @@ def _get_imported_module( dotted_modname = get_import_name(importnode, modname) self.add_message("import-error", args=repr(dotted_modname), node=importnode) + except AttributeError as e: + # Handle mypyc compiled modules that may not have __dict__ + if "__dict__" in str(e): + if not self.linter.is_message_enabled("import-error"): + return None + if _ignore_import_failure(importnode, modname, self._ignored_modules): + return None + if ( + not self.linter.config.analyse_fallback_blocks + and is_from_fallback_block(importnode) + ): + return None + + dotted_modname = get_import_name(importnode, modname) + self.add_message( + "import-error", args=repr(dotted_modname), node=importnode + ) + else: + # Re-raise other AttributeErrors + raise astroid.AstroidError from e except Exception as e: # pragma: no cover raise astroid.AstroidError from e return None diff --git a/tests/functional/i/import_mypy_extension.py b/tests/functional/i/import_mypy_extension.py new file mode 100644 index 0000000000..c0644a5e3e --- /dev/null +++ b/tests/functional/i/import_mypy_extension.py @@ -0,0 +1,12 @@ +"""Test for mypy extension package import crash regression. + +This reproduces the crash described in issue #10223 where importing +mypy modules with --extension-pkg-allow-list=mypy caused an AttributeError +crash due to mypyc-compiled objects not having __dict__ attributes. + +The fix ensures this generates an import-error message instead of crashing. +""" +# pylint: disable=unused-import + +# This should not crash when using --extension-pkg-allow-list=mypy +import mypy.build # [import-error] diff --git a/tests/functional/i/import_mypy_extension.rc b/tests/functional/i/import_mypy_extension.rc new file mode 100644 index 0000000000..14c2a37e3e --- /dev/null +++ b/tests/functional/i/import_mypy_extension.rc @@ -0,0 +1,5 @@ +[Messages Control] +disable=C,R,W + +[TYPECHECK] +extension-pkg-allow-list=mypy diff --git a/tests/functional/i/import_mypy_extension.txt b/tests/functional/i/import_mypy_extension.txt new file mode 100644 index 0000000000..d055de392d --- /dev/null +++ b/tests/functional/i/import_mypy_extension.txt @@ -0,0 +1 @@ +import-error:12:0:12:17::Unable to import 'mypy.build':UNDEFINED