diff --git a/astroid/brain/brain_typing.py b/astroid/brain/brain_typing.py index e1679ae72..8ad8a8bd3 100644 --- a/astroid/brain/brain_typing.py +++ b/astroid/brain/brain_typing.py @@ -345,16 +345,20 @@ def _looks_like_special_alias(node: nodes.Call) -> bool: PY37: Callable = _VariadicGenericAlias(collections.abc.Callable, (), special=True) PY39: Callable = _CallableType(collections.abc.Callable, 2) """ - return isinstance(node.func, nodes.Name) and ( - ( - node.func.name == "_TupleType" - and isinstance(node.args[0], nodes.Name) - and node.args[0].name == "tuple" - ) - or ( - node.func.name == "_CallableType" - and isinstance(node.args[0], nodes.Attribute) - and node.args[0].as_string() == "collections.abc.Callable" + return ( + isinstance(node.func, nodes.Name) + and node.args + and ( + ( + node.func.name == "_TupleType" + and isinstance(node.args[0], nodes.Name) + and node.args[0].name == "tuple" + ) + or ( + node.func.name == "_CallableType" + and isinstance(node.args[0], nodes.Attribute) + and node.args[0].as_string() == "collections.abc.Callable" + ) ) ) diff --git a/tests/brain/test_typing.py b/tests/brain/test_typing.py index 11b77b7f9..744be9458 100644 --- a/tests/brain/test_typing.py +++ b/tests/brain/test_typing.py @@ -70,3 +70,23 @@ def test_infer_typing_alias_incorrect_number_of_arguments( inferred = next(node.value.infer()) assert isinstance(inferred, bases.Instance) assert inferred.name == "_SpecialGenericAlias" + + +class TestSpecialAlias: + @pytest.mark.parametrize( + "code", + [ + "_CallableType()", + "_TupleType()", + ], + ) + def test_special_alias_no_crash_on_empty_args(self, code: str) -> None: + """ + Regression test for: https://github.com/pylint-dev/astroid/issues/2772 + + Test that _CallableType() and _TupleType() calls with no arguments + do not cause an IndexError. + """ + # Should not raise IndexError + module = builder.parse(code) + assert isinstance(module, nodes.Module)