diff --git a/mypy/semanal.py b/mypy/semanal.py index 71f588a144a0..5ee372c43bd1 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -5107,6 +5107,11 @@ def lookup_qualified( if isinstance(typ, AnyType): # Allow access through Var with Any type without error. return self.implicit_symbol(sym, name, parts[i:], typ) + # This might be something like valid `P.args` or invalid `P.__bound__` access. + # Important note that `ParamSpecExpr` is also ignored in other places. + # See https://github.com/python/mypy/pull/13468 + if isinstance(node, ParamSpecExpr) and part in ("args", "kwargs"): + return None # Lookup through invalid node, such as variable or function nextsym = None if not nextsym or nextsym.module_hidden: diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index bac23f31c289..a561acba693c 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -1127,3 +1127,38 @@ def func(callback: Callable[P1, str]) -> Callable[P1, str]: return "foo" return inner [builtins fixtures/paramspec.pyi] + +[case testParamSpecTestPropAccess] +from typing import Callable +from typing_extensions import ParamSpec + +P1 = ParamSpec("P1") + +def func1(callback: Callable[P1, str]) -> Callable[P1, str]: + def inner( + *args: P1.typo, # E: Use "P1.args" for variadic "*" parameter \ + # E: Name "P1.typo" is not defined + **kwargs: P1.kwargs, + ) -> str: + return "foo" + return inner + +def func2(callback: Callable[P1, str]) -> Callable[P1, str]: + def inner( + *args: P1.args, + **kwargs: P1.__bound__, # E: Use "P1.kwargs" for variadic "**" parameter \ + # E: Name "P1.__bound__" is not defined + ) -> str: + return "foo" + return inner + +def func3(callback: Callable[P1, str]) -> Callable[P1, str]: + def inner( + *args: P1.__bound__, # E: Use "P1.args" for variadic "*" parameter \ + # E: Name "P1.__bound__" is not defined + **kwargs: P1.invalid, # E: Use "P1.kwargs" for variadic "**" parameter \ + # E: Name "P1.invalid" is not defined + ) -> str: + return "foo" + return inner +[builtins fixtures/paramspec.pyi]