diff --git a/mypy/applytype.py b/mypy/applytype.py index 324e40db7e65..6a5b5bf85cc3 100644 --- a/mypy/applytype.py +++ b/mypy/applytype.py @@ -18,7 +18,7 @@ def get_target_type( context: Context, skip_unsatisfied: bool ) -> Optional[Type]: - # TODO(shantanu): fix for ParamSpecType + # TODO(PEP612): fix for ParamSpecType if isinstance(tvar, ParamSpecType): return None assert isinstance(tvar, TypeVarType) diff --git a/mypy/checker.py b/mypy/checker.py index 4cd5c6c5580d..a338cc27f73b 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1409,7 +1409,7 @@ def expand_typevars(self, defn: FuncItem, if defn.info: # Class type variables tvars += defn.info.defn.type_vars or [] - # TODO(shantanu): audit for paramspec + # TODO(PEP612): audit for paramspec for tvar in tvars: if isinstance(tvar, TypeVarType) and tvar.values: subst.append([(tvar.id, value) for value in tvar.values]) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 280e9a35d537..22f6775086e2 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4477,7 +4477,7 @@ def merge_typevars_in_callables_by_name( for tv in target.variables: name = tv.fullname if name not in unique_typevars: - # TODO(shantanu): fix for ParamSpecType + # TODO(PEP612): fix for ParamSpecType if isinstance(tv, ParamSpecType): continue assert isinstance(tv, TypeVarType) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 43fe7944ec70..3bdd95c40cb0 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -41,7 +41,7 @@ def freshen_function_type_vars(callee: F) -> F: tvs = [] tvmap: Dict[TypeVarId, Type] = {} for v in callee.variables: - # TODO(shantanu): fix for ParamSpecType + # TODO(PEP612): fix for ParamSpecType if isinstance(v, ParamSpecType): continue assert isinstance(v, TypeVarType) diff --git a/mypy/semanal.py b/mypy/semanal.py index 49c24cde0447..3a1e5628a99b 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1327,8 +1327,8 @@ class Foo(Bar, Generic[T]): ... for name, tvar_expr in declared_tvars: tvar_def = self.tvar_scope.bind_new(name, tvar_expr) if isinstance(tvar_def, TypeVarType): - # This can also be `ParamSpecType`, - # error will be reported elsewhere: #11218 + # TODO(PEP612): fix for ParamSpecType + # Error will be reported elsewhere: #11218 tvar_defs.append(tvar_def) return base_type_exprs, tvar_defs, is_protocol diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 0aa90d49cfb5..33ac20298fc7 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -692,7 +692,7 @@ def analyze_callable_args_for_paramspec( if not isinstance(tvar_def, ParamSpecType): return None - # TODO(shantanu): construct correct type for paramspec + # TODO(PEP612): construct correct type for paramspec return CallableType( [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)], [nodes.ARG_STAR, nodes.ARG_STAR2], @@ -745,7 +745,7 @@ def analyze_callable_type(self, t: UnboundType) -> Type: ) if maybe_ret is None: # Callable[?, RET] (where ? is something invalid) - # TODO(shantanu): change error to mention paramspec, once we actually have some + # TODO(PEP612): change error to mention paramspec, once we actually have some # support for it self.fail('The first argument to Callable must be a list of types or "..."', t) return AnyType(TypeOfAny.from_error) diff --git a/mypy/typeops.py b/mypy/typeops.py index fc0dee538d79..09afcb6e6fba 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -511,7 +511,7 @@ def true_or_false(t: Type) -> ProperType: def erase_def_to_union_or_bound(tdef: TypeVarLikeType) -> Type: - # TODO(shantanu): fix for ParamSpecType + # TODO(PEP612): fix for ParamSpecType if isinstance(tdef, ParamSpecType): return AnyType(TypeOfAny.from_error) assert isinstance(tdef, TypeVarType) diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index a817ae8064c6..4f1c917c32ff 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -15,7 +15,7 @@ def foo1(x: Callable[P, int]) -> Callable[P, str]: ... def foo2(x: P) -> P: ... # E: Invalid location for ParamSpec "P" \ # N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]' -# TODO(shantanu): uncomment once we have support for Concatenate +# TODO(PEP612): uncomment once we have support for Concatenate # def foo3(x: Concatenate[int, P]) -> int: ... $ E: Invalid location for Concatenate def foo4(x: List[P]) -> None: ... # E: Invalid location for ParamSpec "P" \ @@ -29,6 +29,7 @@ def foo6(x: Callable[[P], int]) -> None: ... # E: Invalid location for ParamSpe [builtins fixtures/tuple.pyi] [case testParamSpecTemporaryAnyBehaviour] +# TODO(PEP612): behaviour tested here should change # This is a test of mypy's temporary behaviour in lieu of full support for ParamSpec from typing import Callable, List, Iterator, TypeVar from typing_extensions import ParamSpec @@ -50,3 +51,28 @@ def whatever(x: int) -> Iterator[int]: reveal_type(whatever) # N: Revealed type is "def (*Any, **Any) -> builtins.list[builtins.int*]" reveal_type(whatever(217)) # N: Revealed type is "builtins.list[builtins.int*]" [builtins fixtures/tuple.pyi] + +[case testGenericParamSpecTemporaryBehaviour] +# flags: --python-version 3.10 +# TODO(PEP612): behaviour tested here should change +from typing import Generic, TypeVar, Callable, ParamSpec + +T = TypeVar("T") +P = ParamSpec("P") + +class X(Generic[T, P]): # E: Free type variable expected in Generic[...] + f: Callable[P, int] # E: The first argument to Callable must be a list of types or "..." + x: T +[out] + +[case testInvalidParamSpecType] +# flags: --python-version 3.10 +from typing import ParamSpec + +P = ParamSpec("P") + +class MyFunction(P): # E: Invalid location for ParamSpec "P" \ + # N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]' + ... + +a: MyFunction[int] # E: "MyFunction" expects no type arguments, but 1 given diff --git a/test-data/unit/semanal-errors.test b/test-data/unit/semanal-errors.test index 62ffb4e62b07..9dc75a4930e4 100644 --- a/test-data/unit/semanal-errors.test +++ b/test-data/unit/semanal-errors.test @@ -41,49 +41,6 @@ x = None # type: X [out] main:2: error: Name "X" is not defined -[case testInvalidParamSpecType1] -# flags: --python-version 3.10 -from typing import ParamSpec - -P = ParamSpec("P") - -class MyFunction(P): - ... - -a: MyFunction[int] -[out] -main:6: error: Invalid location for ParamSpec "P" -main:6: note: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]' -main:9: error: "MyFunction" expects no type arguments, but 1 given - -[case testInvalidParamSpecType2] -from typing_extensions import ParamSpec - -P = ParamSpec("P") - -class MyFunction(P): - ... - -a: MyFunction[int] -[out] -main:5: error: Invalid location for ParamSpec "P" -main:5: note: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]' -main:8: error: "MyFunction" expects no type arguments, but 1 given - -[case testGenericParamSpec] -# flags: --python-version 3.10 -from typing import Generic, TypeVar, Callable, ParamSpec - -T = TypeVar("T") -P = ParamSpec("P") - -class X(Generic[T, P]): - f: Callable[P, int] - x: T -[out] -main:7: error: Free type variable expected in Generic[...] -main:8: error: The first argument to Callable must be a list of types or "..." - [case testInvalidGenericArg] from typing import TypeVar, Generic t = TypeVar('t')