diff --git a/ChangeLog b/ChangeLog index 036f888e08..8ab5375b4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,10 @@ Release date: TBA Closes #2521 Closes #2523 +* Fix crash when typing._alias() call is missing arguments. + + Closes #2513 + What's New in astroid 3.3.6? ============================ diff --git a/astroid/brain/brain_typing.py b/astroid/brain/brain_typing.py index 239e63af24..c44687bf89 100644 --- a/astroid/brain/brain_typing.py +++ b/astroid/brain/brain_typing.py @@ -258,6 +258,7 @@ def _looks_like_typing_alias(node: Call) -> bool: isinstance(node.func, Name) # TODO: remove _DeprecatedGenericAlias when Py3.14 min and node.func.name in {"_alias", "_DeprecatedGenericAlias"} + and len(node.args) == 2 and ( # _alias function works also for builtins object such as list and dict isinstance(node.args[0], (Attribute, Name)) diff --git a/tests/brain/test_typing.py b/tests/brain/test_typing.py index 1e8e3eaf88..11b77b7f9e 100644 --- a/tests/brain/test_typing.py +++ b/tests/brain/test_typing.py @@ -4,7 +4,7 @@ import pytest -from astroid import builder +from astroid import bases, builder, nodes from astroid.exceptions import InferenceError @@ -23,3 +23,50 @@ def test_infer_typevar() -> None: ) with pytest.raises(InferenceError): call_node.inferred() + + +class TestTypingAlias: + def test_infer_typing_alias(self) -> None: + """ + Test that _alias() calls can be inferred. + """ + node = builder.extract_node( + """ + from typing import _alias + x = _alias(int, float) + """ + ) + assert isinstance(node, nodes.Assign) + assert isinstance(node.value, nodes.Call) + inferred = next(node.value.infer()) + assert isinstance(inferred, nodes.ClassDef) + assert len(inferred.bases) == 1 + assert inferred.bases[0].name == "int" + + @pytest.mark.parametrize( + "alias_args", + [ + "", # two missing arguments + "int", # one missing argument + "int, float, tuple", # one additional argument + ], + ) + def test_infer_typing_alias_incorrect_number_of_arguments( + self, alias_args: str + ) -> None: + """ + Regression test for: https://github.com/pylint-dev/astroid/issues/2513 + + Test that _alias() calls with the incorrect number of arguments can be inferred. + """ + node = builder.extract_node( + f""" + from typing import _alias + x = _alias({alias_args}) + """ + ) + assert isinstance(node, nodes.Assign) + assert isinstance(node.value, nodes.Call) + inferred = next(node.value.infer()) + assert isinstance(inferred, bases.Instance) + assert inferred.name == "_SpecialGenericAlias"