Skip to content

Commit 226b528

Browse files
authored
Fixed bugs in two of the conformance tests: "generics_basic" and "generics_upper_bound". (#1720)
These tests attempted to validate that type checkers enforced the rule that constraints and upper bounds within a TypedDict definition cannot be parameterized by other type variables (i.e. cannot be generic). The way the tests were written, they weren't actually testing this check. This allowed mypy and pyre (which both fail to catch this condition) to pass the tests. I've updated the test so it properly tests this condition.
1 parent c0f9dec commit 226b528

14 files changed

+149
-121
lines changed
Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
conformant = "Pass"
1+
conformant = "Partial"
2+
notes = """
3+
Does not reject the use of a constraint parameterized by another type variable.
4+
"""
25
output = """
3-
generics_basic.py:36: error: Value of type variable "AnyStr" of "concat" cannot be "Sequence[object]" [type-var]
4-
generics_basic.py:37: error: Value of type variable "AnyStr" of "concat" cannot be "Sequence[object]" [type-var]
5-
generics_basic.py:44: error: TypeVar cannot have only a single constraint [misc]
6-
generics_basic.py:48: error: Type variable "generics_basic.T" is unbound [valid-type]
7-
generics_basic.py:48: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
8-
generics_basic.py:48: note: (Hint: Use "T" in function signature to bind "T" inside a function)
9-
generics_basic.py:59: error: Value of type variable "AnyStr" of "concat" cannot be "Sequence[object]" [type-var]
10-
generics_basic.py:107: error: Duplicate type variables in Generic[...] or Protocol[...] [misc]
11-
generics_basic.py:140: error: Invalid index type "int" for "MyMap1[str, int]"; expected type "str" [index]
12-
generics_basic.py:141: error: Invalid index type "int" for "MyMap2[int, str]"; expected type "str" [index]
13-
generics_basic.py:167: error: Dynamic metaclass not supported for "GenericMetaInstance" [misc]
14-
generics_basic.py:167: error: Type variable "generics_basic.T" is unbound [valid-type]
15-
generics_basic.py:167: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
16-
generics_basic.py:167: note: (Hint: Use "T" in function signature to bind "T" inside a function)
6+
generics_basic.py:40: error: Value of type variable "AnyStr" of "concat" cannot be "Sequence[object]" [type-var]
7+
generics_basic.py:41: error: Value of type variable "AnyStr" of "concat" cannot be "Sequence[object]" [type-var]
8+
generics_basic.py:49: error: TypeVar cannot have only a single constraint [misc]
9+
generics_basic.py:69: error: Value of type variable "AnyStr" of "concat" cannot be "Sequence[object]" [type-var]
10+
generics_basic.py:121: error: Duplicate type variables in Generic[...] or Protocol[...] [misc]
11+
generics_basic.py:157: error: Invalid index type "int" for "MyMap1[str, int]"; expected type "str" [index]
12+
generics_basic.py:158: error: Invalid index type "int" for "MyMap2[int, str]"; expected type "str" [index]
13+
generics_basic.py:191: error: Dynamic metaclass not supported for "GenericMetaInstance" [misc]
14+
generics_basic.py:191: error: Type variable "generics_basic.T" is unbound [valid-type]
15+
generics_basic.py:191: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
16+
generics_basic.py:191: note: (Hint: Use "T" in function signature to bind "T" inside a function)
1717
"""
18-
conformance_automated = "Pass"
18+
conformance_automated = "Fail"
1919
errors_diff = """
20+
Line 55: Expected 1 errors
2021
"""
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
conformant = "Pass"
1+
conformant = "Partial"
2+
notes = """
3+
Does not reject use of type variable within an upper bound.
4+
"""
25
output = """
3-
generics_upper_bound.py:22: error: Type variable "generics_upper_bound.T" is unbound [valid-type]
4-
generics_upper_bound.py:22: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
5-
generics_upper_bound.py:22: note: (Hint: Use "T" in function signature to bind "T" inside a function)
6-
generics_upper_bound.py:41: error: Expression is of type "Collection[int]", not "list[int] | set[int]" [assert-type]
7-
generics_upper_bound.py:48: error: Value of type variable "ST" of "longer" cannot be "int" [type-var]
8-
generics_upper_bound.py:53: error: TypeVar cannot have both values and an upper bound [misc]
6+
generics_upper_bound.py:43: error: Expression is of type "Collection[int]", not "list[int] | set[int]" [assert-type]
7+
generics_upper_bound.py:51: error: Value of type variable "ST" of "longer" cannot be "int" [type-var]
8+
generics_upper_bound.py:56: error: TypeVar cannot have both values and an upper bound [misc]
99
"""
10-
conformance_automated = "Pass"
10+
conformance_automated = "Fail"
1111
errors_diff = """
12+
Line 24: Expected 1 errors
1213
"""

conformance/results/mypy/version.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "mypy 1.9.0"
2-
test_duration = 1.6
2+
test_duration = 1.5
Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
conformant = "Partial"
22
notes = """
33
False positives in examples using constrained type variables.
4+
False negative for constraint parameterized by a type variable.
45
False negative in custom map example.
56
False positive using `iter`.
67
False negative for generic metaclass.
78
"""
89
output = """
9-
generics_basic.py:31:4 Incompatible return type [7]: Expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.
10-
generics_basic.py:31:15 Incompatible parameter type [6]: In call `bytes.__add__`, for 1st positional argument, expected `Union[array[typing.Any], bytearray, bytes, _CData, memoryview, mmap, PickleBuffer]` but got `Variable[AnyStr <: [str, bytes]]`.
11-
generics_basic.py:36:14 Incompatible parameter type [6]: In call `concat`, for 2nd positional argument, expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.
12-
generics_basic.py:37:14 Incompatible parameter type [6]: In call `concat`, for 2nd positional argument, expected `Variable[AnyStr <: [str, bytes]]` but got `str`.
13-
generics_basic.py:44:0 Invalid type [31]: TypeVar can't have a single explicit constraint. Did you mean `bound=str`?
14-
generics_basic.py:48:0 Invalid type [31]: Expression `Variable[BadConstraint2 <: [str, Variable[generics_basic.T]]]` is not a valid type. Type variables cannot contain other type variables in their constraints.
15-
generics_basic.py:59:14 Incompatible parameter type [6]: In call `concat`, for 2nd positional argument, expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.
16-
generics_basic.py:107:0 Duplicate type variables [59]: Duplicate type variable `T` in Generic[...].
17-
generics_basic.py:161:25 Undefined attribute [16]: `typing.Iterator` has no attribute `__getitem__`.
10+
generics_basic.py:34:4 Incompatible return type [7]: Expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.
11+
generics_basic.py:34:15 Incompatible parameter type [6]: In call `bytes.__add__`, for 1st positional argument, expected `Union[array[typing.Any], bytearray, bytes, _CData, memoryview, mmap, PickleBuffer]` but got `Variable[AnyStr <: [str, bytes]]`.
12+
generics_basic.py:40:14 Incompatible parameter type [6]: In call `concat`, for 2nd positional argument, expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.
13+
generics_basic.py:41:14 Incompatible parameter type [6]: In call `concat`, for 2nd positional argument, expected `Variable[AnyStr <: [str, bytes]]` but got `str`.
14+
generics_basic.py:49:0 Invalid type [31]: TypeVar can't have a single explicit constraint. Did you mean `bound=str`?
15+
generics_basic.py:55:57 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T]]` but got `TypeVar`.
16+
generics_basic.py:69:14 Incompatible parameter type [6]: In call `concat`, for 2nd positional argument, expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.
17+
generics_basic.py:121:0 Duplicate type variables [59]: Duplicate type variable `T` in Generic[...].
18+
generics_basic.py:182:25 Undefined attribute [16]: `typing.Iterator` has no attribute `__getitem__`.
1819
"""
1920
conformance_automated = "Fail"
2021
errors_diff = """
21-
Line 140: Expected 1 errors
22-
Line 141: Expected 1 errors
23-
Line 167: Expected 1 errors
24-
Line 31: Unexpected errors ['generics_basic.py:31:4 Incompatible return type [7]: Expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.', 'generics_basic.py:31:15 Incompatible parameter type [6]: In call `bytes.__add__`, for 1st positional argument, expected `Union[array[typing.Any], bytearray, bytes, _CData, memoryview, mmap, PickleBuffer]` but got `Variable[AnyStr <: [str, bytes]]`.']
25-
Line 161: Unexpected errors ['generics_basic.py:161:25 Undefined attribute [16]: `typing.Iterator` has no attribute `__getitem__`.']
22+
Line 157: Expected 1 errors
23+
Line 158: Expected 1 errors
24+
Line 191: Expected 1 errors
25+
Line 34: Unexpected errors ['generics_basic.py:34:4 Incompatible return type [7]: Expected `Variable[AnyStr <: [str, bytes]]` but got `bytes`.', 'generics_basic.py:34:15 Incompatible parameter type [6]: In call `bytes.__add__`, for 1st positional argument, expected `Union[array[typing.Any], bytearray, bytes, _CData, memoryview, mmap, PickleBuffer]` but got `Variable[AnyStr <: [str, bytes]]`.']
26+
Line 182: Unexpected errors ['generics_basic.py:182:25 Undefined attribute [16]: `typing.Iterator` has no attribute `__getitem__`.']
2627
"""

conformance/results/pyre/generics_upper_bound.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ notes = """
33
Does not reject use of upper bound with constrained TypeVar.
44
"""
55
output = """
6-
generics_upper_bound.py:22:0 Invalid type [31]: Expression `Variable[T_Bad1 (bound to typing.List[Variable[generics_upper_bound.T]])]` is not a valid type. Type variables cannot contain other type variables in their constraints.
7-
generics_upper_bound.py:48:7 Incompatible parameter type [6]: In call `longer`, for 1st positional argument, expected `Variable[ST (bound to Sized)]` but got `int`.
8-
generics_upper_bound.py:48:10 Incompatible parameter type [6]: In call `longer`, for 2nd positional argument, expected `Variable[ST (bound to Sized)]` but got `int`.
6+
generics_upper_bound.py:24:42 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T]]` but got `TypeVar`.
7+
generics_upper_bound.py:51:7 Incompatible parameter type [6]: In call `longer`, for 1st positional argument, expected `Variable[ST (bound to Sized)]` but got `int`.
8+
generics_upper_bound.py:51:10 Incompatible parameter type [6]: In call `longer`, for 2nd positional argument, expected `Variable[ST (bound to Sized)]` but got `int`.
99
"""
1010
conformance_automated = "Fail"
1111
errors_diff = """
12-
Line 53: Expected 1 errors
12+
Line 56: Expected 1 errors
1313
"""

conformance/results/pyre/version.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "pyre 0.9.19"
2-
test_duration = 4.0
2+
test_duration = 3.2

conformance/results/pyright/generics_basic.toml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
conformant = "Pass"
22
output = """
3-
generics_basic.py:36:15 - error: Argument of type "bytes" cannot be assigned to parameter "y" of type "AnyStr@concat" in function "concat"
3+
generics_basic.py:40:15 - error: Argument of type "bytes" cannot be assigned to parameter "y" of type "AnyStr@concat" in function "concat"
44
  "bytes" is incompatible with "str" (reportArgumentType)
5-
generics_basic.py:37:15 - error: Argument of type "str" cannot be assigned to parameter "y" of type "AnyStr@concat" in function "concat"
5+
generics_basic.py:41:15 - error: Argument of type "str" cannot be assigned to parameter "y" of type "AnyStr@concat" in function "concat"
66
  "str" is incompatible with "bytes" (reportArgumentType)
7-
generics_basic.py:44:44 - error: TypeVar must have at least two constrained types (reportGeneralTypeIssues)
8-
generics_basic.py:48:49 - error: Type variable "T" has no meaning in this context (reportGeneralTypeIssues)
9-
generics_basic.py:48:49 - error: TypeVar constraint type cannot be generic
10-
generics_basic.py:59:15 - error: Argument of type "bytes" cannot be assigned to parameter "y" of type "AnyStr@concat" in function "concat"
7+
generics_basic.py:49:44 - error: TypeVar must have at least two constrained types (reportGeneralTypeIssues)
8+
generics_basic.py:55:53 - error: TypeVar constraint type cannot be generic
9+
generics_basic.py:69:15 - error: Argument of type "bytes" cannot be assigned to parameter "y" of type "AnyStr@concat" in function "concat"
1110
  "bytes" is incompatible with "str" (reportArgumentType)
12-
generics_basic.py:107:24 - error: Type arguments for "Generic" must be unique
13-
generics_basic.py:140:5 - error: Argument of type "Literal[0]" cannot be assigned to parameter "key" of type "str" in function "__getitem__"
11+
generics_basic.py:121:24 - error: Type arguments for "Generic" must be unique
12+
generics_basic.py:157:5 - error: Argument of type "Literal[0]" cannot be assigned to parameter "key" of type "str" in function "__getitem__"
1413
  "Literal[0]" is incompatible with "str" (reportArgumentType)
15-
generics_basic.py:141:5 - error: Argument of type "Literal[0]" cannot be assigned to parameter "key" of type "str" in function "__getitem__"
14+
generics_basic.py:158:5 - error: Argument of type "Literal[0]" cannot be assigned to parameter "key" of type "str" in function "__getitem__"
1615
  "Literal[0]" is incompatible with "str" (reportArgumentType)
17-
generics_basic.py:167:37 - error: Metaclass cannot be generic (reportGeneralTypeIssues)
16+
generics_basic.py:191:37 - error: Metaclass cannot be generic (reportGeneralTypeIssues)
1817
"""
1918
conformance_automated = "Pass"
2019
errors_diff = """

conformance/results/pyright/generics_upper_bound.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
conformant = "Pass"
22
output = """
3-
generics_upper_bound.py:22:34 - error: TypeVar bound type cannot be generic
4-
generics_upper_bound.py:22:39 - error: Type variable "T" has no meaning in this context (reportGeneralTypeIssues)
5-
generics_upper_bound.py:48:8 - error: Argument of type "Literal[3]" cannot be assigned to parameter "x" of type "ST@longer" in function "longer"
3+
generics_upper_bound.py:24:38 - error: TypeVar bound type cannot be generic
4+
generics_upper_bound.py:51:8 - error: Argument of type "Literal[3]" cannot be assigned to parameter "x" of type "ST@longer" in function "longer"
65
  Type "Literal[3]" is incompatible with type "Sized"
76
    "Literal[3]" is incompatible with protocol "Sized"
87
      "__len__" is not present (reportArgumentType)
9-
generics_upper_bound.py:48:11 - error: Argument of type "Literal[3]" cannot be assigned to parameter "y" of type "ST@longer" in function "longer"
8+
generics_upper_bound.py:51:11 - error: Argument of type "Literal[3]" cannot be assigned to parameter "y" of type "ST@longer" in function "longer"
109
  Type "Literal[3]" is incompatible with type "Sized"
1110
    "Literal[3]" is incompatible with protocol "Sized"
1211
      "__len__" is not present (reportArgumentType)
13-
generics_upper_bound.py:53:44 - error: TypeVar cannot be both bound and constrained
12+
generics_upper_bound.py:56:44 - error: TypeVar cannot be both bound and constrained
1413
"""
1514
conformance_automated = "Pass"
1615
errors_diff = """

conformance/results/pytype/generics_basic.toml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,27 @@ False positives in examples using constrained type variables.
44
False negative for generic metaclass.
55
"""
66
output = """
7-
File "generics_basic.py", line 31, in concat: bad return type [bad-return-type]
7+
File "generics_basic.py", line 34, in concat: bad return type [bad-return-type]
88
Called from (traceback):
9-
line 57, in test_concat_subtype
10-
File "generics_basic.py", line 36, in test_concat: Function concat was called with the wrong arguments [wrong-arg-types]
11-
File "generics_basic.py", line 37, in test_concat: Function concat was called with the wrong arguments [wrong-arg-types]
12-
File "generics_basic.py", line 44, in <module>: Invalid TypeVar: the number of constraints must be 0 or more than 1 [invalid-typevar]
13-
File "generics_basic.py", line 48, in <module>: Invalid TypeVar: constraint cannot contain TypeVars [invalid-typevar]
14-
File "generics_basic.py", line 57, in test_concat_subtype: MyStr [assert-type]
15-
File "generics_basic.py", line 58, in test_concat_subtype: Function concat was called with the wrong arguments [wrong-arg-types]
16-
File "generics_basic.py", line 58, in test_concat_subtype: Any [assert-type]
17-
File "generics_basic.py", line 59, in test_concat_subtype: Function concat was called with the wrong arguments [wrong-arg-types]
18-
File "generics_basic.py", line 107, in <module>: Invalid type annotation 'Generic' [invalid-annotation]
19-
File "generics_basic.py", line 140, in test_my_map: unsupported operand type(s) for item retrieval: MyMap1[str, int] and int [unsupported-operands]
20-
File "generics_basic.py", line 141, in test_my_map: unsupported operand type(s) for item retrieval: MyMap2[int, str] and int [unsupported-operands]
21-
File "generics_basic.py", line 161, in test_my_iterable_any: Iterator[nothing] [assert-type]
9+
line 67, in test_concat_subtype
10+
File "generics_basic.py", line 40, in test_concat: Function concat was called with the wrong arguments [wrong-arg-types]
11+
File "generics_basic.py", line 41, in test_concat: Function concat was called with the wrong arguments [wrong-arg-types]
12+
File "generics_basic.py", line 49, in <module>: Invalid TypeVar: the number of constraints must be 0 or more than 1 [invalid-typevar]
13+
File "generics_basic.py", line 55, in Test: Invalid TypeVar: constraint cannot contain TypeVars [invalid-typevar]
14+
File "generics_basic.py", line 67, in test_concat_subtype: MyStr [assert-type]
15+
File "generics_basic.py", line 68, in test_concat_subtype: Function concat was called with the wrong arguments [wrong-arg-types]
16+
File "generics_basic.py", line 68, in test_concat_subtype: Any [assert-type]
17+
File "generics_basic.py", line 69, in test_concat_subtype: Function concat was called with the wrong arguments [wrong-arg-types]
18+
File "generics_basic.py", line 121, in <module>: Invalid type annotation 'Generic' [invalid-annotation]
19+
File "generics_basic.py", line 157, in test_my_map: unsupported operand type(s) for item retrieval: MyMap1[str, int] and int [unsupported-operands]
20+
File "generics_basic.py", line 158, in test_my_map: unsupported operand type(s) for item retrieval: MyMap2[int, str] and int [unsupported-operands]
21+
File "generics_basic.py", line 182, in test_my_iterable_any: Iterator[nothing] [assert-type]
2222
"""
2323
conformance_automated = "Fail"
2424
errors_diff = """
25-
Line 167: Expected 1 errors
26-
Line 31: Unexpected errors ['File "generics_basic.py", line 31, in concat: bad return type [bad-return-type]']
27-
Line 57: Unexpected errors ['File "generics_basic.py", line 57, in test_concat_subtype: MyStr [assert-type]']
28-
Line 58: Unexpected errors ['File "generics_basic.py", line 58, in test_concat_subtype: Function concat was called with the wrong arguments [wrong-arg-types]', 'File "generics_basic.py", line 58, in test_concat_subtype: Any [assert-type]']
29-
Line 161: Unexpected errors ['File "generics_basic.py", line 161, in test_my_iterable_any: Iterator[nothing] [assert-type]']
25+
Line 191: Expected 1 errors
26+
Line 34: Unexpected errors ['File "generics_basic.py", line 34, in concat: bad return type [bad-return-type]']
27+
Line 67: Unexpected errors ['File "generics_basic.py", line 67, in test_concat_subtype: MyStr [assert-type]']
28+
Line 68: Unexpected errors ['File "generics_basic.py", line 68, in test_concat_subtype: Function concat was called with the wrong arguments [wrong-arg-types]', 'File "generics_basic.py", line 68, in test_concat_subtype: Any [assert-type]']
29+
Line 182: Unexpected errors ['File "generics_basic.py", line 182, in test_my_iterable_any: Iterator[nothing] [assert-type]']
3030
"""

conformance/results/pytype/generics_upper_bound.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ notes = """
33
Does not properly support assert_type.
44
"""
55
output = """
6-
File "generics_upper_bound.py", line 22, in <module>: Invalid TypeVar: bound cannot contain TypeVars [invalid-typevar]
7-
File "generics_upper_bound.py", line 35, in <module>: list [assert-type]
8-
File "generics_upper_bound.py", line 36, in <module>: set [assert-type]
9-
File "generics_upper_bound.py", line 41, in <module>: Union[list, set] [assert-type]
10-
File "generics_upper_bound.py", line 48, in <module>: Function longer was called with the wrong arguments [wrong-arg-types]
11-
File "generics_upper_bound.py", line 53, in <module>: Invalid TypeVar: constraints and a bound are mutually exclusive [invalid-typevar]
6+
File "generics_upper_bound.py", line 24, in Test: Invalid TypeVar: bound cannot contain TypeVars [invalid-typevar]
7+
File "generics_upper_bound.py", line 37, in <module>: list [assert-type]
8+
File "generics_upper_bound.py", line 38, in <module>: set [assert-type]
9+
File "generics_upper_bound.py", line 43, in <module>: Union[list, set] [assert-type]
10+
File "generics_upper_bound.py", line 51, in <module>: Function longer was called with the wrong arguments [wrong-arg-types]
11+
File "generics_upper_bound.py", line 56, in <module>: Invalid TypeVar: constraints and a bound are mutually exclusive [invalid-typevar]
1212
"""
1313
conformance_automated = "Fail"
1414
errors_diff = """
15-
Line 35: Unexpected errors ['File "generics_upper_bound.py", line 35, in <module>: list [assert-type]']
16-
Line 36: Unexpected errors ['File "generics_upper_bound.py", line 36, in <module>: set [assert-type]']
15+
Line 37: Unexpected errors ['File "generics_upper_bound.py", line 37, in <module>: list [assert-type]']
16+
Line 38: Unexpected errors ['File "generics_upper_bound.py", line 38, in <module>: set [assert-type]']
1717
"""

0 commit comments

Comments
 (0)