From 495b5c9022719a270bccbffd5ec6bf3ad6fd8667 Mon Sep 17 00:00:00 2001
From: kotlinisland <65446343+kotlinisland@users.noreply.github.com>
Date: Mon, 9 Mar 2026 12:58:09 +1000
Subject: [PATCH 1/3] specify that parameter specification should have variance
---
.../mypy/generics_paramspec_variance.toml | 20 ++++++++
.../pyrefly/generics_paramspec_variance.toml | 24 +++++++++
.../pyright/generics_paramspec_variance.toml | 40 +++++++++++++++
conformance/results/results.html | 7 +++
.../ty/generics_paramspec_variance.toml | 28 +++++++++++
.../zuban/generics_paramspec_variance.toml | 20 ++++++++
.../tests/generics_paramspec_variance.py | 50 +++++++++++++++++++
docs/spec/generics.rst | 24 +++++----
8 files changed, 203 insertions(+), 10 deletions(-)
create mode 100644 conformance/results/mypy/generics_paramspec_variance.toml
create mode 100644 conformance/results/pyrefly/generics_paramspec_variance.toml
create mode 100644 conformance/results/pyright/generics_paramspec_variance.toml
create mode 100644 conformance/results/ty/generics_paramspec_variance.toml
create mode 100644 conformance/results/zuban/generics_paramspec_variance.toml
create mode 100644 conformance/tests/generics_paramspec_variance.py
diff --git a/conformance/results/mypy/generics_paramspec_variance.toml b/conformance/results/mypy/generics_paramspec_variance.toml
new file mode 100644
index 000000000..43ad6b023
--- /dev/null
+++ b/conformance/results/mypy/generics_paramspec_variance.toml
@@ -0,0 +1,20 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 22: Expected 1 errors
+Line 32: Expected 1 errors
+Line 43: Expected 1 errors
+Line 49: Expected 1 errors
+Line 23: Unexpected errors ['generics_paramspec_variance.py:23: error: Incompatible types in assignment (expression has type "CovariantParamSpec[[int]]", variable has type "CovariantParamSpec[[object]]") [assignment]']
+Line 25: Unexpected errors ['generics_paramspec_variance.py:25: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]']
+Line 39: Unexpected errors ['generics_paramspec_variance.py:39: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]']
+Line 50: Unexpected errors ['generics_paramspec_variance.py:50: error: Incompatible types in assignment (expression has type "CovariantParamSpecOld[[int]]", variable has type "CovariantParamSpecOld[[object]]") [assignment]']
+"""
+output = """
+generics_paramspec_variance.py:13: error: Incompatible types in assignment (expression has type "ContravariantParamSpec[[int]]", variable has type "ContravariantParamSpec[[object]]") [assignment]
+generics_paramspec_variance.py:23: error: Incompatible types in assignment (expression has type "CovariantParamSpec[[int]]", variable has type "CovariantParamSpec[[object]]") [assignment]
+generics_paramspec_variance.py:25: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]
+generics_paramspec_variance.py:36: error: Incompatible types in assignment (expression has type "ContravariantParamSpecOld[[int]]", variable has type "ContravariantParamSpecOld[[object]]") [assignment]
+generics_paramspec_variance.py:39: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]
+generics_paramspec_variance.py:50: error: Incompatible types in assignment (expression has type "CovariantParamSpecOld[[int]]", variable has type "CovariantParamSpecOld[[object]]") [assignment]
+"""
diff --git a/conformance/results/pyrefly/generics_paramspec_variance.toml b/conformance/results/pyrefly/generics_paramspec_variance.toml
new file mode 100644
index 000000000..34c61f85a
--- /dev/null
+++ b/conformance/results/pyrefly/generics_paramspec_variance.toml
@@ -0,0 +1,24 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 13: Expected 1 errors
+Line 22: Expected 1 errors
+Line 32: Expected 1 errors
+Line 43: Expected 1 errors
+Line 14: Unexpected errors ['`ContravariantParamSpec[[object]]` is not assignable to `ContravariantParamSpec[[int]]` [bad-assignment]']
+Line 23: Unexpected errors ['`CovariantParamSpec[[int]]` is not assignable to `CovariantParamSpec[[object]]` [bad-assignment]']
+Line 25: Unexpected errors ['Unexpected keyword argument `contravariant` to ParamSpec [invalid-param-spec]']
+Line 37: Unexpected errors ['`ContravariantParamSpecOld[[object]]` is not assignable to `ContravariantParamSpecOld[[int]]` [bad-assignment]']
+Line 39: Unexpected errors ['Unexpected keyword argument `covariant` to ParamSpec [invalid-param-spec]']
+Line 50: Unexpected errors ['`CovariantParamSpecOld[[int]]` is not assignable to `CovariantParamSpecOld[[object]]` [bad-assignment]']
+"""
+output = """
+ERROR generics_paramspec_variance.py:14:39-71: `ContravariantParamSpec[[object]]` is not assignable to `ContravariantParamSpec[[int]]` [bad-assignment]
+ERROR generics_paramspec_variance.py:23:39-64: `CovariantParamSpec[[int]]` is not assignable to `CovariantParamSpec[[object]]` [bad-assignment]
+ERROR generics_paramspec_variance.py:25:24-42: Unexpected keyword argument `contravariant` to ParamSpec [invalid-param-spec]
+ERROR generics_paramspec_variance.py:36:49-81: `ContravariantParamSpecOld[[int]]` is not assignable to `ContravariantParamSpecOld[[object]]` [bad-assignment]
+ERROR generics_paramspec_variance.py:37:46-81: `ContravariantParamSpecOld[[object]]` is not assignable to `ContravariantParamSpecOld[[int]]` [bad-assignment]
+ERROR generics_paramspec_variance.py:39:26-40: Unexpected keyword argument `covariant` to ParamSpec [invalid-param-spec]
+ERROR generics_paramspec_variance.py:49:43-74: `CovariantParamSpecOld[[object]]` is not assignable to `CovariantParamSpecOld[[int]]` [bad-assignment]
+ERROR generics_paramspec_variance.py:50:46-74: `CovariantParamSpecOld[[int]]` is not assignable to `CovariantParamSpecOld[[object]]` [bad-assignment]
+"""
diff --git a/conformance/results/pyright/generics_paramspec_variance.toml b/conformance/results/pyright/generics_paramspec_variance.toml
new file mode 100644
index 000000000..cb1cdb97d
--- /dev/null
+++ b/conformance/results/pyright/generics_paramspec_variance.toml
@@ -0,0 +1,40 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 32: Expected 1 errors
+Line 43: Expected 1 errors
+Line 14: Unexpected errors ['generics_paramspec_variance.py:14:39 - error: Type "ContravariantParamSpec[(object)]" is not assignable to declared type "ContravariantParamSpec[(int)]"']
+Line 23: Unexpected errors ['generics_paramspec_variance.py:23:39 - error: Type "CovariantParamSpec[(int)]" is not assignable to declared type "CovariantParamSpec[(object)]"']
+Line 25: Unexpected errors ['generics_paramspec_variance.py:25:24 - error: "contravariant" is unknown parameter to ParamSpec (reportGeneralTypeIssues)']
+Line 37: Unexpected errors ['generics_paramspec_variance.py:37:46 - error: Type "ContravariantParamSpecOld[(object)]" is not assignable to declared type "ContravariantParamSpecOld[(int)]"']
+Line 39: Unexpected errors ['generics_paramspec_variance.py:39:26 - error: "covariant" is unknown parameter to ParamSpec (reportGeneralTypeIssues)']
+Line 50: Unexpected errors ['generics_paramspec_variance.py:50:46 - error: Type "CovariantParamSpecOld[(int)]" is not assignable to declared type "CovariantParamSpecOld[(object)]"']
+"""
+output = """
+generics_paramspec_variance.py:13:42 - error: Type "ContravariantParamSpec[(int)]" is not assignable to declared type "ContravariantParamSpec[(object)]"
+ "ContravariantParamSpec[(int)]" is not assignable to "ContravariantParamSpec[(object)]"
+ Type parameter "InP@ContravariantParamSpec" is invariant, but "(int)" is not the same as "(object)" (reportAssignmentType)
+generics_paramspec_variance.py:14:39 - error: Type "ContravariantParamSpec[(object)]" is not assignable to declared type "ContravariantParamSpec[(int)]"
+ "ContravariantParamSpec[(object)]" is not assignable to "ContravariantParamSpec[(int)]"
+ Type parameter "InP@ContravariantParamSpec" is invariant, but "(object)" is not the same as "(int)" (reportAssignmentType)
+generics_paramspec_variance.py:22:36 - error: Type "CovariantParamSpec[(object)]" is not assignable to declared type "CovariantParamSpec[(int)]"
+ "CovariantParamSpec[(object)]" is not assignable to "CovariantParamSpec[(int)]"
+ Type parameter "OutP@CovariantParamSpec" is invariant, but "(object)" is not the same as "(int)" (reportAssignmentType)
+generics_paramspec_variance.py:23:39 - error: Type "CovariantParamSpec[(int)]" is not assignable to declared type "CovariantParamSpec[(object)]"
+ "CovariantParamSpec[(int)]" is not assignable to "CovariantParamSpec[(object)]"
+ Type parameter "OutP@CovariantParamSpec" is invariant, but "(int)" is not the same as "(object)" (reportAssignmentType)
+generics_paramspec_variance.py:25:24 - error: "contravariant" is unknown parameter to ParamSpec (reportGeneralTypeIssues)
+generics_paramspec_variance.py:36:49 - error: Type "ContravariantParamSpecOld[(int)]" is not assignable to declared type "ContravariantParamSpecOld[(object)]"
+ "ContravariantParamSpecOld[(int)]" is not assignable to "ContravariantParamSpecOld[(object)]"
+ Type parameter "InP@ContravariantParamSpecOld" is invariant, but "(int)" is not the same as "(object)" (reportAssignmentType)
+generics_paramspec_variance.py:37:46 - error: Type "ContravariantParamSpecOld[(object)]" is not assignable to declared type "ContravariantParamSpecOld[(int)]"
+ "ContravariantParamSpecOld[(object)]" is not assignable to "ContravariantParamSpecOld[(int)]"
+ Type parameter "InP@ContravariantParamSpecOld" is invariant, but "(object)" is not the same as "(int)" (reportAssignmentType)
+generics_paramspec_variance.py:39:26 - error: "covariant" is unknown parameter to ParamSpec (reportGeneralTypeIssues)
+generics_paramspec_variance.py:49:43 - error: Type "CovariantParamSpecOld[(object)]" is not assignable to declared type "CovariantParamSpecOld[(int)]"
+ "CovariantParamSpecOld[(object)]" is not assignable to "CovariantParamSpecOld[(int)]"
+ Type parameter "OutP@CovariantParamSpecOld" is invariant, but "(object)" is not the same as "(int)" (reportAssignmentType)
+generics_paramspec_variance.py:50:46 - error: Type "CovariantParamSpecOld[(int)]" is not assignable to declared type "CovariantParamSpecOld[(object)]"
+ "CovariantParamSpecOld[(int)]" is not assignable to "CovariantParamSpecOld[(object)]"
+ Type parameter "OutP@CovariantParamSpecOld" is invariant, but "(int)" is not the same as "(object)" (reportAssignmentType)
+"""
diff --git a/conformance/results/results.html b/conformance/results/results.html
index e3c56435d..046ca1357 100644
--- a/conformance/results/results.html
+++ b/conformance/results/results.html
@@ -335,6 +335,13 @@
Python Type System Conformance Test Results
Pass |
Pass |
+| generics_paramspec_variance |
+Unsupported |
+Unsupported |
+Unsupported |
+Unsupported |
+Unsupported |
+
| generics_scoping |
Pass |
Pass |
diff --git a/conformance/results/ty/generics_paramspec_variance.toml b/conformance/results/ty/generics_paramspec_variance.toml
new file mode 100644
index 000000000..2eaefab78
--- /dev/null
+++ b/conformance/results/ty/generics_paramspec_variance.toml
@@ -0,0 +1,28 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 13: Expected 1 errors
+Line 22: Expected 1 errors
+Line 36: Expected 1 errors
+Line 49: Expected 1 errors
+Line 25: Unexpected errors ['generics_paramspec_variance.py:25:7: error[invalid-paramspec] The variance and bound arguments for `ParamSpec` do not have defined semantics yet']
+Line 28: Unexpected errors ['generics_paramspec_variance.py:28:33: error[invalid-argument-type] `ParamSpec` is not a valid argument to `Generic`']
+Line 29: Unexpected errors ['generics_paramspec_variance.py:29:32: error[invalid-type-form] Variable of type `ParamSpec` is not allowed in a return type annotation', 'generics_paramspec_variance.py:29:32: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`']
+Line 39: Unexpected errors ['generics_paramspec_variance.py:39:8: error[invalid-paramspec] The variance and bound arguments for `ParamSpec` do not have defined semantics yet']
+Line 42: Unexpected errors ['generics_paramspec_variance.py:42:29: error[invalid-argument-type] `ParamSpec` is not a valid argument to `Generic`']
+Line 45: Unexpected errors ['generics_paramspec_variance.py:45:34: error[invalid-type-form] Variable of type `ParamSpec` is not allowed in a parameter annotation', 'generics_paramspec_variance.py:45:34: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`']
+"""
+output = """
+generics_paramspec_variance.py:25:7: error[invalid-paramspec] The variance and bound arguments for `ParamSpec` do not have defined semantics yet
+generics_paramspec_variance.py:28:33: error[invalid-argument-type] `ParamSpec` is not a valid argument to `Generic`
+generics_paramspec_variance.py:29:32: error[invalid-type-form] Variable of type `ParamSpec` is not allowed in a return type annotation
+generics_paramspec_variance.py:29:32: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
+generics_paramspec_variance.py:32:34: error[invalid-type-form] Variable of type `ParamSpec` is not allowed in a parameter annotation
+generics_paramspec_variance.py:32:34: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
+generics_paramspec_variance.py:39:8: error[invalid-paramspec] The variance and bound arguments for `ParamSpec` do not have defined semantics yet
+generics_paramspec_variance.py:42:29: error[invalid-argument-type] `ParamSpec` is not a valid argument to `Generic`
+generics_paramspec_variance.py:43:32: error[invalid-type-form] Variable of type `ParamSpec` is not allowed in a return type annotation
+generics_paramspec_variance.py:43:32: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
+generics_paramspec_variance.py:45:34: error[invalid-type-form] Variable of type `ParamSpec` is not allowed in a parameter annotation
+generics_paramspec_variance.py:45:34: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
+"""
diff --git a/conformance/results/zuban/generics_paramspec_variance.toml b/conformance/results/zuban/generics_paramspec_variance.toml
new file mode 100644
index 000000000..43ad6b023
--- /dev/null
+++ b/conformance/results/zuban/generics_paramspec_variance.toml
@@ -0,0 +1,20 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 22: Expected 1 errors
+Line 32: Expected 1 errors
+Line 43: Expected 1 errors
+Line 49: Expected 1 errors
+Line 23: Unexpected errors ['generics_paramspec_variance.py:23: error: Incompatible types in assignment (expression has type "CovariantParamSpec[[int]]", variable has type "CovariantParamSpec[[object]]") [assignment]']
+Line 25: Unexpected errors ['generics_paramspec_variance.py:25: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]']
+Line 39: Unexpected errors ['generics_paramspec_variance.py:39: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]']
+Line 50: Unexpected errors ['generics_paramspec_variance.py:50: error: Incompatible types in assignment (expression has type "CovariantParamSpecOld[[int]]", variable has type "CovariantParamSpecOld[[object]]") [assignment]']
+"""
+output = """
+generics_paramspec_variance.py:13: error: Incompatible types in assignment (expression has type "ContravariantParamSpec[[int]]", variable has type "ContravariantParamSpec[[object]]") [assignment]
+generics_paramspec_variance.py:23: error: Incompatible types in assignment (expression has type "CovariantParamSpec[[int]]", variable has type "CovariantParamSpec[[object]]") [assignment]
+generics_paramspec_variance.py:25: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]
+generics_paramspec_variance.py:36: error: Incompatible types in assignment (expression has type "ContravariantParamSpecOld[[int]]", variable has type "ContravariantParamSpecOld[[object]]") [assignment]
+generics_paramspec_variance.py:39: error: The variance and bound arguments to ParamSpec do not have defined semantics yet [misc]
+generics_paramspec_variance.py:50: error: Incompatible types in assignment (expression has type "CovariantParamSpecOld[[int]]", variable has type "CovariantParamSpecOld[[object]]") [assignment]
+"""
diff --git a/conformance/tests/generics_paramspec_variance.py b/conformance/tests/generics_paramspec_variance.py
new file mode 100644
index 000000000..713833d33
--- /dev/null
+++ b/conformance/tests/generics_paramspec_variance.py
@@ -0,0 +1,50 @@
+"""
+Tests variance of ParamSpec.
+"""
+
+# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#semantics
+
+
+from typing import Callable, Generic, ParamSpec
+
+class ContravariantParamSpec[**InP]:
+ def f(self, *args: InP.args, **kwargs: InP.kwargs): ...
+
+in_obj: ContravariantParamSpec[object] = ContravariantParamSpec[int]() # E
+in_int: ContravariantParamSpec[int] = ContravariantParamSpec[object]() # OK
+
+
+class CovariantParamSpec[**OutP]:
+ def f(self, fn: Callable[OutP, None]) -> None:
+ raise NotImplementedError
+
+
+out_int: CovariantParamSpec[int] = CovariantParamSpec[object]() # E
+out_obj: CovariantParamSpec[object] = CovariantParamSpec[int]() # OK
+
+InP = ParamSpec("InP", contravariant=True)
+
+
+class ContravariantParamSpecOld(Generic[InP]):
+ def in_f(self) -> Callable[InP, None]: # OK
+ raise NotImplementedError
+
+ def out_f(self, fn: Callable[InP, None]) -> None: # E
+ raise NotImplementedError
+
+
+in_obj_old: ContravariantParamSpecOld[object] = ContravariantParamSpecOld[int]() # E
+in_int_old: ContravariantParamSpecOld[int] = ContravariantParamSpecOld[object]() # OK
+
+OutP = ParamSpec("OutP", covariant=True)
+
+
+class CovariantParamSpecOld(Generic[OutP]):
+ def in_f(self) -> Callable[OutP, None]: # E
+ raise NotImplementedError
+ def out_f(self, fn: Callable[OutP, None]) -> None: # OK
+ raise NotImplementedError
+
+
+out_int_old: CovariantParamSpecOld[int] = CovariantParamSpecOld[object]() # E
+out_obj_old: CovariantParamSpecOld[object] = CovariantParamSpecOld[int]() # OK
diff --git a/docs/spec/generics.rst b/docs/spec/generics.rst
index c1fa05325..0bd2ad5c1 100644
--- a/docs/spec/generics.rst
+++ b/docs/spec/generics.rst
@@ -2712,23 +2712,27 @@ The algorithm for computing the variance of a type parameter is as follows.
For each type parameter in a generic class:
-1. If the type parameter is variadic (``TypeVarTuple``) or a parameter
-specification (``ParamSpec``), it is always considered invariant. No further
-inference is needed.
+1. If the type parameter is variadic (``TypeVarTuple``) it is always
+considered invariant. No further inference is needed.
-2. If the type parameter comes from a traditional ``TypeVar`` declaration and
-is not specified as ``infer_variance`` (see below), its variance is specified
-by the ``TypeVar`` constructor call. No further inference is needed.
+2. If the type parameter comes from a traditional ``TypeVar``/``ParamSpec``
+declaration and is not specified as ``infer_variance`` (see below), its
+variance is specified by the constructor call. No further inference is needed.
3. Create two specialized versions of the class. We'll refer to these as
``upper`` and ``lower`` specializations. In both of these specializations,
replace all type parameters other than the one being inferred by a dummy type
instance (a concrete anonymous class that is assumed to meet the bounds or
constraints of the type parameter). In the ``upper`` specialized class,
-specialize the target type parameter with an ``object`` instance. This
-specialization ignores the type parameter's upper bound or constraints. In the
-``lower`` specialized class, specialize the target type parameter with itself
-(i.e. the corresponding type argument is the type parameter itself).
+specialize the target type parameter with:
+
+ an ``object`` instance for a type variable.
+ a ``*tuple[object, ...]`` value for a type variable tuple.
+ a ``(*object, **object)`` value for a parameter specification.
+
+This specialization ignores the type parameter's upper bound or constraints.
+In the ``lower`` specialized class, specialize the target type parameter with
+itself (i.e. the corresponding type argument is the type parameter itself).
4. Determine whether ``lower`` can be assigned to ``upper`` using normal
assignability rules. If so, the target type parameter is covariant. If not,
From 02c4628e11d0d3ad379ec803efdf62601280c140 Mon Sep 17 00:00:00 2001
From: kotlinisland <65446343+kotlinisland@users.noreply.github.com>
Date: Tue, 7 Apr 2026 14:58:52 +1000
Subject: [PATCH 2/3] specify that type variable tuple should have variance
---
.../mypy/generics_typevartuple_basic.toml | 12 ++---
.../mypy/generics_typevartuple_variance.toml | 20 +++++++
.../pyrefly/generics_typevartuple_basic.toml | 14 ++---
.../generics_typevartuple_variance.toml | 24 +++++++++
.../pyright/generics_typevartuple_basic.toml | 21 ++++----
.../generics_typevartuple_variance.toml | 40 ++++++++++++++
conformance/results/results.html | 7 +++
.../ty/generics_typevartuple_basic.toml | 15 +++---
.../ty/generics_typevartuple_variance.toml | 24 +++++++++
.../zuban/generics_typevartuple_basic.toml | 15 +++---
.../zuban/generics_typevartuple_variance.toml | 24 +++++++++
.../tests/generics_typevartuple_basic.py | 3 +-
.../tests/generics_typevartuple_variance.py | 53 +++++++++++++++++++
docs/spec/generics.rst | 21 ++++----
14 files changed, 240 insertions(+), 53 deletions(-)
create mode 100644 conformance/results/mypy/generics_typevartuple_variance.toml
create mode 100644 conformance/results/pyrefly/generics_typevartuple_variance.toml
create mode 100644 conformance/results/pyright/generics_typevartuple_variance.toml
create mode 100644 conformance/results/ty/generics_typevartuple_variance.toml
create mode 100644 conformance/results/zuban/generics_typevartuple_variance.toml
create mode 100644 conformance/tests/generics_typevartuple_variance.py
diff --git a/conformance/results/mypy/generics_typevartuple_basic.toml b/conformance/results/mypy/generics_typevartuple_basic.toml
index 37140c379..bb70bf111 100644
--- a/conformance/results/mypy/generics_typevartuple_basic.toml
+++ b/conformance/results/mypy/generics_typevartuple_basic.toml
@@ -10,14 +10,14 @@ generics_typevartuple_basic.py:52: error: Free type variable expected in Generic
generics_typevartuple_basic.py:53: error: TypeVarTuple "Shape" is only valid with an unpack [valid-type]
generics_typevartuple_basic.py:56: error: TypeVarTuple "Shape" is only valid with an unpack [valid-type]
generics_typevartuple_basic.py:59: error: TypeVarTuple "Shape" is only valid with an unpack [valid-type]
-generics_typevartuple_basic.py:65: error: Unexpected keyword argument "covariant" for "TypeVarTuple" [misc]
-generics_typevartuple_basic.py:66: error: Too many positional arguments for "TypeVarTuple" [misc]
-generics_typevartuple_basic.py:67: error: Unexpected keyword argument "bound" for "TypeVarTuple" [misc]
+generics_typevartuple_basic.py:65: error: Too many positional arguments for "TypeVarTuple" [misc]
+generics_typevartuple_basic.py:66: error: Unexpected keyword argument "bound" for "TypeVarTuple" [misc]
+generics_typevartuple_basic.py:99: error: Cannot infer value of type parameter "Shape" of "multiply" [misc]
generics_typevartuple_basic.py:100: error: Cannot infer value of type parameter "Shape" of "multiply" [misc]
-generics_typevartuple_basic.py:101: error: Cannot infer value of type parameter "Shape" of "multiply" [misc]
-generics_typevartuple_basic.py:107: error: Can only use one type var tuple in a class def [misc]
+generics_typevartuple_basic.py:106: error: Free type variable expected in Generic[...] [misc]
+generics_typevartuple_basic.py:106: error: Name "Ts1" is not defined [name-defined]
"""
conformance_automated = "Fail"
errors_diff = """
-Line 91: Expected 1 errors
+Line 90: Expected 1 errors
"""
diff --git a/conformance/results/mypy/generics_typevartuple_variance.toml b/conformance/results/mypy/generics_typevartuple_variance.toml
new file mode 100644
index 000000000..8eb82f677
--- /dev/null
+++ b/conformance/results/mypy/generics_typevartuple_variance.toml
@@ -0,0 +1,20 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 14: Expected 1 errors
+Line 34: Expected 1 errors
+Line 38: Expected 1 errors
+Line 45: Expected 1 errors
+Line 15: Unexpected errors ['generics_typevartuple_variance.py:15: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTuple[object]", variable has type "ContravariantTypeVarTuple[int]") [assignment]']
+Line 27: Unexpected errors ['generics_typevartuple_variance.py:27: error: Unexpected keyword argument "contravariant" for "TypeVarTuple" [misc]']
+Line 39: Unexpected errors ['generics_typevartuple_variance.py:39: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTupleOld[object]", variable has type "ContravariantTypeVarTupleOld[int]") [assignment]']
+Line 41: Unexpected errors ['generics_typevartuple_variance.py:41: error: Unexpected keyword argument "covariant" for "TypeVarTuple" [misc]']
+"""
+output = """
+generics_typevartuple_variance.py:15: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTuple[object]", variable has type "ContravariantTypeVarTuple[int]") [assignment]
+generics_typevartuple_variance.py:23: error: Incompatible types in assignment (expression has type "CovariantTypeVarTuple[object]", variable has type "CovariantTypeVarTuple[int]") [assignment]
+generics_typevartuple_variance.py:27: error: Unexpected keyword argument "contravariant" for "TypeVarTuple" [misc]
+generics_typevartuple_variance.py:39: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTupleOld[object]", variable has type "ContravariantTypeVarTupleOld[int]") [assignment]
+generics_typevartuple_variance.py:41: error: Unexpected keyword argument "covariant" for "TypeVarTuple" [misc]
+generics_typevartuple_variance.py:52: error: Incompatible types in assignment (expression has type "CovariantTypeVarTupleOld[object]", variable has type "CovariantTypeVarTupleOld[int]") [assignment]
+"""
diff --git a/conformance/results/pyrefly/generics_typevartuple_basic.toml b/conformance/results/pyrefly/generics_typevartuple_basic.toml
index 8ceb260fd..c94ea3e23 100644
--- a/conformance/results/pyrefly/generics_typevartuple_basic.toml
+++ b/conformance/results/pyrefly/generics_typevartuple_basic.toml
@@ -10,11 +10,11 @@ ERROR generics_typevartuple_basic.py:52:22-27: `TypeVarTuple` must be unpacked [
ERROR generics_typevartuple_basic.py:53:37-42: `TypeVarTuple` must be unpacked [invalid-type-var-tuple]
ERROR generics_typevartuple_basic.py:56:34-39: `TypeVarTuple` must be unpacked [invalid-type-var-tuple]
ERROR generics_typevartuple_basic.py:59:24-29: `TypeVarTuple` must be unpacked [invalid-annotation]
-ERROR generics_typevartuple_basic.py:65:27-41: Unexpected keyword argument `covariant` to TypeVarTuple [invalid-type-var-tuple]
-ERROR generics_typevartuple_basic.py:66:27-30: Unexpected positional argument to TypeVarTuple [invalid-type-var-tuple]
-ERROR generics_typevartuple_basic.py:67:27-36: Unexpected keyword argument `bound` to TypeVarTuple [invalid-type-var-tuple]
-ERROR generics_typevartuple_basic.py:91:15-19: Argument `tuple[Literal[0]]` is not assignable to parameter `arg2` with type `tuple[int, int]` in function `func2` [bad-argument-type]
-ERROR generics_typevartuple_basic.py:100:17-18: Argument `Array[Width]` is not assignable to parameter `y` with type `Array[Height]` in function `multiply` [bad-argument-type]
-ERROR generics_typevartuple_basic.py:101:17-18: Argument `Array[Height, Width]` is not assignable to parameter `y` with type `Array[Height]` in function `multiply` [bad-argument-type]
-ERROR generics_typevartuple_basic.py:107:7-13: Type parameters for class may not have more than one TypeVarTuple [invalid-type-var-tuple]
+ERROR generics_typevartuple_basic.py:65:27-30: Unexpected positional argument to TypeVarTuple [invalid-type-var-tuple]
+ERROR generics_typevartuple_basic.py:66:27-36: Unexpected keyword argument `bound` to TypeVarTuple [invalid-type-var-tuple]
+ERROR generics_typevartuple_basic.py:90:15-19: Argument `tuple[Literal[0]]` is not assignable to parameter `arg2` with type `tuple[int, int]` in function `func2` [bad-argument-type]
+ERROR generics_typevartuple_basic.py:99:17-18: Argument `Array[Width]` is not assignable to parameter `y` with type `Array[Height]` in function `multiply` [bad-argument-type]
+ERROR generics_typevartuple_basic.py:100:17-18: Argument `Array[Height, Width]` is not assignable to parameter `y` with type `Array[Height]` in function `multiply` [bad-argument-type]
+ERROR generics_typevartuple_basic.py:106:22-26: Expected a type form, got instance of `*Unknown` [not-a-type]
+ERROR generics_typevartuple_basic.py:106:23-26: Could not find name `Ts1` [unknown-name]
"""
diff --git a/conformance/results/pyrefly/generics_typevartuple_variance.toml b/conformance/results/pyrefly/generics_typevartuple_variance.toml
new file mode 100644
index 000000000..4811a85f3
--- /dev/null
+++ b/conformance/results/pyrefly/generics_typevartuple_variance.toml
@@ -0,0 +1,24 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 34: Expected 1 errors
+Line 45: Expected 1 errors
+Line 15: Unexpected errors ['`ContravariantTypeVarTuple[object]` is not assignable to `ContravariantTypeVarTuple[int]` [bad-assignment]']
+Line 24: Unexpected errors ['`CovariantTypeVarTuple[int]` is not assignable to `CovariantTypeVarTuple[object]` [bad-assignment]']
+Line 27: Unexpected errors ['Unexpected keyword argument `contravariant` to TypeVarTuple [invalid-type-var-tuple]']
+Line 39: Unexpected errors ['`ContravariantTypeVarTupleOld[object]` is not assignable to `ContravariantTypeVarTupleOld[int]` [bad-assignment]']
+Line 41: Unexpected errors ['Unexpected keyword argument `covariant` to TypeVarTuple [invalid-type-var-tuple]']
+Line 53: Unexpected errors ['`CovariantTypeVarTupleOld[int]` is not assignable to `CovariantTypeVarTupleOld[object]` [bad-assignment]']
+"""
+output = """
+ERROR generics_typevartuple_variance.py:14:45-77: `ContravariantTypeVarTuple[int]` is not assignable to `ContravariantTypeVarTuple[object]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:15:42-77: `ContravariantTypeVarTuple[object]` is not assignable to `ContravariantTypeVarTuple[int]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:23:39-70: `CovariantTypeVarTuple[object]` is not assignable to `CovariantTypeVarTuple[int]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:24:42-70: `CovariantTypeVarTuple[int]` is not assignable to `CovariantTypeVarTuple[object]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:27:29-47: Unexpected keyword argument `contravariant` to TypeVarTuple [invalid-type-var-tuple]
+ERROR generics_typevartuple_variance.py:38:52-87: `ContravariantTypeVarTupleOld[int]` is not assignable to `ContravariantTypeVarTupleOld[object]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:39:49-87: `ContravariantTypeVarTupleOld[object]` is not assignable to `ContravariantTypeVarTupleOld[int]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:41:31-45: Unexpected keyword argument `covariant` to TypeVarTuple [invalid-type-var-tuple]
+ERROR generics_typevartuple_variance.py:52:46-80: `CovariantTypeVarTupleOld[object]` is not assignable to `CovariantTypeVarTupleOld[int]` [bad-assignment]
+ERROR generics_typevartuple_variance.py:53:49-80: `CovariantTypeVarTupleOld[int]` is not assignable to `CovariantTypeVarTupleOld[object]` [bad-assignment]
+"""
diff --git a/conformance/results/pyright/generics_typevartuple_basic.toml b/conformance/results/pyright/generics_typevartuple_basic.toml
index 7e5cfa403..04c843367 100644
--- a/conformance/results/pyright/generics_typevartuple_basic.toml
+++ b/conformance/results/pyright/generics_typevartuple_basic.toml
@@ -4,7 +4,7 @@ Does not correctly solve TypeVarTuple with heterogeneous bounds.
"""
conformance_automated = "Fail"
errors_diff = """
-Line 90: Unexpected errors ['generics_typevartuple_basic.py:90:14 - error: Argument of type "tuple[Literal[\\'0\\']]" cannot be assigned to parameter "arg2" of type "tuple[*Ts@func2]" in function "func2"']
+Line 89: Unexpected errors ['generics_typevartuple_basic.py:89:14 - error: Argument of type "tuple[Literal[\\'0\\']]" cannot be assigned to parameter "arg2" of type "tuple[*Ts@func2]" in function "func2"']
"""
output = """
generics_typevartuple_basic.py:42:34 - error: Argument of type "Height" cannot be assigned to parameter "shape" of type "tuple[*Shape@Array]" in function "__init__"
@@ -19,21 +19,20 @@ generics_typevartuple_basic.py:52:22 - error: Expected unpacked TypeVarTuple; us
generics_typevartuple_basic.py:53:37 - error: Expected unpacked TypeVarTuple; use Unpack[Shape] or *Shape (reportInvalidTypeForm)
generics_typevartuple_basic.py:56:34 - error: Expected unpacked TypeVarTuple; use Unpack[Shape] or *Shape (reportInvalidTypeForm)
generics_typevartuple_basic.py:59:24 - error: Expected unpacked TypeVarTuple; use Unpack[Shape] or *Shape (reportInvalidTypeForm)
-generics_typevartuple_basic.py:65:27 - error: "covariant" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)
-generics_typevartuple_basic.py:66:27 - error: TypeVarTuple cannot have value constraints (reportGeneralTypeIssues)
-generics_typevartuple_basic.py:66:32 - error: TypeVarTuple cannot have value constraints (reportGeneralTypeIssues)
-generics_typevartuple_basic.py:67:27 - error: "bound" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)
-generics_typevartuple_basic.py:90:14 - error: Argument of type "tuple[Literal['0']]" cannot be assigned to parameter "arg2" of type "tuple[*Ts@func2]" in function "func2"
+generics_typevartuple_basic.py:65:27 - error: TypeVarTuple cannot have value constraints (reportGeneralTypeIssues)
+generics_typevartuple_basic.py:65:32 - error: TypeVarTuple cannot have value constraints (reportGeneralTypeIssues)
+generics_typevartuple_basic.py:66:27 - error: "bound" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)
+generics_typevartuple_basic.py:89:14 - error: Argument of type "tuple[Literal['0']]" cannot be assigned to parameter "arg2" of type "tuple[*Ts@func2]" in function "func2"
"Literal['0']" is not assignable to "int" (reportArgumentType)
-generics_typevartuple_basic.py:91:15 - error: Argument of type "tuple[Literal[0]]" cannot be assigned to parameter "arg2" of type "tuple[*Ts@func2]" in function "func2"
+generics_typevartuple_basic.py:90:15 - error: Argument of type "tuple[Literal[0]]" cannot be assigned to parameter "arg2" of type "tuple[*Ts@func2]" in function "func2"
"tuple[Literal[0]]" is not assignable to "tuple[int, int]"
Tuple size mismatch; expected 2 but received 1 (reportArgumentType)
-generics_typevartuple_basic.py:100:17 - error: Argument of type "Array[Width]" cannot be assigned to parameter "y" of type "Array[*Shape@multiply]" in function "multiply"
+generics_typevartuple_basic.py:99:17 - error: Argument of type "Array[Width]" cannot be assigned to parameter "y" of type "Array[*Shape@multiply]" in function "multiply"
"Array[Width]" is not assignable to "Array[Height]"
Type parameter "Shape@Array" is invariant, but "*tuple[Width]" is not the same as "*tuple[Height]" (reportArgumentType)
-generics_typevartuple_basic.py:101:17 - error: Argument of type "Array[Height, Width]" cannot be assigned to parameter "y" of type "Array[*Shape@multiply]" in function "multiply"
+generics_typevartuple_basic.py:100:17 - error: Argument of type "Array[Height, Width]" cannot be assigned to parameter "y" of type "Array[*Shape@multiply]" in function "multiply"
"Array[Height, Width]" is not assignable to "Array[Height]"
Type parameter "Shape@Array" is invariant, but "*tuple[Height, Width]" is not the same as "*tuple[Height]" (reportArgumentType)
-generics_typevartuple_basic.py:107:14 - error: Generic class can have at most one TypeVarTuple type parameter but received multiple ("Ts1", "Ts2") (reportGeneralTypeIssues)
-generics_typevartuple_basic.py:107:29 - error: Type argument list can have at most one unpacked TypeVarTuple or tuple (reportInvalidTypeForm)
+generics_typevartuple_basic.py:106:23 - error: "Ts1" is not defined (reportUndefinedVariable)
+generics_typevartuple_basic.py:106:23 - error: Type argument for "Generic" must be a type variable (reportInvalidTypeForm)
"""
diff --git a/conformance/results/pyright/generics_typevartuple_variance.toml b/conformance/results/pyright/generics_typevartuple_variance.toml
new file mode 100644
index 000000000..5812af36a
--- /dev/null
+++ b/conformance/results/pyright/generics_typevartuple_variance.toml
@@ -0,0 +1,40 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 34: Expected 1 errors
+Line 45: Expected 1 errors
+Line 15: Unexpected errors ['generics_typevartuple_variance.py:15:42 - error: Type "ContravariantTypeVarTuple[object]" is not assignable to declared type "ContravariantTypeVarTuple[int]"']
+Line 24: Unexpected errors ['generics_typevartuple_variance.py:24:42 - error: Type "CovariantTypeVarTuple[int]" is not assignable to declared type "CovariantTypeVarTuple[object]"']
+Line 27: Unexpected errors ['generics_typevartuple_variance.py:27:29 - error: "contravariant" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)']
+Line 39: Unexpected errors ['generics_typevartuple_variance.py:39:49 - error: Type "ContravariantTypeVarTupleOld[object]" is not assignable to declared type "ContravariantTypeVarTupleOld[int]"']
+Line 41: Unexpected errors ['generics_typevartuple_variance.py:41:31 - error: "covariant" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)']
+Line 53: Unexpected errors ['generics_typevartuple_variance.py:53:49 - error: Type "CovariantTypeVarTupleOld[int]" is not assignable to declared type "CovariantTypeVarTupleOld[object]"']
+"""
+output = """
+generics_typevartuple_variance.py:14:45 - error: Type "ContravariantTypeVarTuple[int]" is not assignable to declared type "ContravariantTypeVarTuple[object]"
+ "ContravariantTypeVarTuple[int]" is not assignable to "ContravariantTypeVarTuple[object]"
+ Type parameter "InTs@ContravariantTypeVarTuple" is invariant, but "*tuple[int]" is not the same as "*tuple[object]" (reportAssignmentType)
+generics_typevartuple_variance.py:15:42 - error: Type "ContravariantTypeVarTuple[object]" is not assignable to declared type "ContravariantTypeVarTuple[int]"
+ "ContravariantTypeVarTuple[object]" is not assignable to "ContravariantTypeVarTuple[int]"
+ Type parameter "InTs@ContravariantTypeVarTuple" is invariant, but "*tuple[object]" is not the same as "*tuple[int]" (reportAssignmentType)
+generics_typevartuple_variance.py:23:39 - error: Type "CovariantTypeVarTuple[object]" is not assignable to declared type "CovariantTypeVarTuple[int]"
+ "CovariantTypeVarTuple[object]" is not assignable to "CovariantTypeVarTuple[int]"
+ Type parameter "OutTs@CovariantTypeVarTuple" is invariant, but "*tuple[object]" is not the same as "*tuple[int]" (reportAssignmentType)
+generics_typevartuple_variance.py:24:42 - error: Type "CovariantTypeVarTuple[int]" is not assignable to declared type "CovariantTypeVarTuple[object]"
+ "CovariantTypeVarTuple[int]" is not assignable to "CovariantTypeVarTuple[object]"
+ Type parameter "OutTs@CovariantTypeVarTuple" is invariant, but "*tuple[int]" is not the same as "*tuple[object]" (reportAssignmentType)
+generics_typevartuple_variance.py:27:29 - error: "contravariant" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)
+generics_typevartuple_variance.py:38:52 - error: Type "ContravariantTypeVarTupleOld[int]" is not assignable to declared type "ContravariantTypeVarTupleOld[object]"
+ "ContravariantTypeVarTupleOld[int]" is not assignable to "ContravariantTypeVarTupleOld[object]"
+ Type parameter "InTs@ContravariantTypeVarTupleOld" is invariant, but "*tuple[int]" is not the same as "*tuple[object]" (reportAssignmentType)
+generics_typevartuple_variance.py:39:49 - error: Type "ContravariantTypeVarTupleOld[object]" is not assignable to declared type "ContravariantTypeVarTupleOld[int]"
+ "ContravariantTypeVarTupleOld[object]" is not assignable to "ContravariantTypeVarTupleOld[int]"
+ Type parameter "InTs@ContravariantTypeVarTupleOld" is invariant, but "*tuple[object]" is not the same as "*tuple[int]" (reportAssignmentType)
+generics_typevartuple_variance.py:41:31 - error: "covariant" is unknown parameter to TypeVarTuple (reportGeneralTypeIssues)
+generics_typevartuple_variance.py:52:46 - error: Type "CovariantTypeVarTupleOld[object]" is not assignable to declared type "CovariantTypeVarTupleOld[int]"
+ "CovariantTypeVarTupleOld[object]" is not assignable to "CovariantTypeVarTupleOld[int]"
+ Type parameter "OutTs@CovariantTypeVarTupleOld" is invariant, but "*tuple[object]" is not the same as "*tuple[int]" (reportAssignmentType)
+generics_typevartuple_variance.py:53:49 - error: Type "CovariantTypeVarTupleOld[int]" is not assignable to declared type "CovariantTypeVarTupleOld[object]"
+ "CovariantTypeVarTupleOld[int]" is not assignable to "CovariantTypeVarTupleOld[object]"
+ Type parameter "OutTs@CovariantTypeVarTupleOld" is invariant, but "*tuple[int]" is not the same as "*tuple[object]" (reportAssignmentType)
+"""
diff --git a/conformance/results/results.html b/conformance/results/results.html
index 046ca1357..1a0281ba8 100644
--- a/conformance/results/results.html
+++ b/conformance/results/results.html
@@ -468,6 +468,13 @@ Python Type System Conformance Test Results
Pass |
Unsupported |
+| generics_typevartuple_variance |
+Unsupported |
+Unsupported |
+Unsupported |
+Unsupported |
+Unsupported |
+
| generics_upper_bound |
Partial Does not reject use of type variable within an upper bound. |
Pass |
diff --git a/conformance/results/ty/generics_typevartuple_basic.toml b/conformance/results/ty/generics_typevartuple_basic.toml
index 02dace065..06d3bf889 100644
--- a/conformance/results/ty/generics_typevartuple_basic.toml
+++ b/conformance/results/ty/generics_typevartuple_basic.toml
@@ -5,18 +5,17 @@ Line 43: Expected 1 errors
Line 53: Expected 1 errors
Line 56: Expected 1 errors
Line 59: Expected 1 errors
-Line 91: Expected 1 errors
+Line 90: Expected 1 errors
+Line 99: Expected 1 errors
Line 100: Expected 1 errors
-Line 101: Expected 1 errors
-Line 107: Expected 1 errors
Lines 44, 45: Expected error (tag 'v6')
-Line 85: Unexpected errors ['generics_typevartuple_basic.py:85:5: error[type-assertion-failure] Type `tuple[@Todo(TypeVarTuple), ...]` does not match asserted type `tuple[int]`']
+Line 84: Unexpected errors ['generics_typevartuple_basic.py:84:5: error[type-assertion-failure] Type `tuple[@Todo(TypeVarTuple), ...]` does not match asserted type `tuple[int]`']
"""
output = """
generics_typevartuple_basic.py:42:34: error[invalid-argument-type] Argument to `Array.__init__` is incorrect: Expected `tuple[@Todo(TypeVarTuple), ...]`, found `Height`
generics_typevartuple_basic.py:52:14: error[invalid-generic-class] `TypeVarTuple` must be unpacked with `*` or `Unpack[]` when used as an argument to `Generic`
-generics_typevartuple_basic.py:65:27: error[unknown-argument] Argument `covariant` does not match any known parameter of constructor `TypeVarTuple.__new__`
-generics_typevartuple_basic.py:66:27: error[too-many-positional-arguments] Too many positional arguments to constructor `TypeVarTuple.__new__`: expected 2, got 4
-generics_typevartuple_basic.py:67:27: error[unknown-argument] Argument `bound` does not match any known parameter of constructor `TypeVarTuple.__new__`
-generics_typevartuple_basic.py:85:5: error[type-assertion-failure] Type `tuple[@Todo(TypeVarTuple), ...]` does not match asserted type `tuple[int]`
+generics_typevartuple_basic.py:65:27: error[too-many-positional-arguments] Too many positional arguments to constructor `TypeVarTuple.__new__`: expected 2, got 4
+generics_typevartuple_basic.py:66:27: error[unknown-argument] Argument `bound` does not match any known parameter of constructor `TypeVarTuple.__new__`
+generics_typevartuple_basic.py:84:5: error[type-assertion-failure] Type `tuple[@Todo(TypeVarTuple), ...]` does not match asserted type `tuple[int]`
+generics_typevartuple_basic.py:106:23: error[unresolved-reference] Name `Ts1` used when not defined
"""
diff --git a/conformance/results/ty/generics_typevartuple_variance.toml b/conformance/results/ty/generics_typevartuple_variance.toml
new file mode 100644
index 000000000..c3332636e
--- /dev/null
+++ b/conformance/results/ty/generics_typevartuple_variance.toml
@@ -0,0 +1,24 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 34: Expected 1 errors
+Line 38: Expected 1 errors
+Line 45: Expected 1 errors
+Line 52: Expected 1 errors
+Line 15: Unexpected errors ["generics_typevartuple_variance.py:15:9: error[not-subscriptable] Cannot subscript non-generic type ``", "generics_typevartuple_variance.py:15:42: error[not-subscriptable] Cannot subscript non-generic type ``"]
+Line 24: Unexpected errors ["generics_typevartuple_variance.py:24:10: error[not-subscriptable] Cannot subscript non-generic type ``", "generics_typevartuple_variance.py:24:42: error[not-subscriptable] Cannot subscript non-generic type ``"]
+Line 27: Unexpected errors ['generics_typevartuple_variance.py:27:29: error[unknown-argument] Argument `contravariant` does not match any known parameter of constructor `TypeVarTuple.__new__`']
+Line 41: Unexpected errors ['generics_typevartuple_variance.py:41:31: error[unknown-argument] Argument `covariant` does not match any known parameter of constructor `TypeVarTuple.__new__`']
+"""
+output = """
+generics_typevartuple_variance.py:14:9: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:14:45: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:15:9: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:15:42: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:23:10: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:23:39: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:24:10: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:24:42: error[not-subscriptable] Cannot subscript non-generic type ``
+generics_typevartuple_variance.py:27:29: error[unknown-argument] Argument `contravariant` does not match any known parameter of constructor `TypeVarTuple.__new__`
+generics_typevartuple_variance.py:41:31: error[unknown-argument] Argument `covariant` does not match any known parameter of constructor `TypeVarTuple.__new__`
+"""
diff --git a/conformance/results/zuban/generics_typevartuple_basic.toml b/conformance/results/zuban/generics_typevartuple_basic.toml
index ca0cca722..51c93bdff 100644
--- a/conformance/results/zuban/generics_typevartuple_basic.toml
+++ b/conformance/results/zuban/generics_typevartuple_basic.toml
@@ -9,11 +9,12 @@ generics_typevartuple_basic.py:52: error: Free type variable expected in Generic
generics_typevartuple_basic.py:53: error: TypeVarTuple "Shape" is only valid with an unpack [valid-type]
generics_typevartuple_basic.py:56: error: TypeVarTuple "Shape" is only valid with an unpack [valid-type]
generics_typevartuple_basic.py:59: error: TypeVarTuple "Shape" is only valid with an unpack [valid-type]
-generics_typevartuple_basic.py:65: error: Unexpected keyword argument "covariant" for "TypeVarTuple" [call-arg]
-generics_typevartuple_basic.py:66: error: Too many positional arguments for "TypeVarTuple" [call-arg]
-generics_typevartuple_basic.py:67: error: Unexpected keyword argument "bound" for "TypeVarTuple" [call-arg]
-generics_typevartuple_basic.py:91: error: Argument 2 to "func2" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
-generics_typevartuple_basic.py:100: error: Argument 2 to "multiply" has incompatible type "Array[Width]"; expected "Array[Height]" [arg-type]
-generics_typevartuple_basic.py:101: error: Argument 2 to "multiply" has incompatible type "Array[Height, Width]"; expected "Array[Height]" [arg-type]
-generics_typevartuple_basic.py:107: error: Can only use one type var tuple in a class def [misc]
+generics_typevartuple_basic.py:65: error: Too many positional arguments for "TypeVarTuple" [call-arg]
+generics_typevartuple_basic.py:66: error: Unexpected keyword argument "bound" for "TypeVarTuple" [call-arg]
+generics_typevartuple_basic.py:90: error: Argument 2 to "func2" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
+generics_typevartuple_basic.py:99: error: Argument 2 to "multiply" has incompatible type "Array[Width]"; expected "Array[Height]" [arg-type]
+generics_typevartuple_basic.py:100: error: Argument 2 to "multiply" has incompatible type "Array[Height, Width]"; expected "Array[Height]" [arg-type]
+generics_typevartuple_basic.py:106: error: Free type variable expected in Generic[...] [misc]
+generics_typevartuple_basic.py:106: error: Name "Ts1" is not defined [name-defined]
+generics_typevartuple_basic.py:106: error: Duplicate type variables in Generic[...] or Protocol[...] [misc]
"""
diff --git a/conformance/results/zuban/generics_typevartuple_variance.toml b/conformance/results/zuban/generics_typevartuple_variance.toml
new file mode 100644
index 000000000..e5da7cf10
--- /dev/null
+++ b/conformance/results/zuban/generics_typevartuple_variance.toml
@@ -0,0 +1,24 @@
+conformant = "Unsupported"
+conformance_automated = "Fail"
+errors_diff = """
+Line 34: Expected 1 errors
+Line 45: Expected 1 errors
+Line 15: Unexpected errors ['generics_typevartuple_variance.py:15: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTuple[object]", variable has type "ContravariantTypeVarTuple[int]") [assignment]']
+Line 24: Unexpected errors ['generics_typevartuple_variance.py:24: error: Incompatible types in assignment (expression has type "CovariantTypeVarTuple[int]", variable has type "CovariantTypeVarTuple[object]") [assignment]']
+Line 27: Unexpected errors ['generics_typevartuple_variance.py:27: error: Unexpected keyword argument "contravariant" for "TypeVarTuple" [call-arg]']
+Line 39: Unexpected errors ['generics_typevartuple_variance.py:39: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTupleOld[object]", variable has type "ContravariantTypeVarTupleOld[int]") [assignment]']
+Line 41: Unexpected errors ['generics_typevartuple_variance.py:41: error: Unexpected keyword argument "covariant" for "TypeVarTuple" [call-arg]']
+Line 53: Unexpected errors ['generics_typevartuple_variance.py:53: error: Incompatible types in assignment (expression has type "CovariantTypeVarTupleOld[int]", variable has type "CovariantTypeVarTupleOld[object]") [assignment]']
+"""
+output = """
+generics_typevartuple_variance.py:14: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTuple[int]", variable has type "ContravariantTypeVarTuple[object]") [assignment]
+generics_typevartuple_variance.py:15: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTuple[object]", variable has type "ContravariantTypeVarTuple[int]") [assignment]
+generics_typevartuple_variance.py:23: error: Incompatible types in assignment (expression has type "CovariantTypeVarTuple[object]", variable has type "CovariantTypeVarTuple[int]") [assignment]
+generics_typevartuple_variance.py:24: error: Incompatible types in assignment (expression has type "CovariantTypeVarTuple[int]", variable has type "CovariantTypeVarTuple[object]") [assignment]
+generics_typevartuple_variance.py:27: error: Unexpected keyword argument "contravariant" for "TypeVarTuple" [call-arg]
+generics_typevartuple_variance.py:38: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTupleOld[int]", variable has type "ContravariantTypeVarTupleOld[object]") [assignment]
+generics_typevartuple_variance.py:39: error: Incompatible types in assignment (expression has type "ContravariantTypeVarTupleOld[object]", variable has type "ContravariantTypeVarTupleOld[int]") [assignment]
+generics_typevartuple_variance.py:41: error: Unexpected keyword argument "covariant" for "TypeVarTuple" [call-arg]
+generics_typevartuple_variance.py:52: error: Incompatible types in assignment (expression has type "CovariantTypeVarTupleOld[object]", variable has type "CovariantTypeVarTupleOld[int]") [assignment]
+generics_typevartuple_variance.py:53: error: Incompatible types in assignment (expression has type "CovariantTypeVarTupleOld[int]", variable has type "CovariantTypeVarTupleOld[object]") [assignment]
+"""
diff --git a/conformance/tests/generics_typevartuple_basic.py b/conformance/tests/generics_typevartuple_basic.py
index 47b493ff0..c48556b94 100644
--- a/conformance/tests/generics_typevartuple_basic.py
+++ b/conformance/tests/generics_typevartuple_basic.py
@@ -60,9 +60,8 @@ def method1(*args: Shape) -> None: # E: not unpacked
...
-# > TypeVarTuple does not yet support specification of variance, bounds, constraints.
+# > TypeVarTuple does not yet support specification of bounds, constraints.
-Ts1 = TypeVarTuple("Ts1", covariant=True) # E
Ts2 = TypeVarTuple("Ts2", int, float) # E
Ts3 = TypeVarTuple("Ts3", bound=int) # E
diff --git a/conformance/tests/generics_typevartuple_variance.py b/conformance/tests/generics_typevartuple_variance.py
new file mode 100644
index 000000000..8eb3485d1
--- /dev/null
+++ b/conformance/tests/generics_typevartuple_variance.py
@@ -0,0 +1,53 @@
+"""
+Tests variance of TypeVarTuple.
+"""
+
+# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#semantics
+
+
+from typing import Generic, TypeVarTuple
+
+class ContravariantTypeVarTuple[*InTs]:
+ def f(self, t: tuple[*InTs]):
+ raise NotImplementedError
+
+in_obj: ContravariantTypeVarTuple[object] = ContravariantTypeVarTuple[int]() # E
+in_int: ContravariantTypeVarTuple[int] = ContravariantTypeVarTuple[object]() # OK
+
+
+class CovariantTypeVarTuple[*OutTs]:
+ def f(self) -> tuple[*OutTs]:
+ raise NotImplementedError
+
+
+out_int: CovariantTypeVarTuple[int] = CovariantTypeVarTuple[object]() # E
+out_obj: CovariantTypeVarTuple[object] = CovariantTypeVarTuple[int]() # OK
+
+
+InTs = TypeVarTuple("InTs", contravariant=True)
+
+
+class ContravariantTypeVarTupleOld(Generic[*InTs]):
+ def in_f(self, *args: *InTs) -> None: # OK
+ raise NotImplementedError
+
+ def out_f(self) -> tuple[*InTs]: # E
+ raise NotImplementedError
+
+
+in_obj_old: ContravariantTypeVarTupleOld[object] = ContravariantTypeVarTupleOld[int]() # E
+in_int_old: ContravariantTypeVarTupleOld[int] = ContravariantTypeVarTupleOld[object]() # OK
+
+OutTs = TypeVarTuple("OutTs", covariant=True)
+
+
+class CovariantTypeVarTupleOld(Generic[*OutTs]):
+ def in_f(self, *args: *OutTs) -> None: # E
+ raise NotImplementedError
+
+ def out_f(self) -> tuple[*OutTs]: # OK
+ raise NotImplementedError
+
+
+out_int_old: CovariantTypeVarTupleOld[int] = CovariantTypeVarTupleOld[object]() # E
+out_obj_old: CovariantTypeVarTupleOld[object] = CovariantTypeVarTupleOld[int]() # OK
diff --git a/docs/spec/generics.rst b/docs/spec/generics.rst
index 0bd2ad5c1..a383bc042 100644
--- a/docs/spec/generics.rst
+++ b/docs/spec/generics.rst
@@ -678,8 +678,8 @@ Prior to 3.12, the ``ParamSpec`` constructor can be used.
P = ParamSpec("WrongName") # Rejected because P =/= WrongName
The runtime should accept ``bound``\ s and ``covariant`` and ``contravariant``
-arguments in the declaration just as ``typing.TypeVar`` does, but for now we
-will defer the standardization of the semantics of those options to a later PEP.
+arguments in the declaration just as ``typing.TypeVar`` does, but for ``bound`` we
+will defer the standardization of the semantics of this option to a later PEP.
.. _`paramspec_valid_use_locations`:
@@ -1189,12 +1189,11 @@ for two reasons:
* To improve readability: the star also functions as an explicit visual
indicator that the type variable tuple is not a normal type variable.
-Variance, Type Constraints and Type Bounds: Not Supported
+Type Constraints and Type Bounds: Not Supported
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
``TypeVarTuple`` does not currently support specification of:
-* Variance (e.g. ``TypeVar('T', covariant=True)``)
* Type constraints (``TypeVar('T', int, float)``)
* Type bounds (``TypeVar('T', bound=ParentClass)``)
@@ -2712,14 +2711,12 @@ The algorithm for computing the variance of a type parameter is as follows.
For each type parameter in a generic class:
-1. If the type parameter is variadic (``TypeVarTuple``) it is always
-considered invariant. No further inference is needed.
+1. If the type parameter comes from a traditional
+``TypeVar``/``TypeVarTuple``/``ParamSpec`` declaration and is not specified
+as ``infer_variance`` (see below), its variance is specified by the
+constructor call. No further inference is needed.
-2. If the type parameter comes from a traditional ``TypeVar``/``ParamSpec``
-declaration and is not specified as ``infer_variance`` (see below), its
-variance is specified by the constructor call. No further inference is needed.
-
-3. Create two specialized versions of the class. We'll refer to these as
+2. Create two specialized versions of the class. We'll refer to these as
``upper`` and ``lower`` specializations. In both of these specializations,
replace all type parameters other than the one being inferred by a dummy type
instance (a concrete anonymous class that is assumed to meet the bounds or
@@ -2734,7 +2731,7 @@ This specialization ignores the type parameter's upper bound or constraints.
In the ``lower`` specialized class, specialize the target type parameter with
itself (i.e. the corresponding type argument is the type parameter itself).
-4. Determine whether ``lower`` can be assigned to ``upper`` using normal
+3. Determine whether ``lower`` can be assigned to ``upper`` using normal
assignability rules. If so, the target type parameter is covariant. If not,
determine whether ``upper`` can be assigned to ``lower``. If so, the target
type parameter is contravariant. If neither of these combinations are
From 8ecdde064d632bf8e4eca87c61d0b047ae13c06c Mon Sep 17 00:00:00 2001
From: kotlinisland <65446343+kotlinisland@users.noreply.github.com>
Date: Fri, 24 Apr 2026 09:50:31 +1000
Subject: [PATCH 3/3] fixup! specify that parameter specification should have
variance
---
docs/spec/generics.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/spec/generics.rst b/docs/spec/generics.rst
index a383bc042..8207cc21a 100644
--- a/docs/spec/generics.rst
+++ b/docs/spec/generics.rst
@@ -2725,7 +2725,7 @@ specialize the target type parameter with:
an ``object`` instance for a type variable.
a ``*tuple[object, ...]`` value for a type variable tuple.
- a ``(*object, **object)`` value for a parameter specification.
+ a ``...`` value for a parameter specification.
This specialization ignores the type parameter's upper bound or constraints.
In the ``lower`` specialized class, specialize the target type parameter with
|---|