From 0c7ca834151cf53e83280fc2eec9604a46955018 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 25 Feb 2026 03:15:59 +0100 Subject: [PATCH 1/4] Allow type checkers to infer more precise types for tuples This is consisent with the latest changes where f(1) could either be an int or a Literal[1] def f[T](x: T) -> T: ... assert_type(f(1), int) # or assert_type(f(1), Literal[1]) The same is possible with tuples: def f[*Ts](*x: *Ts) -> tuple[*Ts]: ... assert_type(f(1), tuple[int]) # or assert_type(f(1), tuple[Literal[1]]) --- .../mypy/generics_typevartuple_args.toml | 22 ++++++++++--------- .../mypy/generics_typevartuple_callable.toml | 6 +++-- .../results/pyrefly/aliases_explicit.toml | 2 +- .../results/pyrefly/aliases_recursive.toml | 1 + .../pyrefly/aliases_type_statement.toml | 1 + .../pyrefly/aliases_typealiastype.toml | 16 +++++--------- .../results/pyrefly/generics_scoping.toml | 8 +++---- .../pyrefly/generics_typevartuple_args.toml | 20 +++++++++-------- .../generics_typevartuple_callable.toml | 1 + conformance/results/pyrefly/version.toml | 2 +- .../pyright/generics_typevartuple_args.toml | 20 +++++++++-------- .../generics_typevartuple_callable.toml | 1 + conformance/results/results.html | 10 ++++----- .../results/zuban/generics_scoping.toml | 11 +++++----- .../zuban/generics_typevartuple_args.toml | 22 ++++++++++--------- .../zuban/generics_typevartuple_callable.toml | 1 + conformance/results/zuban/version.toml | 2 +- .../tests/generics_typevartuple_args.py | 8 ++++--- .../tests/generics_typevartuple_callable.py | 5 +++-- 19 files changed, 86 insertions(+), 73 deletions(-) diff --git a/conformance/results/mypy/generics_typevartuple_args.toml b/conformance/results/mypy/generics_typevartuple_args.toml index a6fae99fd..f84af3488 100644 --- a/conformance/results/mypy/generics_typevartuple_args.toml +++ b/conformance/results/mypy/generics_typevartuple_args.toml @@ -3,17 +3,19 @@ notes = """ Does not enforce that tuples captured by TypeVarTuple are same type. """ output = """ -generics_typevartuple_args.py:33: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:34: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:48: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:57: error: Argument 2 to "func2" has incompatible type "int"; expected "*tuple[*tuple[str, ...], str]" [arg-type] -generics_typevartuple_args.py:58: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:59: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:59: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:67: error: Too few arguments for "func3" [call-arg] +generics_typevartuple_args.py:35: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:36: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:50: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:59: error: Argument 2 to "func2" has incompatible type "int"; expected "*tuple[*tuple[str, ...], str]" [arg-type] +generics_typevartuple_args.py:60: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:61: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:61: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:69: error: Too few arguments for "func3" [call-arg] """ conformance_automated = "Fail" errors_diff = """ -Line 75: Expected 1 errors -Line 76: Expected 1 errors +Line 77: Expected 1 errors +Line 78: Expected 1 errors +Lines 20, 21: Expected error (tag 'args_to_tuple') +Lines 33, 34: Expected error (tag 'exec_le') """ diff --git a/conformance/results/mypy/generics_typevartuple_callable.toml b/conformance/results/mypy/generics_typevartuple_callable.toml index 904ddc9fd..e2d25e904 100644 --- a/conformance/results/mypy/generics_typevartuple_callable.toml +++ b/conformance/results/mypy/generics_typevartuple_callable.toml @@ -1,7 +1,9 @@ -conformant = "Pass" +conformant = "Partial" +notes = "Does use assert_type in two different ways" output = """ generics_typevartuple_callable.py:26: error: Argument "target" to "Process" has incompatible type "Callable[[int, str], None]"; expected "Callable[[str, int], None]" [arg-type] """ -conformance_automated = "Pass" +conformance_automated = "Fail" errors_diff = """ +Lines 49, 50: Expected error (tag 'fun3') """ diff --git a/conformance/results/pyrefly/aliases_explicit.toml b/conformance/results/pyrefly/aliases_explicit.toml index b56c87078..9edd1350a 100644 --- a/conformance/results/pyrefly/aliases_explicit.toml +++ b/conformance/results/pyrefly/aliases_explicit.toml @@ -4,7 +4,7 @@ errors_diff = """ """ output = """ ERROR aliases_explicit.py:67:9-28: `TypeAlias[GoodTypeAlias2, type[int | None]]` is not subscriptable [unsupported-operation] -ERROR aliases_explicit.py:68:9-28: `TypeAlias[GoodTypeAlias3, type[list[GoodTypeAlias2]]]` is not subscriptable [unsupported-operation] +ERROR aliases_explicit.py:68:9-28: `TypeAlias[GoodTypeAlias3, type[list[int | None]]]` is not subscriptable [unsupported-operation] ERROR aliases_explicit.py:69:9-33: Expected 1 type argument for `GoodTypeAlias4`, got 2 [bad-specialization] ERROR aliases_explicit.py:70:9-33: Expected 1 type argument for `GoodTypeAlias8`, got 2 [bad-specialization] ERROR aliases_explicit.py:71:9-33: Expected a valid ParamSpec expression, got `int` [invalid-param-spec] diff --git a/conformance/results/pyrefly/aliases_recursive.toml b/conformance/results/pyrefly/aliases_recursive.toml index 0f805c8d5..327b37f70 100644 --- a/conformance/results/pyrefly/aliases_recursive.toml +++ b/conformance/results/pyrefly/aliases_recursive.toml @@ -14,4 +14,5 @@ ERROR aliases_recursive.py:63:30-43: `list[list[float] | str | GenericTypeAlias1 ERROR aliases_recursive.py:69:35-64: `list[int | list[int | list[int | list[float] | str | GenericTypeAlias2[str, int]] | str | GenericTypeAlias2[str, int]] | str | GenericTypeAlias2[str, int]]` is not assignable to `list[int | str | GenericTypeAlias2[str, int]]` [bad-assignment] ERROR aliases_recursive.py:72:29-57: Found cyclic self-reference in `RecursiveUnion` [invalid-type-alias] ERROR aliases_recursive.py:75:31-61: Found cyclic self-reference in `MutualReference1` [invalid-type-alias] +ERROR aliases_recursive.py:75:93-123: Found cyclic self-reference in `MutualReference2` [invalid-type-alias] """ diff --git a/conformance/results/pyrefly/aliases_type_statement.toml b/conformance/results/pyrefly/aliases_type_statement.toml index b58468417..01603ba9d 100644 --- a/conformance/results/pyrefly/aliases_type_statement.toml +++ b/conformance/results/pyrefly/aliases_type_statement.toml @@ -31,5 +31,6 @@ ERROR aliases_type_statement.py:77:7-41: `str` is not assignable to upper bound ERROR aliases_type_statement.py:79:7-41: `int` is not assignable to upper bound `str` of type variable `T` [bad-specialization] ERROR aliases_type_statement.py:82:28-47: Found cyclic self-reference in `RecursiveTypeAlias3` [invalid-type-alias] ERROR aliases_type_statement.py:84:31-59: Found cyclic self-reference in `RecursiveTypeAlias4` [invalid-type-alias] +ERROR aliases_type_statement.py:88:28-47: Found cyclic self-reference in `RecursiveTypeAlias6` [invalid-type-alias] ERROR aliases_type_statement.py:89:28-47: Found cyclic self-reference in `RecursiveTypeAlias7` [invalid-type-alias] """ diff --git a/conformance/results/pyrefly/aliases_typealiastype.toml b/conformance/results/pyrefly/aliases_typealiastype.toml index ff8d05904..c4e98a923 100644 --- a/conformance/results/pyrefly/aliases_typealiastype.toml +++ b/conformance/results/pyrefly/aliases_typealiastype.toml @@ -1,11 +1,5 @@ -conformant = "Partial" -notes = """ -Does not detect circular definitions. -""" -conformance_automated = "Fail" +conformance_automated = "Pass" errors_diff = """ -Line 48: Expected 1 errors -Line 66: Expected 1 errors """ output = """ ERROR aliases_typealiastype.py:32:7-30: Object of class `TypeAliasType` has no attribute `other_attrib` [missing-attribute] @@ -13,9 +7,10 @@ ERROR aliases_typealiastype.py:40:5-30: `int` is not assignable to upper bound ` ERROR aliases_typealiastype.py:43:13-66: Type variable `S` is out of scope for this `TypeAliasType` [invalid-type-alias] ERROR aliases_typealiastype.py:44:13-48: Type variable `S` is out of scope for this `TypeAliasType` [invalid-type-alias] ERROR aliases_typealiastype.py:45:45-65: Value for argument `type_params` must be a tuple literal [invalid-type-alias] -ERROR aliases_typealiastype.py:46:41-50: Found cyclic self-reference in `BadAlias4` [invalid-type-alias] -ERROR aliases_typealiastype.py:47:40-60: Found cyclic self-reference in `BadAlias5` [invalid-type-alias] -ERROR aliases_typealiastype.py:49:40-49: Found cyclic self-reference in `BadAlias7` [invalid-type-alias] +ERROR aliases_typealiastype.py:46:13-52: Found cyclic self-reference in `BadAlias4` [invalid-type-alias] +ERROR aliases_typealiastype.py:47:13-79: Found cyclic self-reference in `BadAlias5` [invalid-type-alias] +ERROR aliases_typealiastype.py:48:13-52: Found cyclic self-reference in `BadAlias6` [invalid-type-alias] +ERROR aliases_typealiastype.py:49:13-50: Found cyclic self-reference in `BadAlias7` [invalid-type-alias] ERROR aliases_typealiastype.py:52:40-80: Function call cannot be used in annotations [invalid-annotation] ERROR aliases_typealiastype.py:53:40-50: List literal cannot be used in annotations [invalid-annotation] ERROR aliases_typealiastype.py:54:42-55: Tuple literal cannot be used in annotations [invalid-annotation] @@ -31,4 +26,5 @@ ERROR aliases_typealiastype.py:61:42-46: Bool literal cannot be used in annotati ERROR aliases_typealiastype.py:62:42-43: Number literal cannot be used in annotations [invalid-annotation] ERROR aliases_typealiastype.py:63:42-53: Boolean operation cannot be used in annotations [invalid-annotation] ERROR aliases_typealiastype.py:64:42-52: F-string cannot be used in annotations [invalid-annotation] +ERROR aliases_typealiastype.py:66:14-59: Found cyclic self-reference in `BadAlias21` [invalid-type-alias] """ diff --git a/conformance/results/pyrefly/generics_scoping.toml b/conformance/results/pyrefly/generics_scoping.toml index a4d46cbff..236c49f06 100644 --- a/conformance/results/pyrefly/generics_scoping.toml +++ b/conformance/results/pyrefly/generics_scoping.toml @@ -4,13 +4,9 @@ Does not implement several scoping checks/restrictions for generics """ conformance_automated = "Fail" errors_diff = """ -Line 61: Expected 1 errors -Line 65: Expected 1 errors Line 86: Expected 1 errors Line 89: Expected 1 errors Line 98: Expected 1 errors -Line 105: Expected 1 errors -Line 106: Expected 1 errors Line 107: Expected 1 errors """ output = """ @@ -19,5 +15,9 @@ ERROR generics_scoping.py:20:12-38: assert_type(str, Literal['a']) failed [asser ERROR generics_scoping.py:34:10-13: Argument `Literal['a']` is not assignable to parameter `x` with type `int` in function `MyClass.meth_2` [bad-argument-type] ERROR generics_scoping.py:50:12-48: assert_type(str, Literal['abc']) failed [assert-type] ERROR generics_scoping.py:54:12-50: assert_type(bytes, Literal[b'abc']) failed [assert-type] +ERROR generics_scoping.py:61:8-15: Type variable `S` is not in scope [invalid-type-var] +ERROR generics_scoping.py:65:14-21: Type variable `S` is not in scope [invalid-type-var] ERROR generics_scoping.py:76:11-20: Redundant type parameter declaration [invalid-type-var] +ERROR generics_scoping.py:105:14-15: Type variable `T` is not in scope [invalid-type-var] +ERROR generics_scoping.py:106:14-21: Type variable `T` is not in scope [invalid-type-var] """ diff --git a/conformance/results/pyrefly/generics_typevartuple_args.toml b/conformance/results/pyrefly/generics_typevartuple_args.toml index 6656023bc..46219e4f9 100644 --- a/conformance/results/pyrefly/generics_typevartuple_args.toml +++ b/conformance/results/pyrefly/generics_typevartuple_args.toml @@ -3,13 +3,15 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -ERROR generics_typevartuple_args.py:33:8-19: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] -ERROR generics_typevartuple_args.py:34:8-30: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] -ERROR generics_typevartuple_args.py:48:6-17: Unpacked argument `tuple[Literal[1], Literal['2'], Literal[3]]` is not assignable to parameter `*args` with type `tuple[int, ...]` in function `func1` [bad-argument-type] -ERROR generics_typevartuple_args.py:57:6-16: Unpacked argument `tuple[Literal[1], Literal[1], Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:58:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:59:6-10: Unpacked argument `tuple[Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:67:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, str]` in function `func3` [bad-argument-type] -ERROR generics_typevartuple_args.py:75:13-19: Argument `tuple[Literal[1], Literal[2]]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] -ERROR generics_typevartuple_args.py:76:13-19: Argument `tuple[Literal['1']]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] +ERROR generics_typevartuple_args.py:21:12-68: assert_type(tuple[int, str], tuple[Literal[1], Literal['a']]) failed [assert-type] +ERROR generics_typevartuple_args.py:34:12-71: assert_type(tuple[int, str], tuple[Literal[0], Literal['']]) failed [assert-type] +ERROR generics_typevartuple_args.py:35:8-19: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] +ERROR generics_typevartuple_args.py:36:8-30: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] +ERROR generics_typevartuple_args.py:50:6-17: Unpacked argument `tuple[Literal[1], Literal['2'], Literal[3]]` is not assignable to parameter `*args` with type `tuple[int, ...]` in function `func1` [bad-argument-type] +ERROR generics_typevartuple_args.py:59:6-16: Unpacked argument `tuple[Literal[1], Literal[1], Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:60:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:61:6-10: Unpacked argument `tuple[Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:69:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, str]` in function `func3` [bad-argument-type] +ERROR generics_typevartuple_args.py:77:13-19: Argument `tuple[Literal[1], Literal[2]]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] +ERROR generics_typevartuple_args.py:78:13-19: Argument `tuple[Literal['1']]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] """ diff --git a/conformance/results/pyrefly/generics_typevartuple_callable.toml b/conformance/results/pyrefly/generics_typevartuple_callable.toml index 4c3a32c03..435b78147 100644 --- a/conformance/results/pyrefly/generics_typevartuple_callable.toml +++ b/conformance/results/pyrefly/generics_typevartuple_callable.toml @@ -4,4 +4,5 @@ errors_diff = """ """ output = """ ERROR generics_typevartuple_callable.py:26:28-35: Argument `tuple[Literal[''], Literal[0]]` is not assignable to parameter `args` with type `tuple[int, str]` in function `Process.__init__` [bad-argument-type] +ERROR generics_typevartuple_callable.py:50:12-71: assert_type(tuple[float, str, complex], tuple[float, Literal[''], complex]) failed [assert-type] """ diff --git a/conformance/results/pyrefly/version.toml b/conformance/results/pyrefly/version.toml index d8470f38f..64c5c3a32 100644 --- a/conformance/results/pyrefly/version.toml +++ b/conformance/results/pyrefly/version.toml @@ -1 +1 @@ -version = "pyrefly 0.53.0" +version = "pyrefly 0.54.0" diff --git a/conformance/results/pyright/generics_typevartuple_args.toml b/conformance/results/pyright/generics_typevartuple_args.toml index 2ef2c70e2..360227a04 100644 --- a/conformance/results/pyright/generics_typevartuple_args.toml +++ b/conformance/results/pyright/generics_typevartuple_args.toml @@ -1,20 +1,22 @@ conformant = "Pass" output = """ -generics_typevartuple_args.py:33:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le" +generics_typevartuple_args.py:21:13 - error: "assert_type" mismatch: expected "tuple[Literal[1], Literal['a']]" but received "tuple[int, str]" (reportAssertTypeFailure) +generics_typevartuple_args.py:34:13 - error: "assert_type" mismatch: expected "tuple[Literal[0], Literal['']]" but received "tuple[int, str]" (reportAssertTypeFailure) +generics_typevartuple_args.py:35:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le"   "Literal['']" is not assignable to "Env" (reportArgumentType) -generics_typevartuple_args.py:34:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le" +generics_typevartuple_args.py:36:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le"   "Literal['']" is not assignable to "Env" (reportArgumentType) -generics_typevartuple_args.py:48:10 - error: Argument of type "Literal['2']" cannot be assigned to parameter of type "int" in function "func1" +generics_typevartuple_args.py:50:10 - error: Argument of type "Literal['2']" cannot be assigned to parameter of type "int" in function "func1"   "Literal['2']" is not assignable to "int" (reportArgumentType) -generics_typevartuple_args.py:57:10 - error: Argument of type "Literal[1]" cannot be assigned to parameter of type "str" in function "func2" +generics_typevartuple_args.py:59:10 - error: Argument of type "Literal[1]" cannot be assigned to parameter of type "str" in function "func2"   "Literal[1]" is not assignable to "str" (reportArgumentType) -generics_typevartuple_args.py:58:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) -generics_typevartuple_args.py:59:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) -generics_typevartuple_args.py:67:1 - error: Argument missing for parameter "args[1]" (reportCallIssue) -generics_typevartuple_args.py:75:13 - error: Argument of type "tuple[Literal[1], Literal[2]]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4" +generics_typevartuple_args.py:60:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) +generics_typevartuple_args.py:61:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) +generics_typevartuple_args.py:69:1 - error: Argument missing for parameter "args[1]" (reportCallIssue) +generics_typevartuple_args.py:77:13 - error: Argument of type "tuple[Literal[1], Literal[2]]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4"   "tuple[Literal[1], Literal[2]]" is not assignable to "tuple[int]"     Tuple size mismatch; expected 1 but received 2 (reportArgumentType) -generics_typevartuple_args.py:76:14 - error: Argument of type "tuple[Literal['1']]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4" +generics_typevartuple_args.py:78:14 - error: Argument of type "tuple[Literal['1']]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4"   "Literal['1']" is not assignable to "int" (reportArgumentType) """ conformance_automated = "Pass" diff --git a/conformance/results/pyright/generics_typevartuple_callable.toml b/conformance/results/pyright/generics_typevartuple_callable.toml index fb569c88c..0e189aa78 100644 --- a/conformance/results/pyright/generics_typevartuple_callable.toml +++ b/conformance/results/pyright/generics_typevartuple_callable.toml @@ -3,6 +3,7 @@ output = """ generics_typevartuple_callable.py:26:28 - error: Argument of type "tuple[Literal[''], Literal[0]]" cannot be assigned to parameter "args" of type "tuple[*Ts@__init__]" in function "__init__"   "Literal['']" is not assignable to "int"   "Literal[0]" is not assignable to "str" (reportArgumentType) +generics_typevartuple_callable.py:50:13 - error: "assert_type" mismatch: expected "tuple[float, Literal[''], complex]" but received "tuple[float, str, complex]" (reportAssertTypeFailure) """ conformance_automated = "Pass" errors_diff = """ diff --git a/conformance/results/results.html b/conformance/results/results.html index 980ba8d8b..5e6ab8f0a 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -176,9 +176,9 @@

Python Type System Conformance Test Results

pyright 1.1.408
-
zuban 0.6.0
+
zuban 0.6.1
-
pyrefly 0.53.0
+
pyrefly 0.54.0
@@ -307,7 +307,7 @@

Python Type System Conformance Test Results

     generics_scoping Pass Pass -Partial +Pass
Partial

Does not implement several scoping checks/restrictions for generics

     generics_self_advanced @@ -383,7 +383,7 @@

Python Type System Conformance Test Results

Partial

TypeVarTuple is pinned too early when calling generic function

     generics_typevartuple_callable -Pass +
Partial

Does use assert_type in two different ways

Pass Pass Pass @@ -503,7 +503,7 @@

Python Type System Conformance Test Results

Partial

Incorrectly rejects some recursive type aliases using TypeAliasType.

Incorrectly rejects the use of a class-scoped TypeVar in a TypeAliasType definition.

Pass Pass -
Partial

Does not detect circular definitions.

+Pass      aliases_variance Pass diff --git a/conformance/results/zuban/generics_scoping.toml b/conformance/results/zuban/generics_scoping.toml index 7c937b14e..54b38f2f7 100644 --- a/conformance/results/zuban/generics_scoping.toml +++ b/conformance/results/zuban/generics_scoping.toml @@ -1,13 +1,12 @@ -conformance_automated = "Fail" -conformant = "Partial" +conformance_automated = "Pass" errors_diff = """ -Lines 15, 16: Expected error (tag 'fun1') -Lines 19, 20: Expected error (tag 'fun2') -Lines 49, 50: Expected error (tag 'method-str') -Lines 53, 54: Expected error (tag 'method-bytes') """ output = """ +generics_scoping.py:15: error: Expression is of type "Literal[1]", not "int" [misc] +generics_scoping.py:19: error: Expression is of type "Literal['a']", not "str" [misc] generics_scoping.py:34: error: Argument 1 to "meth_2" of "MyClass" has incompatible type "str"; expected "int" [arg-type] +generics_scoping.py:49: error: Expression is of type "Literal['abc']", not "str" [misc] +generics_scoping.py:53: error: Expression is of type "Literal[b'abc']", not "bytes" [misc] generics_scoping.py:61: error: Type variable "generics_scoping.S" is unbound [misc] generics_scoping.py:61: note: (Hint: Use "Generic[S]" or "Protocol[S]" base class to bind "S" inside a class) generics_scoping.py:61: note: (Hint: Use "S" in function signature to bind "S" inside a function) diff --git a/conformance/results/zuban/generics_typevartuple_args.toml b/conformance/results/zuban/generics_typevartuple_args.toml index f2d5d1ccf..1406a53ef 100644 --- a/conformance/results/zuban/generics_typevartuple_args.toml +++ b/conformance/results/zuban/generics_typevartuple_args.toml @@ -2,14 +2,16 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -generics_typevartuple_args.py:33: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:34: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:48: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:57: error: Argument 2 to "func2" has incompatible type "int"; expected "str" [arg-type] -generics_typevartuple_args.py:58: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:59: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:59: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:67: error: Too few arguments for "func3" [call-arg] -generics_typevartuple_args.py:75: error: Argument 2 to "func4" has incompatible type "tuple[Literal[1], int]"; expected "tuple[int]" [arg-type] -generics_typevartuple_args.py:76: error: Argument 2 to "func4" has incompatible type "tuple[Literal['1']]"; expected "tuple[int]" [arg-type] +generics_typevartuple_args.py:20: error: Expression is of type "tuple[Literal[1], Literal['a']]", not "tuple[int, str]" [misc] +generics_typevartuple_args.py:33: error: Expression is of type "tuple[Literal[0], Literal['']]", not "tuple[int, str]" [misc] +generics_typevartuple_args.py:35: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:36: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:50: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:59: error: Argument 2 to "func2" has incompatible type "int"; expected "str" [arg-type] +generics_typevartuple_args.py:60: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:61: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:61: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:69: error: Too few arguments for "func3" [call-arg] +generics_typevartuple_args.py:77: error: Argument 2 to "func4" has incompatible type "tuple[Literal[1], int]"; expected "tuple[int]" [arg-type] +generics_typevartuple_args.py:78: error: Argument 2 to "func4" has incompatible type "tuple[Literal['1']]"; expected "tuple[int]" [arg-type] """ diff --git a/conformance/results/zuban/generics_typevartuple_callable.toml b/conformance/results/zuban/generics_typevartuple_callable.toml index d18ba3c57..04d81aba3 100644 --- a/conformance/results/zuban/generics_typevartuple_callable.toml +++ b/conformance/results/zuban/generics_typevartuple_callable.toml @@ -3,4 +3,5 @@ errors_diff = """ """ output = """ generics_typevartuple_callable.py:26: error: Argument "args" to "Process" has incompatible type "tuple[str, int]"; expected "tuple[int, str]" [arg-type] +generics_typevartuple_callable.py:49: error: Expression is of type "tuple[float, Literal[''], complex]", not "tuple[float, str, complex]" [misc] """ diff --git a/conformance/results/zuban/version.toml b/conformance/results/zuban/version.toml index c5293aabd..edcd1bf53 100644 --- a/conformance/results/zuban/version.toml +++ b/conformance/results/zuban/version.toml @@ -1 +1 @@ -version = "zuban 0.6.0" +version = "zuban 0.6.1" diff --git a/conformance/tests/generics_typevartuple_args.py b/conformance/tests/generics_typevartuple_args.py index 114d2ec44..b4bf05b47 100644 --- a/conformance/tests/generics_typevartuple_args.py +++ b/conformance/tests/generics_typevartuple_args.py @@ -7,7 +7,7 @@ # > If *args is annotated as a type variable tuple, the types of the individual # > arguments become the types in the type variable tuple. -from typing import TypeVarTuple, assert_type +from typing import TypeVarTuple, assert_type, Literal Ts = TypeVarTuple("Ts") @@ -17,7 +17,8 @@ def args_to_tuple(*args: *Ts) -> tuple[*Ts]: raise NotImplementedError -assert_type(args_to_tuple(1, "a"), tuple[int, str]) +assert_type(args_to_tuple(1, "a"), tuple[int, str]) # E[args_to_tuple] +assert_type(args_to_tuple(1, "a"), tuple[Literal[1], Literal["a"]]) # E[args_to_tuple] class Env: @@ -29,7 +30,8 @@ def exec_le(path: str, *args: * tuple[*Ts, Env], env: Env | None = None) -> tupl assert_type(exec_le("", Env()), tuple[()]) # OK -assert_type(exec_le("", 0, "", Env()), tuple[int, str]) # OK +assert_type(exec_le("", 0, "", Env()), tuple[int, str]) # E[exec_le] +assert_type(exec_le("", 0, "", Env()), tuple[Literal[0], Literal['']]) # E[exec_le] exec_le("", 0, "") # E exec_le("", 0, "", env=Env()) # E diff --git a/conformance/tests/generics_typevartuple_callable.py b/conformance/tests/generics_typevartuple_callable.py index f0292505e..e22fdc3c6 100644 --- a/conformance/tests/generics_typevartuple_callable.py +++ b/conformance/tests/generics_typevartuple_callable.py @@ -7,7 +7,7 @@ # > Type variable tuples can also be used in the arguments section of a Callable. -from typing import Callable, TypeVar, TypeVarTuple, assert_type +from typing import Callable, TypeVar, TypeVarTuple, assert_type, Literal Ts = TypeVarTuple("Ts") T = TypeVar("T") @@ -46,4 +46,5 @@ def func3(*args: * tuple[int, *Ts, T]) -> tuple[T, *Ts]: raise NotImplementedError -assert_type(func3(1, "", 3j, 3.4), tuple[float, str, complex]) +assert_type(func3(1, "", 3j, 3.4), tuple[float, str, complex]) # E[fun3] +assert_type(func3(1, "", 3j, 3.4), tuple[float, Literal[''], complex]) # E[fun3] From c1ffe96722d0bba2a0b1ccec216d6f2f68c317d0 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 25 Feb 2026 09:48:53 +0100 Subject: [PATCH 2/4] Use custom functions for expecting tuples, this avoids the need for multiple assert_types depending on different type inference --- .../mypy/generics_typevartuple_args.toml | 22 +++++++++---------- .../mypy/generics_typevartuple_callable.toml | 5 +---- .../pyrefly/generics_typevartuple_args.toml | 20 ++++++++--------- .../generics_typevartuple_callable.toml | 1 - .../pyright/generics_typevartuple_args.toml | 20 ++++++++--------- .../generics_typevartuple_callable.toml | 1 - conformance/results/results.html | 2 +- .../zuban/generics_typevartuple_args.toml | 22 +++++++++---------- .../zuban/generics_typevartuple_callable.toml | 1 - .../tests/generics_typevartuple_args.py | 10 +++++---- .../tests/generics_typevartuple_callable.py | 7 ++++-- 11 files changed, 51 insertions(+), 60 deletions(-) diff --git a/conformance/results/mypy/generics_typevartuple_args.toml b/conformance/results/mypy/generics_typevartuple_args.toml index f84af3488..a01d57cec 100644 --- a/conformance/results/mypy/generics_typevartuple_args.toml +++ b/conformance/results/mypy/generics_typevartuple_args.toml @@ -3,19 +3,17 @@ notes = """ Does not enforce that tuples captured by TypeVarTuple are same type. """ output = """ -generics_typevartuple_args.py:35: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:36: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:50: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:59: error: Argument 2 to "func2" has incompatible type "int"; expected "*tuple[*tuple[str, ...], str]" [arg-type] -generics_typevartuple_args.py:60: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:61: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:61: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:69: error: Too few arguments for "func3" [call-arg] +generics_typevartuple_args.py:37: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:38: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:52: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:61: error: Argument 2 to "func2" has incompatible type "int"; expected "*tuple[*tuple[str, ...], str]" [arg-type] +generics_typevartuple_args.py:62: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:63: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:63: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:71: error: Too few arguments for "func3" [call-arg] """ conformance_automated = "Fail" errors_diff = """ -Line 77: Expected 1 errors -Line 78: Expected 1 errors -Lines 20, 21: Expected error (tag 'args_to_tuple') -Lines 33, 34: Expected error (tag 'exec_le') +Line 79: Expected 1 errors +Line 80: Expected 1 errors """ diff --git a/conformance/results/mypy/generics_typevartuple_callable.toml b/conformance/results/mypy/generics_typevartuple_callable.toml index e2d25e904..ac5239993 100644 --- a/conformance/results/mypy/generics_typevartuple_callable.toml +++ b/conformance/results/mypy/generics_typevartuple_callable.toml @@ -1,9 +1,6 @@ -conformant = "Partial" -notes = "Does use assert_type in two different ways" output = """ generics_typevartuple_callable.py:26: error: Argument "target" to "Process" has incompatible type "Callable[[int, str], None]"; expected "Callable[[str, int], None]" [arg-type] """ -conformance_automated = "Fail" +conformance_automated = "Pass" errors_diff = """ -Lines 49, 50: Expected error (tag 'fun3') """ diff --git a/conformance/results/pyrefly/generics_typevartuple_args.toml b/conformance/results/pyrefly/generics_typevartuple_args.toml index 46219e4f9..62c2bca87 100644 --- a/conformance/results/pyrefly/generics_typevartuple_args.toml +++ b/conformance/results/pyrefly/generics_typevartuple_args.toml @@ -3,15 +3,13 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -ERROR generics_typevartuple_args.py:21:12-68: assert_type(tuple[int, str], tuple[Literal[1], Literal['a']]) failed [assert-type] -ERROR generics_typevartuple_args.py:34:12-71: assert_type(tuple[int, str], tuple[Literal[0], Literal['']]) failed [assert-type] -ERROR generics_typevartuple_args.py:35:8-19: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] -ERROR generics_typevartuple_args.py:36:8-30: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] -ERROR generics_typevartuple_args.py:50:6-17: Unpacked argument `tuple[Literal[1], Literal['2'], Literal[3]]` is not assignable to parameter `*args` with type `tuple[int, ...]` in function `func1` [bad-argument-type] -ERROR generics_typevartuple_args.py:59:6-16: Unpacked argument `tuple[Literal[1], Literal[1], Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:60:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:61:6-10: Unpacked argument `tuple[Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:69:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, str]` in function `func3` [bad-argument-type] -ERROR generics_typevartuple_args.py:77:13-19: Argument `tuple[Literal[1], Literal[2]]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] -ERROR generics_typevartuple_args.py:78:13-19: Argument `tuple[Literal['1']]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] +ERROR generics_typevartuple_args.py:37:8-19: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] +ERROR generics_typevartuple_args.py:38:8-30: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] +ERROR generics_typevartuple_args.py:52:6-17: Unpacked argument `tuple[Literal[1], Literal['2'], Literal[3]]` is not assignable to parameter `*args` with type `tuple[int, ...]` in function `func1` [bad-argument-type] +ERROR generics_typevartuple_args.py:61:6-16: Unpacked argument `tuple[Literal[1], Literal[1], Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:62:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:63:6-10: Unpacked argument `tuple[Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:71:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, str]` in function `func3` [bad-argument-type] +ERROR generics_typevartuple_args.py:79:13-19: Argument `tuple[Literal[1], Literal[2]]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] +ERROR generics_typevartuple_args.py:80:13-19: Argument `tuple[Literal['1']]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] """ diff --git a/conformance/results/pyrefly/generics_typevartuple_callable.toml b/conformance/results/pyrefly/generics_typevartuple_callable.toml index 435b78147..4c3a32c03 100644 --- a/conformance/results/pyrefly/generics_typevartuple_callable.toml +++ b/conformance/results/pyrefly/generics_typevartuple_callable.toml @@ -4,5 +4,4 @@ errors_diff = """ """ output = """ ERROR generics_typevartuple_callable.py:26:28-35: Argument `tuple[Literal[''], Literal[0]]` is not assignable to parameter `args` with type `tuple[int, str]` in function `Process.__init__` [bad-argument-type] -ERROR generics_typevartuple_callable.py:50:12-71: assert_type(tuple[float, str, complex], tuple[float, Literal[''], complex]) failed [assert-type] """ diff --git a/conformance/results/pyright/generics_typevartuple_args.toml b/conformance/results/pyright/generics_typevartuple_args.toml index 360227a04..451bcdf58 100644 --- a/conformance/results/pyright/generics_typevartuple_args.toml +++ b/conformance/results/pyright/generics_typevartuple_args.toml @@ -1,22 +1,20 @@ conformant = "Pass" output = """ -generics_typevartuple_args.py:21:13 - error: "assert_type" mismatch: expected "tuple[Literal[1], Literal['a']]" but received "tuple[int, str]" (reportAssertTypeFailure) -generics_typevartuple_args.py:34:13 - error: "assert_type" mismatch: expected "tuple[Literal[0], Literal['']]" but received "tuple[int, str]" (reportAssertTypeFailure) -generics_typevartuple_args.py:35:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le" +generics_typevartuple_args.py:37:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le"   "Literal['']" is not assignable to "Env" (reportArgumentType) -generics_typevartuple_args.py:36:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le" +generics_typevartuple_args.py:38:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le"   "Literal['']" is not assignable to "Env" (reportArgumentType) -generics_typevartuple_args.py:50:10 - error: Argument of type "Literal['2']" cannot be assigned to parameter of type "int" in function "func1" +generics_typevartuple_args.py:52:10 - error: Argument of type "Literal['2']" cannot be assigned to parameter of type "int" in function "func1"   "Literal['2']" is not assignable to "int" (reportArgumentType) -generics_typevartuple_args.py:59:10 - error: Argument of type "Literal[1]" cannot be assigned to parameter of type "str" in function "func2" +generics_typevartuple_args.py:61:10 - error: Argument of type "Literal[1]" cannot be assigned to parameter of type "str" in function "func2"   "Literal[1]" is not assignable to "str" (reportArgumentType) -generics_typevartuple_args.py:60:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) -generics_typevartuple_args.py:61:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) -generics_typevartuple_args.py:69:1 - error: Argument missing for parameter "args[1]" (reportCallIssue) -generics_typevartuple_args.py:77:13 - error: Argument of type "tuple[Literal[1], Literal[2]]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4" +generics_typevartuple_args.py:62:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) +generics_typevartuple_args.py:63:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) +generics_typevartuple_args.py:71:1 - error: Argument missing for parameter "args[1]" (reportCallIssue) +generics_typevartuple_args.py:79:13 - error: Argument of type "tuple[Literal[1], Literal[2]]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4"   "tuple[Literal[1], Literal[2]]" is not assignable to "tuple[int]"     Tuple size mismatch; expected 1 but received 2 (reportArgumentType) -generics_typevartuple_args.py:78:14 - error: Argument of type "tuple[Literal['1']]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4" +generics_typevartuple_args.py:80:14 - error: Argument of type "tuple[Literal['1']]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4"   "Literal['1']" is not assignable to "int" (reportArgumentType) """ conformance_automated = "Pass" diff --git a/conformance/results/pyright/generics_typevartuple_callable.toml b/conformance/results/pyright/generics_typevartuple_callable.toml index 0e189aa78..fb569c88c 100644 --- a/conformance/results/pyright/generics_typevartuple_callable.toml +++ b/conformance/results/pyright/generics_typevartuple_callable.toml @@ -3,7 +3,6 @@ output = """ generics_typevartuple_callable.py:26:28 - error: Argument of type "tuple[Literal[''], Literal[0]]" cannot be assigned to parameter "args" of type "tuple[*Ts@__init__]" in function "__init__"   "Literal['']" is not assignable to "int"   "Literal[0]" is not assignable to "str" (reportArgumentType) -generics_typevartuple_callable.py:50:13 - error: "assert_type" mismatch: expected "tuple[float, Literal[''], complex]" but received "tuple[float, str, complex]" (reportAssertTypeFailure) """ conformance_automated = "Pass" errors_diff = """ diff --git a/conformance/results/results.html b/conformance/results/results.html index 5e6ab8f0a..95c73cb79 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -383,7 +383,7 @@

Python Type System Conformance Test Results

Partial

TypeVarTuple is pinned too early when calling generic function

     generics_typevartuple_callable -
Partial

Does use assert_type in two different ways

+Pass Pass Pass Pass diff --git a/conformance/results/zuban/generics_typevartuple_args.toml b/conformance/results/zuban/generics_typevartuple_args.toml index 1406a53ef..ab1d0d92e 100644 --- a/conformance/results/zuban/generics_typevartuple_args.toml +++ b/conformance/results/zuban/generics_typevartuple_args.toml @@ -2,16 +2,14 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -generics_typevartuple_args.py:20: error: Expression is of type "tuple[Literal[1], Literal['a']]", not "tuple[int, str]" [misc] -generics_typevartuple_args.py:33: error: Expression is of type "tuple[Literal[0], Literal['']]", not "tuple[int, str]" [misc] -generics_typevartuple_args.py:35: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:36: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:50: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:59: error: Argument 2 to "func2" has incompatible type "int"; expected "str" [arg-type] -generics_typevartuple_args.py:60: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:61: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:61: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:69: error: Too few arguments for "func3" [call-arg] -generics_typevartuple_args.py:77: error: Argument 2 to "func4" has incompatible type "tuple[Literal[1], int]"; expected "tuple[int]" [arg-type] -generics_typevartuple_args.py:78: error: Argument 2 to "func4" has incompatible type "tuple[Literal['1']]"; expected "tuple[int]" [arg-type] +generics_typevartuple_args.py:37: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:38: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:52: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:61: error: Argument 2 to "func2" has incompatible type "int"; expected "str" [arg-type] +generics_typevartuple_args.py:62: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:63: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:63: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:71: error: Too few arguments for "func3" [call-arg] +generics_typevartuple_args.py:79: error: Argument 2 to "func4" has incompatible type "tuple[Literal[1], int]"; expected "tuple[int]" [arg-type] +generics_typevartuple_args.py:80: error: Argument 2 to "func4" has incompatible type "tuple[Literal['1']]"; expected "tuple[int]" [arg-type] """ diff --git a/conformance/results/zuban/generics_typevartuple_callable.toml b/conformance/results/zuban/generics_typevartuple_callable.toml index 04d81aba3..d18ba3c57 100644 --- a/conformance/results/zuban/generics_typevartuple_callable.toml +++ b/conformance/results/zuban/generics_typevartuple_callable.toml @@ -3,5 +3,4 @@ errors_diff = """ """ output = """ generics_typevartuple_callable.py:26: error: Argument "args" to "Process" has incompatible type "tuple[str, int]"; expected "tuple[int, str]" [arg-type] -generics_typevartuple_callable.py:49: error: Expression is of type "tuple[float, Literal[''], complex]", not "tuple[float, str, complex]" [misc] """ diff --git a/conformance/tests/generics_typevartuple_args.py b/conformance/tests/generics_typevartuple_args.py index b4bf05b47..66124ed6d 100644 --- a/conformance/tests/generics_typevartuple_args.py +++ b/conformance/tests/generics_typevartuple_args.py @@ -17,8 +17,11 @@ def args_to_tuple(*args: *Ts) -> tuple[*Ts]: raise NotImplementedError -assert_type(args_to_tuple(1, "a"), tuple[int, str]) # E[args_to_tuple] -assert_type(args_to_tuple(1, "a"), tuple[Literal[1], Literal["a"]]) # E[args_to_tuple] +def takes_int_and_str(tup: tuple[int, str]) -> None: + raise NotImplementedError + + +takes_int_and_str(args_to_tuple(1, "a")) class Env: @@ -30,8 +33,7 @@ def exec_le(path: str, *args: * tuple[*Ts, Env], env: Env | None = None) -> tupl assert_type(exec_le("", Env()), tuple[()]) # OK -assert_type(exec_le("", 0, "", Env()), tuple[int, str]) # E[exec_le] -assert_type(exec_le("", 0, "", Env()), tuple[Literal[0], Literal['']]) # E[exec_le] +takes_int_and_str(exec_le("", 0, "", Env())) exec_le("", 0, "") # E exec_le("", 0, "", env=Env()) # E diff --git a/conformance/tests/generics_typevartuple_callable.py b/conformance/tests/generics_typevartuple_callable.py index e22fdc3c6..d43f41677 100644 --- a/conformance/tests/generics_typevartuple_callable.py +++ b/conformance/tests/generics_typevartuple_callable.py @@ -46,5 +46,8 @@ def func3(*args: * tuple[int, *Ts, T]) -> tuple[T, *Ts]: raise NotImplementedError -assert_type(func3(1, "", 3j, 3.4), tuple[float, str, complex]) # E[fun3] -assert_type(func3(1, "", 3j, 3.4), tuple[float, Literal[''], complex]) # E[fun3] +def takes_float_str_complex(tup: tuple[float, str, complex]) -> None: + raise NotImplementedError + + +takes_float_str_complex(func3(1, "", 3j, 3.4)) From 476cf341f868af266676191c7813109384505f67 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 25 Feb 2026 19:48:08 +0100 Subject: [PATCH 3/4] Use assert_type with tuples in functions so types cannot be inferred as literals --- .../mypy/generics_typevartuple_args.toml | 20 +++++++++---------- .../mypy/generics_typevartuple_callable.toml | 1 + .../pyrefly/generics_typevartuple_args.toml | 18 ++++++++--------- .../pyright/generics_typevartuple_args.toml | 18 ++++++++--------- .../zuban/generics_typevartuple_args.toml | 20 +++++++++---------- .../tests/generics_typevartuple_args.py | 20 ++++++++----------- .../tests/generics_typevartuple_callable.py | 9 +++------ 7 files changed, 50 insertions(+), 56 deletions(-) diff --git a/conformance/results/mypy/generics_typevartuple_args.toml b/conformance/results/mypy/generics_typevartuple_args.toml index a01d57cec..a6fae99fd 100644 --- a/conformance/results/mypy/generics_typevartuple_args.toml +++ b/conformance/results/mypy/generics_typevartuple_args.toml @@ -3,17 +3,17 @@ notes = """ Does not enforce that tuples captured by TypeVarTuple are same type. """ output = """ -generics_typevartuple_args.py:37: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:38: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:52: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:61: error: Argument 2 to "func2" has incompatible type "int"; expected "*tuple[*tuple[str, ...], str]" [arg-type] -generics_typevartuple_args.py:62: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:63: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:63: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:71: error: Too few arguments for "func3" [call-arg] +generics_typevartuple_args.py:33: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:34: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:48: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:57: error: Argument 2 to "func2" has incompatible type "int"; expected "*tuple[*tuple[str, ...], str]" [arg-type] +generics_typevartuple_args.py:58: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:59: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:59: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:67: error: Too few arguments for "func3" [call-arg] """ conformance_automated = "Fail" errors_diff = """ -Line 79: Expected 1 errors -Line 80: Expected 1 errors +Line 75: Expected 1 errors +Line 76: Expected 1 errors """ diff --git a/conformance/results/mypy/generics_typevartuple_callable.toml b/conformance/results/mypy/generics_typevartuple_callable.toml index ac5239993..904ddc9fd 100644 --- a/conformance/results/mypy/generics_typevartuple_callable.toml +++ b/conformance/results/mypy/generics_typevartuple_callable.toml @@ -1,3 +1,4 @@ +conformant = "Pass" output = """ generics_typevartuple_callable.py:26: error: Argument "target" to "Process" has incompatible type "Callable[[int, str], None]"; expected "Callable[[str, int], None]" [arg-type] """ diff --git a/conformance/results/pyrefly/generics_typevartuple_args.toml b/conformance/results/pyrefly/generics_typevartuple_args.toml index 62c2bca87..ae29ac7e9 100644 --- a/conformance/results/pyrefly/generics_typevartuple_args.toml +++ b/conformance/results/pyrefly/generics_typevartuple_args.toml @@ -3,13 +3,13 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -ERROR generics_typevartuple_args.py:37:8-19: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] -ERROR generics_typevartuple_args.py:38:8-30: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] -ERROR generics_typevartuple_args.py:52:6-17: Unpacked argument `tuple[Literal[1], Literal['2'], Literal[3]]` is not assignable to parameter `*args` with type `tuple[int, ...]` in function `func1` [bad-argument-type] -ERROR generics_typevartuple_args.py:61:6-16: Unpacked argument `tuple[Literal[1], Literal[1], Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:62:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:63:6-10: Unpacked argument `tuple[Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] -ERROR generics_typevartuple_args.py:71:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, str]` in function `func3` [bad-argument-type] -ERROR generics_typevartuple_args.py:79:13-19: Argument `tuple[Literal[1], Literal[2]]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] -ERROR generics_typevartuple_args.py:80:13-19: Argument `tuple[Literal['1']]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] +ERROR generics_typevartuple_args.py:33:12-23: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] +ERROR generics_typevartuple_args.py:34:12-34: Unpacked argument `tuple[Literal[0], Literal['']]` is not assignable to parameter `*args` with type `tuple[*@_, Env]` in function `exec_le` [bad-argument-type] +ERROR generics_typevartuple_args.py:48:6-17: Unpacked argument `tuple[Literal[1], Literal['2'], Literal[3]]` is not assignable to parameter `*args` with type `tuple[int, ...]` in function `func1` [bad-argument-type] +ERROR generics_typevartuple_args.py:57:6-16: Unpacked argument `tuple[Literal[1], Literal[1], Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:58:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:59:6-10: Unpacked argument `tuple[Literal['']]` is not assignable to parameter `*args` with type `tuple[int, *tuple[str, ...], str]` in function `func2` [bad-argument-type] +ERROR generics_typevartuple_args.py:67:6-9: Unpacked argument `tuple[Literal[1]]` is not assignable to parameter `*args` with type `tuple[int, str]` in function `func3` [bad-argument-type] +ERROR generics_typevartuple_args.py:75:13-19: Argument `tuple[Literal[1], Literal[2]]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] +ERROR generics_typevartuple_args.py:76:13-19: Argument `tuple[Literal['1']]` is not assignable to parameter `*args` with type `tuple[int]` in function `func4` [bad-argument-type] """ diff --git a/conformance/results/pyright/generics_typevartuple_args.toml b/conformance/results/pyright/generics_typevartuple_args.toml index 451bcdf58..de352581a 100644 --- a/conformance/results/pyright/generics_typevartuple_args.toml +++ b/conformance/results/pyright/generics_typevartuple_args.toml @@ -1,20 +1,20 @@ conformant = "Pass" output = """ -generics_typevartuple_args.py:37:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le" +generics_typevartuple_args.py:33:20 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le"   "Literal['']" is not assignable to "Env" (reportArgumentType) -generics_typevartuple_args.py:38:16 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le" +generics_typevartuple_args.py:34:20 - error: Argument of type "Literal['']" cannot be assigned to parameter of type "Env" in function "exec_le"   "Literal['']" is not assignable to "Env" (reportArgumentType) -generics_typevartuple_args.py:52:10 - error: Argument of type "Literal['2']" cannot be assigned to parameter of type "int" in function "func1" +generics_typevartuple_args.py:48:10 - error: Argument of type "Literal['2']" cannot be assigned to parameter of type "int" in function "func1"   "Literal['2']" is not assignable to "int" (reportArgumentType) -generics_typevartuple_args.py:61:10 - error: Argument of type "Literal[1]" cannot be assigned to parameter of type "str" in function "func2" +generics_typevartuple_args.py:57:10 - error: Argument of type "Literal[1]" cannot be assigned to parameter of type "str" in function "func2"   "Literal[1]" is not assignable to "str" (reportArgumentType) -generics_typevartuple_args.py:62:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) -generics_typevartuple_args.py:63:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) -generics_typevartuple_args.py:71:1 - error: Argument missing for parameter "args[1]" (reportCallIssue) -generics_typevartuple_args.py:79:13 - error: Argument of type "tuple[Literal[1], Literal[2]]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4" +generics_typevartuple_args.py:58:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) +generics_typevartuple_args.py:59:1 - error: Argument missing for parameter "args[2]" (reportCallIssue) +generics_typevartuple_args.py:67:1 - error: Argument missing for parameter "args[1]" (reportCallIssue) +generics_typevartuple_args.py:75:13 - error: Argument of type "tuple[Literal[1], Literal[2]]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4"   "tuple[Literal[1], Literal[2]]" is not assignable to "tuple[int]"     Tuple size mismatch; expected 1 but received 2 (reportArgumentType) -generics_typevartuple_args.py:80:14 - error: Argument of type "tuple[Literal['1']]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4" +generics_typevartuple_args.py:76:14 - error: Argument of type "tuple[Literal['1']]" cannot be assigned to parameter "args" of type "tuple[*Ts@func4]" in function "func4"   "Literal['1']" is not assignable to "int" (reportArgumentType) """ conformance_automated = "Pass" diff --git a/conformance/results/zuban/generics_typevartuple_args.toml b/conformance/results/zuban/generics_typevartuple_args.toml index ab1d0d92e..f2d5d1ccf 100644 --- a/conformance/results/zuban/generics_typevartuple_args.toml +++ b/conformance/results/zuban/generics_typevartuple_args.toml @@ -2,14 +2,14 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -generics_typevartuple_args.py:37: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:38: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] -generics_typevartuple_args.py:52: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:61: error: Argument 2 to "func2" has incompatible type "int"; expected "str" [arg-type] -generics_typevartuple_args.py:62: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:63: error: Too few arguments for "func2" [call-arg] -generics_typevartuple_args.py:63: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] -generics_typevartuple_args.py:71: error: Too few arguments for "func3" [call-arg] -generics_typevartuple_args.py:79: error: Argument 2 to "func4" has incompatible type "tuple[Literal[1], int]"; expected "tuple[int]" [arg-type] -generics_typevartuple_args.py:80: error: Argument 2 to "func4" has incompatible type "tuple[Literal['1']]"; expected "tuple[int]" [arg-type] +generics_typevartuple_args.py:33: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:34: error: Argument 3 to "exec_le" has incompatible type "str"; expected "Env" [arg-type] +generics_typevartuple_args.py:48: error: Argument 2 to "func1" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:57: error: Argument 2 to "func2" has incompatible type "int"; expected "str" [arg-type] +generics_typevartuple_args.py:58: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:59: error: Too few arguments for "func2" [call-arg] +generics_typevartuple_args.py:59: error: Argument 1 to "func2" has incompatible type "str"; expected "int" [arg-type] +generics_typevartuple_args.py:67: error: Too few arguments for "func3" [call-arg] +generics_typevartuple_args.py:75: error: Argument 2 to "func4" has incompatible type "tuple[Literal[1], int]"; expected "tuple[int]" [arg-type] +generics_typevartuple_args.py:76: error: Argument 2 to "func4" has incompatible type "tuple[Literal['1']]"; expected "tuple[int]" [arg-type] """ diff --git a/conformance/tests/generics_typevartuple_args.py b/conformance/tests/generics_typevartuple_args.py index 66124ed6d..1afd69f28 100644 --- a/conformance/tests/generics_typevartuple_args.py +++ b/conformance/tests/generics_typevartuple_args.py @@ -7,7 +7,7 @@ # > If *args is annotated as a type variable tuple, the types of the individual # > arguments become the types in the type variable tuple. -from typing import TypeVarTuple, assert_type, Literal +from typing import TypeVarTuple, assert_type Ts = TypeVarTuple("Ts") @@ -17,13 +17,6 @@ def args_to_tuple(*args: *Ts) -> tuple[*Ts]: raise NotImplementedError -def takes_int_and_str(tup: tuple[int, str]) -> None: - raise NotImplementedError - - -takes_int_and_str(args_to_tuple(1, "a")) - - class Env: ... @@ -32,10 +25,13 @@ def exec_le(path: str, *args: * tuple[*Ts, Env], env: Env | None = None) -> tupl raise NotImplementedError -assert_type(exec_le("", Env()), tuple[()]) # OK -takes_int_and_str(exec_le("", 0, "", Env())) -exec_le("", 0, "") # E -exec_le("", 0, "", env=Env()) # E +def has_int_and_str(x: int, y: str): + assert_type(args_to_tuple(x, y), tuple[int, str]) + + assert_type(exec_le("", Env()), tuple[()]) # OK + assert_type(exec_le(y, x, y, Env()), tuple[int, str]) # OK + exec_le("", 0, "") # E + exec_le("", 0, "", env=Env()) # E # > Using an unpacked unbounded tuple is equivalent to the diff --git a/conformance/tests/generics_typevartuple_callable.py b/conformance/tests/generics_typevartuple_callable.py index d43f41677..f0b32c6ed 100644 --- a/conformance/tests/generics_typevartuple_callable.py +++ b/conformance/tests/generics_typevartuple_callable.py @@ -7,7 +7,7 @@ # > Type variable tuples can also be used in the arguments section of a Callable. -from typing import Callable, TypeVar, TypeVarTuple, assert_type, Literal +from typing import Callable, TypeVar, TypeVarTuple, assert_type Ts = TypeVarTuple("Ts") T = TypeVar("T") @@ -46,8 +46,5 @@ def func3(*args: * tuple[int, *Ts, T]) -> tuple[T, *Ts]: raise NotImplementedError -def takes_float_str_complex(tup: tuple[float, str, complex]) -> None: - raise NotImplementedError - - -takes_float_str_complex(func3(1, "", 3j, 3.4)) +def has_int_and_str(x: int, y: str): + assert_type(func3(x, y, 3j, 3.4), tuple[float, str, complex]) From 40bc3c339897caee339f3f379eaaebbcfa790198 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 25 Feb 2026 20:19:58 +0000 Subject: [PATCH 4/4] Small change to be even more accepting of narrowing rules Co-authored-by: Alex Waygood --- conformance/tests/generics_typevartuple_callable.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conformance/tests/generics_typevartuple_callable.py b/conformance/tests/generics_typevartuple_callable.py index f0b32c6ed..11e596573 100644 --- a/conformance/tests/generics_typevartuple_callable.py +++ b/conformance/tests/generics_typevartuple_callable.py @@ -46,5 +46,5 @@ def func3(*args: * tuple[int, *Ts, T]) -> tuple[T, *Ts]: raise NotImplementedError -def has_int_and_str(x: int, y: str): - assert_type(func3(x, y, 3j, 3.4), tuple[float, str, complex]) +def has_int_and_str(a: int, b: str, c: float, d: complex): + assert_type(func3(a, b, c, d), tuple[float, str, complex])