Skip to content

Commit d08f800

Browse files
AlexWaygoodcarljm
andauthored
Add conformance results for ty (#2208)
Co-authored-by: Carl Meyer <carl@oddbird.net>
1 parent 7f8f6bb commit d08f800

File tree

146 files changed

+2552
-24
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+2552
-24
lines changed

conformance/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Note that some type checkers may not run on some platforms. If a type checker fa
8080

8181
Different type checkers report errors in different ways (with different wording in error messages and different line numbers or character ranges for errors). This variation makes it difficult to fully automate test validation given that tests will want to check for both false positive and false negative type errors. Some level of manual inspection will therefore be needed to determine whether a type checker is fully conformant with all tests in any given test file. This "scoring" process is required only when the output of a test changes — e.g. when a new version of that type checker is released and the tests are rerun. We assume that the output of a type checker will be the same from one run to the next unless/until a new version is released that fixes or introduces a bug. In this case, the output will need to be manually inspected and the conformance results re-scored for those tests whose output has changed.
8282

83-
Conformance results are reported and summarized for each supported type checker. Currently, results are reported for mypy, pyrefly, pyright, and zuban. It is the goal and desire to add additional type checkers over time.
83+
Conformance results are reported and summarized for each supported type checker. Currently, results are reported for mypy, pyrefly, pyright, zuban and ty. It is the goal and desire to add additional type checkers over time.
8484

8585
## Adding a New Test Case
8686

conformance/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies = [
99
"tomli",
1010
"tomlkit",
1111
"zuban",
12+
"ty",
1213
]
1314

1415
[tool.uv]

conformance/results/results.html

Lines changed: 161 additions & 20 deletions
Large diffs are not rendered by default.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
conformance_automated = "Fail"
2+
conformant = "Partial"
3+
notes = "`Concatenate` in type aliases is currently unsupported"
4+
errors_diff = """
5+
Line 87: Expected 1 errors
6+
Line 100: Expected 1 errors
7+
Line 57: Unexpected errors ['aliases_explicit.py:57:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `(int, str, str, /) -> None`']
8+
"""
9+
output = """
10+
aliases_explicit.py:57:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `(int, str, str, /) -> None`
11+
aliases_explicit.py:67:9: error[not-subscriptable] Cannot subscript non-generic type `<types.UnionType special-form 'int | None'>`
12+
aliases_explicit.py:68:9: error[not-subscriptable] Cannot subscript non-generic type `<class 'list[int | None]'>`
13+
aliases_explicit.py:69:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
14+
aliases_explicit.py:70:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
15+
aliases_explicit.py:71:24: error[invalid-type-arguments] Type argument for `ParamSpec` must be either a list of types, `ParamSpec`, `Concatenate`, or `...`
16+
aliases_explicit.py:79:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
17+
aliases_explicit.py:80:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
18+
aliases_explicit.py:81:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
19+
aliases_explicit.py:82:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
20+
aliases_explicit.py:83:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
21+
aliases_explicit.py:84:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
22+
aliases_explicit.py:85:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
23+
aliases_explicit.py:86:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
24+
aliases_explicit.py:88:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
25+
aliases_explicit.py:89:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
26+
aliases_explicit.py:90:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
27+
aliases_explicit.py:91:1: error[invalid-type-form] Invalid right-hand side for `typing.TypeAlias` assignment
28+
aliases_explicit.py:101:6: error[call-non-callable] Object of type `UnionType` is not callable
29+
aliases_explicit.py:102:5: error[not-subscriptable] Cannot subscript non-generic type `<types.UnionType special-form 'list[Unknown] | set[Unknown]'>`
30+
"""
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
conformance_automated = "Fail"
2+
conformant = "Partial"
3+
notes = """
4+
Does not reject variables with `Any` or `Unknown` types when used as implicit type aliases.
5+
Does not support `Concatenate` in type aliases.
6+
"""
7+
errors_diff = """
8+
Line 106: Expected 1 errors
9+
Line 111: Expected 1 errors
10+
Line 112: Expected 1 errors
11+
Line 113: Expected 1 errors
12+
Line 117: Expected 1 errors
13+
Line 68: Unexpected errors ['aliases_implicit.py:68:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `(int, str, str, /) -> None`']
14+
"""
15+
output = """
16+
aliases_implicit.py:68:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `(int, str, str, /) -> None`
17+
aliases_implicit.py:76:9: error[not-subscriptable] Cannot subscript non-generic type `<types.UnionType special-form 'int | None'>`
18+
aliases_implicit.py:77:9: error[not-subscriptable] Cannot subscript non-generic type `<class 'list[int | None]'>`
19+
aliases_implicit.py:78:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
20+
aliases_implicit.py:79:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
21+
aliases_implicit.py:80:24: error[invalid-type-arguments] Type argument for `ParamSpec` must be either a list of types, `ParamSpec`, `Concatenate`, or `...`
22+
aliases_implicit.py:81:25: error[invalid-type-arguments] Type `str` is not assignable to upper bound `int | float` of type variable `TFloat@GoodTypeAlias12`
23+
aliases_implicit.py:107:9: error[invalid-type-form] Variable of type `list[<class 'int'> | <class 'str'>]` is not allowed in a type expression
24+
aliases_implicit.py:108:9: error[invalid-type-form] Variable of type `tuple[tuple[<class 'int'>, <class 'str'>]]` is not allowed in a type expression
25+
aliases_implicit.py:109:9: error[invalid-type-form] Variable of type `list[<class 'int'>]` is not allowed in a type expression
26+
aliases_implicit.py:110:9: error[invalid-type-form] Variable of type `dict[str, str]` is not allowed in a type expression
27+
aliases_implicit.py:114:9: error[invalid-type-form] Variable of type `Literal[3]` is not allowed in a type expression
28+
aliases_implicit.py:115:10: error[invalid-type-form] Variable of type `Literal[True]` is not allowed in a type expression
29+
aliases_implicit.py:116:10: error[invalid-type-form] Variable of type `Literal[1]` is not allowed in a type expression
30+
aliases_implicit.py:118:10: error[invalid-type-form] Variable of type `Literal["int"]` is not allowed in a type expression
31+
aliases_implicit.py:119:10: error[invalid-type-form] Variable of type `Literal["int | str"]` is not allowed in a type expression
32+
aliases_implicit.py:133:6: error[call-non-callable] Object of type `UnionType` is not callable
33+
aliases_implicit.py:135:5: error[not-subscriptable] Cannot subscript non-generic type `<types.UnionType special-form 'list[Unknown] | set[Unknown]'>`
34+
"""
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
conformance_automated = "Pass"
2+
errors_diff = """
3+
"""
4+
output = """
5+
aliases_newtype.py:11:8: error[invalid-argument-type] Argument is incorrect: Expected `int`, found `Literal["user"]`
6+
aliases_newtype.py:12:14: error[invalid-assignment] Object of type `Literal[42]` is not assignable to `UserId`
7+
aliases_newtype.py:18:11: error[invalid-assignment] Object of type `<NewType pseudo-class 'UserId'>` is not assignable to `type`
8+
aliases_newtype.py:23:16: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | UnionType | tuple[Divergent, ...]`, found `<NewType pseudo-class 'UserId'>`
9+
aliases_newtype.py:26:21: error[invalid-base] Cannot subclass an instance of NewType
10+
aliases_newtype.py:35:1: error[invalid-newtype] The name of a `NewType` (`BadName`) must match the name of the variable it is assigned to (`GoodName`)
11+
aliases_newtype.py:41:6: error[invalid-type-form] `GoodNewType1` is a `NewType` and cannot be specialized
12+
aliases_newtype.py:47:38: error[invalid-newtype] invalid base for `typing.NewType`: type `int | str`
13+
aliases_newtype.py:50:38: error[invalid-newtype] invalid base for `typing.NewType`: A `NewType` base cannot be generic
14+
aliases_newtype.py:52:38: error[invalid-newtype] invalid base for `typing.NewType`: type `Hashable`
15+
aliases_newtype.py:54:38: error[invalid-newtype] invalid base for `typing.NewType`: type `Literal[7]`
16+
aliases_newtype.py:61:38: error[invalid-newtype] invalid base for `typing.NewType`: type `TD1`
17+
aliases_newtype.py:63:15: error[invalid-newtype] Wrong number of arguments in `NewType` creation: expected 2, found 3
18+
aliases_newtype.py:65:38: error[invalid-newtype] invalid base for `typing.NewType`: type `Any`
19+
"""
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
conformance_automated = "Fail"
2+
conformant = "Unsupported"
3+
errors_diff = """
4+
Line 19: Expected 1 errors
5+
Line 20: Expected 1 errors
6+
Line 38: Expected 1 errors
7+
Line 39: Expected 1 errors
8+
Line 50: Expected 1 errors
9+
Line 51: Expected 1 errors
10+
Line 52: Expected 1 errors
11+
Line 63: Expected 1 errors
12+
Line 69: Expected 1 errors
13+
Line 72: Expected 1 errors
14+
Line 75: Expected 1 errors
15+
"""
16+
output = """
17+
"""
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
conformance_automated = "Fail"
2+
conformant = "Partial"
3+
notes = """
4+
Does not reject use of the `type` statement inside functions.
5+
Does not reject circular definitions of type aliases.
6+
Does not reject redeclarations of type aliases.
7+
Does not support `type` statements generic over `TypeVarTuple`s.
8+
"""
9+
errors_diff = """
10+
Line 56: Expected 1 errors
11+
Line 84: Expected 1 errors
12+
Lines 51, 52: Expected error (tag 'TA14')
13+
Line 10: Unexpected errors ['aliases_type_statement.py:10:52: error[invalid-type-arguments] Too many type arguments: expected 2, got 3', 'aliases_type_statement.py:10:52: error[invalid-type-form] `...` is not allowed in this context in a type expression']
14+
"""
15+
output = """
16+
aliases_type_statement.py:10:52: error[invalid-type-arguments] Too many type arguments: expected 2, got 3
17+
aliases_type_statement.py:10:52: error[invalid-type-form] `...` is not allowed in this context in a type expression
18+
aliases_type_statement.py:17:1: error[unresolved-attribute] Object of type `TypeAliasType` has no attribute `bit_count`
19+
aliases_type_statement.py:19:1: error[call-non-callable] Object of type `TypeAliasType` is not callable
20+
aliases_type_statement.py:23:7: error[unresolved-attribute] Object of type `TypeAliasType` has no attribute `other_attrib`
21+
aliases_type_statement.py:26:18: error[invalid-base] Invalid class base with type `TypeAliasType`
22+
aliases_type_statement.py:31:22: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | UnionType | tuple[Divergent, ...]`, found `TypeAliasType`
23+
aliases_type_statement.py:37:22: error[invalid-type-form] Function calls are not allowed in type expressions
24+
aliases_type_statement.py:38:22: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
25+
aliases_type_statement.py:39:22: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression
26+
aliases_type_statement.py:39:23: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
27+
aliases_type_statement.py:40:22: error[invalid-type-form] List comprehensions are not allowed in type expressions
28+
aliases_type_statement.py:41:22: error[invalid-type-form] Dict literals are not allowed in type expressions
29+
aliases_type_statement.py:42:22: error[invalid-type-form] Function calls are not allowed in type expressions
30+
aliases_type_statement.py:43:22: error[invalid-type-form] Invalid subscript of object of type `list[<class 'int'>]` in type expression
31+
aliases_type_statement.py:43:28: error[invalid-type-form] Int literals are not allowed in this context in a type expression
32+
aliases_type_statement.py:44:22: error[invalid-type-form] `if` expressions are not allowed in type expressions
33+
aliases_type_statement.py:45:22: error[invalid-type-form] Variable of type `Literal[1]` is not allowed in a type expression
34+
aliases_type_statement.py:46:23: error[invalid-type-form] Boolean literals are not allowed in this context in a type expression
35+
aliases_type_statement.py:47:23: error[invalid-type-form] Int literals are not allowed in this context in a type expression
36+
aliases_type_statement.py:48:23: error[invalid-type-form] Boolean operations are not allowed in type expressions
37+
aliases_type_statement.py:49:23: error[fstring-type-annotation] Type expressions cannot use f-strings
38+
aliases_type_statement.py:62:23: error[unbound-type-variable] Type variable `V` is not bound to any outer generic context
39+
aliases_type_statement.py:67:17: error[unbound-type-variable] Type variable `T1` is not bound to any outer generic context
40+
aliases_type_statement.py:77:27: error[invalid-type-arguments] Type `str` is not assignable to upper bound `int` of type variable `S@RecursiveTypeAlias2`
41+
aliases_type_statement.py:79:32: error[invalid-type-arguments] Type `int` is not assignable to upper bound `str` of type variable `T@RecursiveTypeAlias2`
42+
aliases_type_statement.py:82:1: error[cyclic-type-alias-definition] Cyclic definition of `RecursiveTypeAlias3`
43+
aliases_type_statement.py:88:1: error[cyclic-type-alias-definition] Cyclic definition of `RecursiveTypeAlias6`
44+
aliases_type_statement.py:89:1: error[cyclic-type-alias-definition] Cyclic definition of `RecursiveTypeAlias7`
45+
"""
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
conformance_automated = "Fail"
2+
conformant = "Partial"
3+
notes = """
4+
Does not reject specializing a type parameter in a generic type alias with a type inconsistent with the parameter's upper bound.
5+
Does not reject declaring a type alias with a type variable that is not in scope.
6+
Does not reject declaring a type alias with a non-literal tuple passed to the `type_params` parameter.
7+
Does not reject cyclically defined type aliases.
8+
"""
9+
errors_diff = """
10+
Line 40: Expected 1 errors
11+
Line 43: Expected 1 errors
12+
Line 44: Expected 1 errors
13+
Line 45: Expected 1 errors
14+
Line 46: Expected 1 errors
15+
Line 47: Expected 1 errors
16+
Line 48: Expected 1 errors
17+
"""
18+
output = """
19+
aliases_typealiastype.py:32:7: error[unresolved-attribute] Object of type `TypeAliasType` has no attribute `other_attrib`
20+
aliases_typealiastype.py:52:40: error[invalid-type-form] Function calls are not allowed in type expressions
21+
aliases_typealiastype.py:53:40: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
22+
aliases_typealiastype.py:54:42: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression
23+
aliases_typealiastype.py:54:43: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
24+
aliases_typealiastype.py:55:42: error[invalid-type-form] List comprehensions are not allowed in type expressions
25+
aliases_typealiastype.py:56:42: error[invalid-type-form] Dict literals are not allowed in type expressions
26+
aliases_typealiastype.py:57:42: error[invalid-type-form] Function calls are not allowed in type expressions
27+
aliases_typealiastype.py:58:42: error[invalid-type-form] Invalid subscript of object of type `list[<class 'int'>]` in type expression
28+
aliases_typealiastype.py:58:48: error[invalid-type-form] Int literals are not allowed in this context in a type expression
29+
aliases_typealiastype.py:59:42: error[invalid-type-form] `if` expressions are not allowed in type expressions
30+
aliases_typealiastype.py:60:42: error[invalid-type-form] Variable of type `Literal[3]` is not allowed in a type expression
31+
aliases_typealiastype.py:61:42: error[invalid-type-form] Boolean literals are not allowed in this context in a type expression
32+
aliases_typealiastype.py:62:42: error[invalid-type-form] Int literals are not allowed in this context in a type expression
33+
aliases_typealiastype.py:63:42: error[invalid-type-form] Boolean operations are not allowed in type expressions
34+
aliases_typealiastype.py:64:42: error[invalid-type-form] F-strings are not allowed in type expressions
35+
aliases_typealiastype.py:66:47: error[unresolved-reference] Name `BadAlias21` used when not defined
36+
"""
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
conformance_automated = "Fail"
2+
conformant = "Unsupported"
3+
errors_diff = """
4+
Line 24: Expected 1 errors
5+
Line 28: Expected 1 errors
6+
Line 32: Expected 1 errors
7+
Line 44: Expected 1 errors
8+
"""
9+
output = """
10+
"""

0 commit comments

Comments
 (0)