diff --git a/conformance/results/mypy/annotations_coroutines.toml b/conformance/results/mypy/annotations_coroutines.toml new file mode 100644 index 000000000..2146548eb --- /dev/null +++ b/conformance/results/mypy/annotations_coroutines.toml @@ -0,0 +1,3 @@ +conformant = "Pass" +output = """ +""" diff --git a/conformance/results/mypy/annotations_forward_refs.toml b/conformance/results/mypy/annotations_forward_refs.toml new file mode 100644 index 000000000..34a604c35 --- /dev/null +++ b/conformance/results/mypy/annotations_forward_refs.toml @@ -0,0 +1,31 @@ +conformant = "Partial" +notes = """ +Does not report error for a forward reference that is not enclosed in quotes. +Does not report error for use of quoted type with "|" operator (runtime error). +Incorrectly generates error for quoted type defined in class scope. +""" +output = """ +annotations_forward_refs.py:41: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:42: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:43: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:44: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:45: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:46: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:47: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:48: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:49: error: Variable "annotations_forward_refs.var1" is not valid as a type [valid-type] +annotations_forward_refs.py:49: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +annotations_forward_refs.py:50: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:51: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:52: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:53: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:54: error: Invalid type comment or annotation [valid-type] +annotations_forward_refs.py:55: error: Module "types" is not valid as a type [valid-type] +annotations_forward_refs.py:55: note: Perhaps you meant to use a protocol matching the module structure? +annotations_forward_refs.py:80: error: Name "ClassF" is not defined [name-defined] +annotations_forward_refs.py:87: error: Function "annotations_forward_refs.ClassD.int" is not valid as a type [valid-type] +annotations_forward_refs.py:87: note: Perhaps you need "Callable[...]" or a callback protocol? +annotations_forward_refs.py:89: error: Function "annotations_forward_refs.ClassD.int" is not valid as a type [valid-type] +annotations_forward_refs.py:89: note: Perhaps you need "Callable[...]" or a callback protocol? +annotations_forward_refs.py:93: error: Expression is of type int?, not "int" [assert-type] +""" diff --git a/conformance/results/mypy/annotations_generators.toml b/conformance/results/mypy/annotations_generators.toml new file mode 100644 index 000000000..5d0520f8a --- /dev/null +++ b/conformance/results/mypy/annotations_generators.toml @@ -0,0 +1,15 @@ +conformant = "Partial" +notes = """ +Does not report incompatible Generator type in `yield from` statement. +""" +output = """ +annotations_generators.py:50: error: Missing return statement [return] +annotations_generators.py:53: error: Incompatible return value type (got "bool", expected "C") [return-value] +annotations_generators.py:56: error: Incompatible types in "yield" (actual type "int", expected type "A") [misc] +annotations_generators.py:65: error: Incompatible types in "yield" (actual type "int", expected type "A") [misc] +annotations_generators.py:74: error: Incompatible types in "yield" (actual type "B", expected type "A") [misc] +annotations_generators.py:85: error: The return type of a generator function should be "Generator" or one of its supertypes [misc] +annotations_generators.py:90: error: The return type of an async generator function should be "AsyncGenerator" or one of its supertypes [misc] +annotations_generators.py:117: error: Incompatible types in "yield from" (actual type "A", expected type "B") [misc] +annotations_generators.py:118: error: Incompatible types in "yield from" (actual type "int", expected type "B") [misc] +""" diff --git a/conformance/results/mypy/annotations_methods.toml b/conformance/results/mypy/annotations_methods.toml new file mode 100644 index 000000000..2146548eb --- /dev/null +++ b/conformance/results/mypy/annotations_methods.toml @@ -0,0 +1,3 @@ +conformant = "Pass" +output = """ +""" diff --git a/conformance/results/mypy/annotations_typeexpr.toml b/conformance/results/mypy/annotations_typeexpr.toml index b5caec86b..501db9cb4 100644 --- a/conformance/results/mypy/annotations_typeexpr.toml +++ b/conformance/results/mypy/annotations_typeexpr.toml @@ -1,20 +1,22 @@ conformant = "Pass" output = """ -annotations_typeexpr.py:77: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:77: note: Suggestion: use eval[...] instead of eval(...) -annotations_typeexpr.py:78: error: Bracketed expression "[...]" is not valid as a type [valid-type] -annotations_typeexpr.py:79: error: Syntax error in type annotation [syntax] -annotations_typeexpr.py:79: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) -annotations_typeexpr.py:80: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:81: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:82: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:83: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:84: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:85: error: Variable "annotations_typeexpr.var1" is not valid as a type [valid-type] -annotations_typeexpr.py:85: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -annotations_typeexpr.py:86: error: Invalid type: try using Literal[True] instead? [valid-type] -annotations_typeexpr.py:87: error: Invalid type: try using Literal[1] instead? [valid-type] -annotations_typeexpr.py:88: error: Invalid type: try using Literal[-1] instead? [valid-type] -annotations_typeexpr.py:89: error: Invalid type comment or annotation [valid-type] -annotations_typeexpr.py:90: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:88: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:88: note: Suggestion: use eval[...] instead of eval(...) +annotations_typeexpr.py:89: error: Bracketed expression "[...]" is not valid as a type [valid-type] +annotations_typeexpr.py:90: error: Syntax error in type annotation [syntax] +annotations_typeexpr.py:90: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) +annotations_typeexpr.py:91: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:92: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:93: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:94: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:95: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:96: error: Variable "annotations_typeexpr.var1" is not valid as a type [valid-type] +annotations_typeexpr.py:96: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +annotations_typeexpr.py:97: error: Invalid type: try using Literal[True] instead? [valid-type] +annotations_typeexpr.py:98: error: Invalid type: try using Literal[1] instead? [valid-type] +annotations_typeexpr.py:99: error: Invalid type: try using Literal[-1] instead? [valid-type] +annotations_typeexpr.py:100: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:101: error: Invalid type comment or annotation [valid-type] +annotations_typeexpr.py:102: error: Module "types" is not valid as a type [valid-type] +annotations_typeexpr.py:102: note: Perhaps you meant to use a protocol matching the module structure? """ diff --git a/conformance/results/mypy/protocols_explicit.toml b/conformance/results/mypy/protocols_explicit.toml index 7c43076c8..388ddbe74 100644 --- a/conformance/results/mypy/protocols_explicit.toml +++ b/conformance/results/mypy/protocols_explicit.toml @@ -1,6 +1,6 @@ conformant = "Pass" notes = """ -Does not report unimplemented attributes for class that explicitly derives from protocol until is instantiated. +Does not report unimplemented attributes for class that explicitly derives from protocol until it is instantiated. """ output = """ protocols_explicit.py:27: error: Call to abstract method "draw" of "PColor" with trivial body via super() is unsafe [safe-super] diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml index b7d9a9d4b..77d2d0487 100644 --- a/conformance/results/mypy/version.toml +++ b/conformance/results/mypy/version.toml @@ -1,2 +1,2 @@ version = "mypy 1.8.0" -test_duration = 0.3901679515838623 +test_duration = 0.5739729404449463 diff --git a/conformance/results/pyre/annotations_coroutines.toml b/conformance/results/pyre/annotations_coroutines.toml new file mode 100644 index 000000000..b04dee644 --- /dev/null +++ b/conformance/results/pyre/annotations_coroutines.toml @@ -0,0 +1,7 @@ +conformant = "Partial" +notes = """ +Does not evaluate correct type for async function. +""" +output = """ +annotations_coroutines.py:19:45 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Tuple[Type[Variable[_T_co](covariant)], Type[Variable[_T_contra](contravariant)], Type[Variable[_V_co](covariant)]]` but got `Tuple[object, object, Type[str]]`. +""" diff --git a/conformance/results/pyre/annotations_forward_refs.toml b/conformance/results/pyre/annotations_forward_refs.toml new file mode 100644 index 000000000..3a88c0b03 --- /dev/null +++ b/conformance/results/pyre/annotations_forward_refs.toml @@ -0,0 +1,28 @@ +conformant = "Partial" +notes = """ +Does not report error for a forward reference that is not enclosed in quotes. +Does not report error for use of quoted type with "|" operator (runtime error). +Does not reject f-string in quoted type annotation. +Incorrectly generates error for quoted type defined in class scope. +Does not generate error for unquoted type defined in class scope. +""" +output = """ +annotations_forward_refs.py:19:25 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T]]` but got `UnionType`. +annotations_forward_refs.py:41:8 Undefined or invalid type [11]: Annotation `eval(.join(map(chr, [105, 110, 116])))` is not defined as a type. +annotations_forward_refs.py:42:8 Invalid type [31]: Expression `"[int, str]"` is not a valid type. +annotations_forward_refs.py:43:8 Invalid type [31]: Expression `"(int, str)"` is not a valid type. +annotations_forward_refs.py:44:8 Undefined or invalid type [11]: Annotation `comprehension(int for generators(generator($target$i in range(1) if )))` is not defined as a type. +annotations_forward_refs.py:45:8 Invalid type [31]: Expression `"{ }"` is not a valid type. +annotations_forward_refs.py:46:8 Undefined or invalid type [11]: Annotation `lambda () (int)()` is not defined as a type. +annotations_forward_refs.py:47:8 Invalid type [31]: Expression `[int][0]` is not a valid type. +annotations_forward_refs.py:48:8 Invalid type [31]: Expression `"int if 1 < 3 else str"` is not a valid type. +annotations_forward_refs.py:49:8 Undefined or invalid type [11]: Annotation `var1` is not defined as a type. +annotations_forward_refs.py:50:9 Invalid type [31]: Expression `"True"` is not a valid type. +annotations_forward_refs.py:51:9 Invalid type [31]: Expression `"1"` is not a valid type. +annotations_forward_refs.py:52:9 Invalid type [31]: Expression `"-1"` is not a valid type. +annotations_forward_refs.py:53:9 Invalid type [31]: Expression `"int or str"` is not a valid type. +annotations_forward_refs.py:55:9 Undefined or invalid type [11]: Annotation `types` is not defined as a type. +annotations_forward_refs.py:77:0 Uninitialized attribute [13]: Attribute `ClassC` is declared in class `ClassD` to have type `ClassC` but is never initialized. +annotations_forward_refs.py:80:12 Undefined or invalid type [11]: Annotation `ClassF` is not defined as a type. +annotations_forward_refs.py:87:7 Undefined or invalid type [11]: Annotation `ClassD.int` is not defined as a type. +""" diff --git a/conformance/results/pyre/annotations_generators.toml b/conformance/results/pyre/annotations_generators.toml new file mode 100644 index 000000000..eb4111820 --- /dev/null +++ b/conformance/results/pyre/annotations_generators.toml @@ -0,0 +1,20 @@ +conformant = "Partial" +notes = """ +Does not report invalid return type for generator when function implicitly returns None. +Incorrectly evaluates type of call to async generator. +""" +output = """ +annotations_generators.py:53:8 Incompatible return type [7]: Expected `Generator[A, B, C]` but got `Generator[typing.Any, typing.Any, bool]`. +annotations_generators.py:56:8 Incompatible return type [7]: Expected `Generator[A, B, C]` but got `Generator[int, typing.Any, typing.Any]`. +annotations_generators.py:65:8 Incompatible return type [7]: Expected `Generator[A, int, typing.Any]` but got `Generator[int, typing.Any, typing.Any]`. +annotations_generators.py:74:4 Incompatible return type [7]: Expected `Iterator[A]` but got `Generator[B, typing.Any, typing.Any]`. +annotations_generators.py:86:4 Incompatible return type [7]: Expected `int` but got `Generator[None, typing.Any, typing.Any]`. +annotations_generators.py:87:4 Incompatible return type [7]: Expected `int` but got `Generator[typing.Any, typing.Any, int]`. +annotations_generators.py:90:0 Incompatible async generator return type [57]: Expected return annotation to be AsyncGenerator or a superclass but got `int`. +annotations_generators.py:91:4 Incompatible return type [7]: Expected `int` but got `AsyncGenerator[None, typing.Any]`. +annotations_generators.py:117:4 Incompatible return type [7]: Expected `Iterator[B]` but got `Generator[A, None, typing.Any]`. +annotations_generators.py:118:4 Incompatible return type [7]: Expected `Iterator[B]` but got `Generator[int, None, typing.Any]`. +annotations_generators.py:134:4 Incompatible return type [7]: Expected `Generator[None, str, None]` but got `Generator[None, int, typing.Any]`. +annotations_generators.py:166:35 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Tuple[Type[Variable[_T_co](covariant)], Type[Variable[_T_contra](contravariant)]]` but got `Tuple[Type[str], None]`. +annotations_generators.py:173:35 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Tuple[Type[Variable[_T_co](covariant)], Type[Variable[_T_contra](contravariant)]]` but got `Tuple[Type[str], None]`. +""" diff --git a/conformance/results/pyre/annotations_methods.toml b/conformance/results/pyre/annotations_methods.toml new file mode 100644 index 000000000..2146548eb --- /dev/null +++ b/conformance/results/pyre/annotations_methods.toml @@ -0,0 +1,3 @@ +conformant = "Pass" +output = """ +""" diff --git a/conformance/results/pyre/annotations_typeexpr.toml b/conformance/results/pyre/annotations_typeexpr.toml index 86bc19108..c1cb1b406 100644 --- a/conformance/results/pyre/annotations_typeexpr.toml +++ b/conformance/results/pyre/annotations_typeexpr.toml @@ -1,19 +1,20 @@ conformant = "Pass" output = """ -annotations_typeexpr.py:65:26 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T]]` but got `object`. -annotations_typeexpr.py:67:27 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T_co](covariant)]` but got `Tuple[object, typing.Any]`. -annotations_typeexpr.py:77:8 Invalid type [31]: Expression `eval("".join(map(chr, [105, 110, 116])))` is not a valid type. -annotations_typeexpr.py:78:8 Invalid type [31]: Expression `[int, str]` is not a valid type. -annotations_typeexpr.py:79:8 Invalid type [31]: Expression `(int, str)` is not a valid type. -annotations_typeexpr.py:80:8 Invalid type [31]: Expression `comprehension(int for generators(generator($target$i in range(1) if )))` is not a valid type. -annotations_typeexpr.py:81:8 Invalid type [31]: Expression `{ }` is not a valid type. -annotations_typeexpr.py:82:8 Invalid type [31]: Expression `lambda () (int)()` is not a valid type. -annotations_typeexpr.py:83:8 Invalid type [31]: Expression `[int][0]` is not a valid type. -annotations_typeexpr.py:84:8 Invalid type [31]: Expression `int if 1 < 3 else str` is not a valid type. -annotations_typeexpr.py:85:8 Undefined or invalid type [11]: Annotation `var1` is not defined as a type. -annotations_typeexpr.py:86:9 Invalid type [31]: Expression `True` is not a valid type. -annotations_typeexpr.py:87:9 Invalid type [31]: Expression `1` is not a valid type. -annotations_typeexpr.py:88:9 Invalid type [31]: Expression `-1` is not a valid type. -annotations_typeexpr.py:89:9 Invalid type [31]: Expression `int or str` is not a valid type. -annotations_typeexpr.py:90:9 Invalid type [31]: Expression `"int"` is not a valid type. +annotations_typeexpr.py:75:26 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T]]` but got `object`. +annotations_typeexpr.py:77:27 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T_co](covariant)]` but got `Tuple[object, typing.Any]`. +annotations_typeexpr.py:88:8 Invalid type [31]: Expression `eval("".join(map(chr, [105, 110, 116])))` is not a valid type. +annotations_typeexpr.py:89:8 Invalid type [31]: Expression `[int, str]` is not a valid type. +annotations_typeexpr.py:90:8 Invalid type [31]: Expression `(int, str)` is not a valid type. +annotations_typeexpr.py:91:8 Invalid type [31]: Expression `comprehension(int for generators(generator($target$i in range(1) if )))` is not a valid type. +annotations_typeexpr.py:92:8 Invalid type [31]: Expression `{ }` is not a valid type. +annotations_typeexpr.py:93:8 Invalid type [31]: Expression `lambda () (int)()` is not a valid type. +annotations_typeexpr.py:94:8 Invalid type [31]: Expression `[int][0]` is not a valid type. +annotations_typeexpr.py:95:8 Invalid type [31]: Expression `int if 1 < 3 else str` is not a valid type. +annotations_typeexpr.py:96:8 Undefined or invalid type [11]: Annotation `var1` is not defined as a type. +annotations_typeexpr.py:97:9 Invalid type [31]: Expression `True` is not a valid type. +annotations_typeexpr.py:98:9 Invalid type [31]: Expression `1` is not a valid type. +annotations_typeexpr.py:99:9 Invalid type [31]: Expression `-1` is not a valid type. +annotations_typeexpr.py:100:9 Invalid type [31]: Expression `int or str` is not a valid type. +annotations_typeexpr.py:101:9 Invalid type [31]: Expression `"int"` is not a valid type. +annotations_typeexpr.py:102:9 Undefined or invalid type [11]: Annotation `types` is not defined as a type. """ diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml index 80d7d0ee9..6280c9e57 100644 --- a/conformance/results/pyre/version.toml +++ b/conformance/results/pyre/version.toml @@ -1,2 +1,2 @@ version = "pyre 0.9.19" -test_duration = 1.8171961307525635 +test_duration = 1.835569143295288 diff --git a/conformance/results/pyright/annotations_coroutines.toml b/conformance/results/pyright/annotations_coroutines.toml new file mode 100644 index 000000000..2146548eb --- /dev/null +++ b/conformance/results/pyright/annotations_coroutines.toml @@ -0,0 +1,3 @@ +conformant = "Pass" +output = """ +""" diff --git a/conformance/results/pyright/annotations_forward_refs.toml b/conformance/results/pyright/annotations_forward_refs.toml new file mode 100644 index 000000000..1ace3b6bc --- /dev/null +++ b/conformance/results/pyright/annotations_forward_refs.toml @@ -0,0 +1,37 @@ +conformant = "Pass" +output = """ +annotations_forward_refs.py:22:7 - error: "ClassA" is not defined (reportUndefinedVariable) +annotations_forward_refs.py:23:12 - error: "ClassA" is not defined (reportUndefinedVariable) +annotations_forward_refs.py:24:7 - error: Union syntax cannot be used with string operand; use quotes around entire expression (reportGeneralTypeIssues) +annotations_forward_refs.py:25:13 - error: Union syntax cannot be used with string operand; use quotes around entire expression (reportGeneralTypeIssues) +annotations_forward_refs.py:41:9 - error: Expected type but received a string literal (reportGeneralTypeIssues) +annotations_forward_refs.py:42:10 - error: List expression not allowed in type annotation +  Use List[T] to indicate a list type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) +annotations_forward_refs.py:42:10 - error: Expected type expression but received "list[Unknown]" (reportGeneralTypeIssues) +annotations_forward_refs.py:43:10 - error: Tuple expression not allowed in type annotation +  Use Tuple[T1, ..., Tn] to indicate a tuple type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) +annotations_forward_refs.py:44:10 - error: List expression not allowed in type annotation +  Use List[T] to indicate a list type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) +annotations_forward_refs.py:44:10 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) +annotations_forward_refs.py:45:10 - error: Dictionary expression not allowed in type annotation +  Use Dict[T1, T2] to indicate a dictionary type (reportGeneralTypeIssues) +annotations_forward_refs.py:45:10 - error: Expected type expression but received "dict[Unknown, Unknown]" (reportGeneralTypeIssues) +annotations_forward_refs.py:46:10 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +annotations_forward_refs.py:47:10 - error: List expression not allowed in type annotation +  Use List[T] to indicate a list type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) +annotations_forward_refs.py:47:10 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) +annotations_forward_refs.py:48:10 - error: Ternary expression not allowed in type annotation +annotations_forward_refs.py:49:10 - error: Variable not allowed in type expression (reportGeneralTypeIssues) +annotations_forward_refs.py:50:11 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) +annotations_forward_refs.py:51:11 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) +annotations_forward_refs.py:52:11 - error: Unary operator not allowed in type annotation +annotations_forward_refs.py:53:11 - error: Binary operator not allowed in type annotation +annotations_forward_refs.py:54:11 - error: Expected expression +annotations_forward_refs.py:54:11 - error: Tuple expression not allowed in type annotation +  Use Tuple[T1, ..., Tn] to indicate a tuple type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) +annotations_forward_refs.py:55:10 - error: Module cannot be used as a type (reportGeneralTypeIssues) +annotations_forward_refs.py:66:26 - error: "ClassB" is not defined (reportUndefinedVariable) +annotations_forward_refs.py:80:14 - error: Type of "ClassF" could not be determined because it refers to itself (reportGeneralTypeIssues) +annotations_forward_refs.py:80:14 - error: Variable not allowed in type expression (reportGeneralTypeIssues) +annotations_forward_refs.py:89:8 - error: Expected type expression but received "(self: Self@ClassD) -> None" (reportGeneralTypeIssues) +""" diff --git a/conformance/results/pyright/annotations_generators.toml b/conformance/results/pyright/annotations_generators.toml new file mode 100644 index 000000000..91fcdd77f --- /dev/null +++ b/conformance/results/pyright/annotations_generators.toml @@ -0,0 +1,33 @@ +conformant = "Pass" +output = """ +annotations_generators.py:53:16 - error: Expression of type "Literal[False]" cannot be assigned to return type "C" +  "Literal[False]" is incompatible with "C" (reportGeneralTypeIssues) +annotations_generators.py:56:15 - error: Return type of generator function must be compatible with "Generator[Literal[3], Any, Any]" +  "Literal[3]" is incompatible with "A" (reportGeneralTypeIssues) +annotations_generators.py:50:21 - error: Function with declared return type "C" must return value on all code paths +  "None" is incompatible with "C" (reportGeneralTypeIssues) +annotations_generators.py:65:15 - error: Return type of generator function must be compatible with "Generator[Literal[3], Any, Any]" +  "Literal[3]" is incompatible with "A" (reportGeneralTypeIssues) +annotations_generators.py:74:11 - error: Return type of generator function must be compatible with "Generator[B, Any, Any]" +  "B" is incompatible with "A" (reportGeneralTypeIssues) +annotations_generators.py:86:11 - error: Return type of generator function must be compatible with "Generator[None, Any, Any]" +  "Generator[None, Unknown, Unknown]" is incompatible with "int" (reportGeneralTypeIssues) +annotations_generators.py:85:21 - error: Return type of generator function must be compatible with "Generator[Any, Any, Any]" +  "Generator[Any, Any, Any]" is incompatible with "int" (reportGeneralTypeIssues) +annotations_generators.py:91:11 - error: Return type of async generator function must be compatible with "AsyncGenerator[None, Any]" +  "AsyncGenerator[None, Unknown, Unknown]" is incompatible with "int" (reportGeneralTypeIssues) +annotations_generators.py:90:27 - error: Return type of async generator function must be compatible with "AsyncGenerator[Any, Any]" +  "AsyncGenerator[Any, Any, Any]" is incompatible with "int" (reportGeneralTypeIssues) +annotations_generators.py:117:16 - error: Return type of generator function must be compatible with "Generator[A, Any, Any]" +  "Generator[A, Unknown, Unknown]" is incompatible with "Iterator[B]" +    Type parameter "_T_co@Iterator" is covariant, but "A" is not a subtype of "B" +      "A" is incompatible with "B" (reportGeneralTypeIssues) +annotations_generators.py:118:16 - error: Return type of generator function must be compatible with "Generator[int, Any, Any]" +  "Generator[int, Unknown, Unknown]" is incompatible with "Iterator[B]" +    Type parameter "_T_co@Iterator" is covariant, but "int" is not a subtype of "B" +      "int" is incompatible with "B" (reportGeneralTypeIssues) +annotations_generators.py:134:16 - error: Return type of generator function must be compatible with "Generator[None, Any, Any]" +  "Generator[None, int, Unknown]" is incompatible with "Generator[None, str, None]" +    Type parameter "_SendT_contra@Generator" is contravariant, but "int" is not a supertype of "str" +      "str" is incompatible with "int" (reportGeneralTypeIssues) +""" diff --git a/conformance/results/pyright/annotations_methods.toml b/conformance/results/pyright/annotations_methods.toml new file mode 100644 index 000000000..2146548eb --- /dev/null +++ b/conformance/results/pyright/annotations_methods.toml @@ -0,0 +1,3 @@ +conformant = "Pass" +output = """ +""" diff --git a/conformance/results/pyright/annotations_typeexpr.toml b/conformance/results/pyright/annotations_typeexpr.toml index d09b9c0c3..bf313b95f 100644 --- a/conformance/results/pyright/annotations_typeexpr.toml +++ b/conformance/results/pyright/annotations_typeexpr.toml @@ -1,28 +1,29 @@ conformant = "Pass" output = """ -annotations_typeexpr.py:77:9 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) -annotations_typeexpr.py:78:9 - error: List expression not allowed in type annotation +annotations_typeexpr.py:88:9 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +annotations_typeexpr.py:89:9 - error: List expression not allowed in type annotation   Use List[T] to indicate a list type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) -annotations_typeexpr.py:78:9 - error: Expected type expression but received "list[Unknown]" (reportGeneralTypeIssues) -annotations_typeexpr.py:79:9 - error: Tuple expression not allowed in type annotation +annotations_typeexpr.py:89:9 - error: Expected type expression but received "list[Unknown]" (reportGeneralTypeIssues) +annotations_typeexpr.py:90:9 - error: Tuple expression not allowed in type annotation   Use Tuple[T1, ..., Tn] to indicate a tuple type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) -annotations_typeexpr.py:80:9 - error: List expression not allowed in type annotation +annotations_typeexpr.py:91:9 - error: List expression not allowed in type annotation   Use List[T] to indicate a list type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) -annotations_typeexpr.py:80:9 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) -annotations_typeexpr.py:81:9 - error: Dictionary expression not allowed in type annotation +annotations_typeexpr.py:91:9 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) +annotations_typeexpr.py:92:9 - error: Dictionary expression not allowed in type annotation   Use Dict[T1, T2] to indicate a dictionary type (reportGeneralTypeIssues) -annotations_typeexpr.py:81:9 - error: Expected type expression but received "dict[Unknown, Unknown]" (reportGeneralTypeIssues) -annotations_typeexpr.py:82:9 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) -annotations_typeexpr.py:83:9 - error: List expression not allowed in type annotation +annotations_typeexpr.py:92:9 - error: Expected type expression but received "dict[Unknown, Unknown]" (reportGeneralTypeIssues) +annotations_typeexpr.py:93:9 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +annotations_typeexpr.py:94:9 - error: List expression not allowed in type annotation   Use List[T] to indicate a list type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) -annotations_typeexpr.py:83:9 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) -annotations_typeexpr.py:84:9 - error: Ternary expression not allowed in type annotation -annotations_typeexpr.py:85:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) -annotations_typeexpr.py:86:10 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) -annotations_typeexpr.py:87:10 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) -annotations_typeexpr.py:88:10 - error: Unary operator not allowed in type annotation -annotations_typeexpr.py:89:10 - error: Binary operator not allowed in type annotation -annotations_typeexpr.py:90:10 - error: Expected expression -annotations_typeexpr.py:90:10 - error: Tuple expression not allowed in type annotation +annotations_typeexpr.py:94:9 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) +annotations_typeexpr.py:95:9 - error: Ternary expression not allowed in type annotation +annotations_typeexpr.py:96:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) +annotations_typeexpr.py:97:10 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) +annotations_typeexpr.py:98:10 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) +annotations_typeexpr.py:99:10 - error: Unary operator not allowed in type annotation +annotations_typeexpr.py:100:10 - error: Binary operator not allowed in type annotation +annotations_typeexpr.py:101:10 - error: Expected expression +annotations_typeexpr.py:101:10 - error: Tuple expression not allowed in type annotation   Use Tuple[T1, ..., Tn] to indicate a tuple type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) +annotations_typeexpr.py:102:10 - error: Module cannot be used as a type (reportGeneralTypeIssues) """ diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml index 3b63294bb..effaafcb3 100644 --- a/conformance/results/pyright/version.toml +++ b/conformance/results/pyright/version.toml @@ -1,2 +1,2 @@ version = "pyright 1.1.344" -test_duration = 1.1894707679748535 +test_duration = 1.2371001243591309 diff --git a/conformance/results/pytype/annotations_coroutines.toml b/conformance/results/pytype/annotations_coroutines.toml new file mode 100644 index 000000000..7f77af071 --- /dev/null +++ b/conformance/results/pytype/annotations_coroutines.toml @@ -0,0 +1,9 @@ +conformant = "Partial" +notes = """ +Does not evaluate correct type for async function. +""" +output = """ +File "annotations_coroutines.py", line 19, in : Callable[[int], str] [assert-type] + Expected: Callable[[int], Coroutine[Any, Any, str]] + Actual: Callable[[int], str] +""" diff --git a/conformance/results/pytype/annotations_forward_refs.toml b/conformance/results/pytype/annotations_forward_refs.toml new file mode 100644 index 000000000..86a252c55 --- /dev/null +++ b/conformance/results/pytype/annotations_forward_refs.toml @@ -0,0 +1,45 @@ +conformant = "Partial" +notes = """ +Does not reject some illegal type expression forms when quoted. +Incorrectly generates error for quoted type defined in class scope. +Evaluates incorrect type for class variable annotated with quoted type expression. +""" +output = """ +File "annotations_forward_refs.py", line 22, in : Name 'ClassA' is not defined [name-error] +File "annotations_forward_refs.py", line 23, in : Name 'ClassA' is not defined [name-error] +File "annotations_forward_refs.py", line 24, in : unsupported operand type(s) for |: ''ClassA': str' and 'int: Type[int]' [unsupported-operands] + No attribute '__or__' on ''ClassA': str' or '__ror__' on 'int: Type[int]' +File "annotations_forward_refs.py", line 25, in : Missing parameter 'y' in call to function int.__or__ [missing-parameter] + Expected: (self, y) + Actually passed: (self) +File "annotations_forward_refs.py", line 40, in : invalid syntax [python-compiler-error] +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '[int, str]' for p2 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '(int, str)' for p3 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '' for p4 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '{}' for p5 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '1' for p9 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation 'True' for p10 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '1' for p11 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '-1' for p12 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 40, in : Invalid type annotation '' for p15 [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 66, in ClassB: Name 'ClassB' is not defined [name-error] +File "annotations_forward_refs.py", line 80, in ClassD: Name 'ClassF' is not defined [name-error] +File "annotations_forward_refs.py", line 82, in ClassD: Invalid type annotation '' for str [invalid-annotation] + Must be constant +File "annotations_forward_refs.py", line 87, in ClassD: Invalid type annotation '' for x [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 89, in ClassD: Invalid type annotation '' for y [invalid-annotation] + Not a type +File "annotations_forward_refs.py", line 93, in : Any [assert-type] + Expected: int + Actual: Any +""" diff --git a/conformance/results/pytype/annotations_generators.toml b/conformance/results/pytype/annotations_generators.toml new file mode 100644 index 000000000..a596cdbed --- /dev/null +++ b/conformance/results/pytype/annotations_generators.toml @@ -0,0 +1,37 @@ +conformant = "Partial" +notes = """ +Does not report invalid return type for generator when function implicitly returns None. +Reports invalid error when return type of generator is annotated as a compatible protocol. +Does not report type violation in `yield from` statement. +""" +output = """ +File "annotations_generators.py", line 53, in generator2: bad return type [bad-return-type] + Expected: C + Actually returned: bool +File "annotations_generators.py", line 56, in generator2: bad return type [bad-return-type] + Expected: C + Actually returned: None +File "annotations_generators.py", line 56, in generator2: bad return type [bad-return-type] + Expected: A + Actually returned: int +File "annotations_generators.py", line 65, in generator3: bad return type [bad-return-type] + Expected: A + Actually returned: int +File "annotations_generators.py", line 74, in generator5: bad return type [bad-return-type] + Expected: A + Actually returned: B +File "annotations_generators.py", line 85, in : Bad return type 'int' for generator function generator8 [bad-yield-annotation] + Expected Generator, Iterable or Iterator +File "annotations_generators.py", line 90, in : Bad return type 'int' for async generator function generator9 [bad-yield-annotation] + Expected AsyncGenerator, AsyncIterable or AsyncIterator +File "annotations_generators.py", line 99, in : Bad return type 'IntIterator' for generator function generator15 [bad-yield-annotation] + Expected Generator, Iterable or Iterator +File "annotations_generators.py", line 108, in : Bad return type 'AsyncIntIterator' for async generator function generator16 [bad-yield-annotation] + Expected AsyncGenerator, AsyncIterable or AsyncIterator +File "annotations_generators.py", line 117, in generator18: bad return type [bad-return-type] + Expected: B + Actually returned: A +File "annotations_generators.py", line 118, in generator18: bad return type [bad-return-type] + Expected: B + Actually returned: A +""" diff --git a/conformance/results/pytype/annotations_methods.toml b/conformance/results/pytype/annotations_methods.toml new file mode 100644 index 000000000..2146548eb --- /dev/null +++ b/conformance/results/pytype/annotations_methods.toml @@ -0,0 +1,3 @@ +conformant = "Pass" +output = """ +""" diff --git a/conformance/results/pytype/annotations_typeexpr.toml b/conformance/results/pytype/annotations_typeexpr.toml index 6b91be0f3..6f76e031d 100644 --- a/conformance/results/pytype/annotations_typeexpr.toml +++ b/conformance/results/pytype/annotations_typeexpr.toml @@ -5,22 +5,25 @@ Does not reject call lambda expression in type annotation. Does not reject list expression in type annotation. Does not reject ternary expression in type annotation. Does not reject f-string in type annotation. +Does not reject module in type annotation. """ output = """ -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '[int, str]' for p2 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '[int, str]' for p2 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '(int, str)' for p3 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '(int, str)' for p3 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '' for p4 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '' for p4 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '{}' for p5 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '{}' for p5 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '3' for p9 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '3' for p9 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation 'True' for p10 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation 'True' for p10 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '1' for p11 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '1' for p11 [invalid-annotation] Not a type -File "annotations_typeexpr.py", line 76, in : Invalid type annotation '-1' for p12 [invalid-annotation] +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '-1' for p12 [invalid-annotation] + Not a type +File "annotations_typeexpr.py", line 87, in : Invalid type annotation '' for p15 [invalid-annotation] Not a type """ diff --git a/conformance/results/pytype/qualifiers_final_decorator.toml b/conformance/results/pytype/qualifiers_final_decorator.toml index 0667a582f..c8b206801 100644 --- a/conformance/results/pytype/qualifiers_final_decorator.toml +++ b/conformance/results/pytype/qualifiers_final_decorator.toml @@ -9,9 +9,9 @@ File "qualifiers_final_decorator.py", line 21, in : Cannot subclass fina File "qualifiers_final_decorator.py", line 52, in method4: bad return type [bad-return-type] Expected: str Actually returned: int -File "qualifiers_final_decorator.py", line 55, in : Class Derived2 overrides final method method3, defined in base class Base2 [final-error] -File "qualifiers_final_decorator.py", line 55, in : Class Derived2 overrides final method method4, defined in base class Base2 [final-error] File "qualifiers_final_decorator.py", line 55, in : Class Derived2 overrides final method method1, defined in base class Base2 [final-error] +File "qualifiers_final_decorator.py", line 55, in : Class Derived2 overrides final method method4, defined in base class Base2 [final-error] +File "qualifiers_final_decorator.py", line 55, in : Class Derived2 overrides final method method3, defined in base class Base2 [final-error] File "qualifiers_final_decorator.py", line 55, in : Class Derived2 overrides final method method2, defined in base class Base2 [final-error] File "qualifiers_final_decorator.py", line 76, in method4: bad return type [bad-return-type] Expected: str diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml index d030bd0e0..e59542b3e 100644 --- a/conformance/results/pytype/version.toml +++ b/conformance/results/pytype/version.toml @@ -1,2 +1,2 @@ version = "pytype 2023.12.18" -test_duration = 89.29483127593994 +test_duration = 98.66855192184448 diff --git a/conformance/results/results.html b/conformance/results/results.html index 001b6d056..6bbf8315f 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -127,12 +127,16 @@

Python Type System Conformance Test Results

-
mypy 1.8.0(0.39sec) +
mypy 1.8.0(0.57sec)
+ + + + - + @@ -247,12 +251,16 @@

Python Type System Conformance Test Results

Type annotations
     annotations_coroutinesPass
     annotations_forward_refsPartialDoes not report error for a forward reference that is not enclosed in quotes.
Does not report error for use of quoted type with "|" operator (runtime error).
Incorrectly generates error for quoted type defined in class scope.
     annotations_generatorsPartialDoes not report incompatible Generator type in `yield from` statement.
     annotations_methodsPass
     annotations_typeexprPass
@@ -185,7 +189,7 @@

Python Type System Conformance Test Results

Protocols
     protocols_class_objectsPass
     protocols_definitionPartialRejects implicit class variable when matching protocol with explicit ClassVar.
Does not detect protocol mismatch if concrete method is missing annotations.
Does not detect protocol mismatch if concrete method's parameters are position-only.
     protocols_explicitPassDoes not report unimplemented attributes for class that explicitly derives from protocol until is instantiated.
     protocols_explicitPassDoes not report unimplemented attributes for class that explicitly derives from protocol until it is instantiated.
     protocols_genericPartialFails protocol matching when method-scoped TypeVar is used in protocol.
     protocols_mergingPass
     protocols_modulesPass
     directives_version_platformPassDoes not understand three-element form of sys.version checks.
Does not understand os.name checks.
-
pyright 1.1.344(1.19sec) +
pyright 1.1.344(1.24sec)
+ + + +
Type annotations
     annotations_coroutinesPass
     annotations_forward_refsPass
     annotations_generatorsPass
     annotations_methodsPass
     annotations_typeexprPass
@@ -367,12 +375,16 @@

Python Type System Conformance Test Results

     directives_version_platformPass
-
pyre 0.9.19(1.82sec) +
pyre 0.9.19(1.84sec)
+ + + +
Type annotations
     annotations_coroutinesPartialDoes not evaluate correct type for async function.
     annotations_forward_refsPartialDoes not report error for a forward reference that is not enclosed in quotes.
Does not report error for use of quoted type with "|" operator (runtime error).
Does not reject f-string in quoted type annotation.
Incorrectly generates error for quoted type defined in class scope.
Does not generate error for unquoted type defined in class scope.
     annotations_generatorsPartialDoes not report invalid return type for generator when function implicitly returns None.
Incorrectly evaluates type of call to async generator.
     annotations_methodsPass
     annotations_typeexprPass
@@ -487,13 +499,17 @@

Python Type System Conformance Test Results

     directives_version_platformPartialDoes not support sys.platform checks.
Does not support os.name checks.
-
pytype 2023.12.18(99.84sec) +
pytype 2023.12.18(98.67sec)
- + + + + + diff --git a/conformance/tests/annotations_coroutines.py b/conformance/tests/annotations_coroutines.py new file mode 100644 index 000000000..186c3c495 --- /dev/null +++ b/conformance/tests/annotations_coroutines.py @@ -0,0 +1,24 @@ +""" +Tests for annotating generators and coroutines. +""" + +# Specification: https://typing.readthedocs.io/en/latest/spec/annotations.html#annotating-generator-functions-and-coroutines + +# > Coroutines introduced in PEP 492 are annotated with the same syntax as +# > ordinary functions. However, the return type annotation corresponds to +# > the type of await expression, not to the coroutine type. + + +from typing import Any, Callable, Coroutine, assert_type + + +async def func1(ignored: int, /) -> str: + return "spam" + + +assert_type(func1, Callable[[int], Coroutine[Any, Any, str]]) + + +async def func2() -> None: + x = await func1(42) + assert_type(x, str) diff --git a/conformance/tests/annotations_forward_refs.py b/conformance/tests/annotations_forward_refs.py new file mode 100644 index 000000000..0d90a7d56 --- /dev/null +++ b/conformance/tests/annotations_forward_refs.py @@ -0,0 +1,93 @@ +""" +Tests the handling of forward references in type annotations. +""" + +# > When a type hint contains names that have not been defined yet, that +# > definition may be expressed as a string literal, to be resolved later. + + +import types +from typing import assert_type + + +def func1( + p1: "ClassA", p2: "list[ClassA]", p3: list["ClassA"], p4: list["int | ClassA"] +) -> None: + assert_type(p1, ClassA) + assert_type(p2, list[ClassA]) + assert_type(p3, list[ClassA]) + assert_type(p4, list[ClassA | int]) + + +bad1: ClassA # Type error: requires quotes +bad2: list[ClassA] # Type error: requires quotes +bad3: "ClassA" | int # Runtime error +bad4: int | "ClassA" # Runtime error + + +class ClassA: + ... + + +# > The string literal should contain a valid Python expression +# > should be a valid code object). + +var1 = 1 + + +# The following should all generate errors because they are not legal type +# expressions, despite being enclosed in quotes. +def invalid_annotations( + p1: "eval(" ".join(map(chr, [105, 110, 116])))", + p2: "[int, str]", + p3: "(int, str)", + p4: "[int for i in range(1)]", + p5: "{}", + p6: "(lambda : int)()", + p7: "[int][0]", + p8: "int if 1 < 3 else str", + p9: "var1", + p10: "True", + p11: "1", + p12: "-1", + p13: "int or str", + p14: 'f"int"', + p15: "types", +): + pass + + +# > It should evaluate without errors once the module has been fully loaded. +# > The local and global namespace in which it is evaluated should be the same +# > namespaces in which default arguments to the same function would be evaluated. + + +class ClassB: + def method1(self) -> ClassB: # Runtime error + return ClassB() + + def method2(self) -> "ClassB": # OK + return ClassB() + + +class ClassC: + ... + + +class ClassD: + ClassC: "ClassC" # OK + + ClassF: "ClassF" # Type error: circular reference + + str: "str" = "" # OK + + def int(self) -> None: # OK + ... + + x: "int" = 0 # OK + + y: int = 0 # Type error: Refers to local int, which isn't a legal type expression + + +assert_type(ClassD.str, str) +assert_type(ClassD.x, int) diff --git a/conformance/tests/annotations_generators.py b/conformance/tests/annotations_generators.py new file mode 100644 index 000000000..0803b7d74 --- /dev/null +++ b/conformance/tests/annotations_generators.py @@ -0,0 +1,174 @@ +""" +Tests for annotating generators. +""" + +# Specification: https://typing.readthedocs.io/en/latest/spec/annotations.html#annotating-generator-functions-and-coroutines + +# The return type of generator functions can be annotated by the generic type +# Generator[yield_type, send_type, return_type] provided by typing.py module. + +import asyncio +from typing import ( + Any, + AsyncGenerator, + AsyncIterable, + AsyncIterator, + Awaitable, + Generator, + Iterable, + Iterator, + Literal, + Protocol, + TypeVar, + assert_type, +) + +T = TypeVar("T") + + +class A: + pass + + +class B: + def should_continue(self) -> bool: + return True + + +class C: + pass + + +def generator1() -> Generator[A, B, C]: + cont = B() + while cont.should_continue(): + yield A() + + return C() + + +def generator2() -> Generator[A, B, C]: # Type error: missing return + cont = B() + if cont.should_continue(): + return False # Type error: incompatible return type + + while cont.should_continue(): + yield 3 # Type error: incompatible yield type + + +def generator3() -> Generator[A, int, Any]: + cont = B() + if cont.should_continue(): + return 3 + + while cont.should_continue(): + yield 3 # Incompatible yield type + + +def generator4() -> Iterable[A]: + yield A() + return True + + +def generator5() -> Iterator[A]: + yield B() # Type error: incompatible yield type + + +def generator6() -> Generator[None, None, None]: + yield + + +def generator7() -> Iterator[dict[str, int]]: + yield {"": 0} # OK + + +def generator8() -> int: # Type error: incompatible return type + yield None + return 0 + + +async def generator9() -> int: # Type error: incompatible return type + yield None + + +class IntIterator(Protocol): + def __next__(self, /) -> int: + ... + + +def generator15() -> IntIterator: # OK + yield 0 + + +class AsyncIntIterator(Protocol): + def __anext__(self, /) -> Awaitable[int]: + ... + + +async def generator16() -> AsyncIntIterator: # OK + yield 0 + + +def generator17() -> Iterator[A]: # OK + yield from generator17() + + +def generator18() -> Iterator[B]: + yield from generator17() # Type error: incompatible generator type + yield from [1] # Type error: incompatible generator type + + +def generator19() -> Generator[None, float, None]: # OK + x: float = yield + + +def generator20() -> Generator[None, int, None]: # OK + yield from generator19() + + +def generator21() -> Generator[None, int, None]: + x: float = yield + + +def generator22() -> Generator[None, str, None]: + yield from generator21() # Type error: incompatible send type + + +def generator23() -> Iterable[str]: # OK + return + yield "" # Unreachable + + +async def generator24() -> AsyncIterable[str]: # OK + return + yield "" # Unreachable + + +def generator25(ints1: list[int], ints2: list[int]) -> Generator[int, None, None]: # OK + yield from ints1 + yield from ints2 + + +async def get_data() -> list[int]: + await asyncio.sleep(1) + return [1, 2, 3] + + +async def generator26(nums: list[int]) -> AsyncGenerator[str, None]: + for n in nums: + await asyncio.sleep(1) + yield f"The number is {n}" + + +async def generator27() -> AsyncGenerator[str, None]: + data = await get_data() + v1 = generator26(data) + assert_type(v1, AsyncGenerator[str, None]) + return v1 + + +async def generator28() -> AsyncIterator[str]: + data = await get_data() + v1 = generator26(data) + assert_type(v1, AsyncGenerator[str, None]) + return v1 diff --git a/conformance/tests/annotations_methods.py b/conformance/tests/annotations_methods.py new file mode 100644 index 000000000..49df6b64a --- /dev/null +++ b/conformance/tests/annotations_methods.py @@ -0,0 +1,30 @@ +""" +Tests for annotating instance and class methods. +""" + +# Specification: https://typing.readthedocs.io/en/latest/spec/annotations.html#annotating-instance-and-class-methods + +from typing import TypeVar, assert_type + + +T = TypeVar("T", bound="A") + + +class A: + def copy(self: T) -> T: + return self + + @classmethod + def factory(cls: type[T]) -> T: + return cls() + + +class B(A): + ... + + +assert_type(A().copy(), A) +assert_type(A.factory(), A) + +assert_type(B().copy(), B) +assert_type(B.factory(), B) diff --git a/conformance/tests/annotations_typeexpr.py b/conformance/tests/annotations_typeexpr.py index 064cac65c..81d08496c 100644 --- a/conformance/tests/annotations_typeexpr.py +++ b/conformance/tests/annotations_typeexpr.py @@ -10,15 +10,20 @@ # https://typing.readthedocs.io/en/latest/spec/annotations.html#valid-type-expression-forms + def greeting(name: str) -> str: - return 'Hello ' + name + return "Hello " + name + -assert_type(greeting('Monty'), str) +assert_type(greeting("Monty"), str) # > Expressions whose type is a subtype of a specific argument type are also accepted for that argument. -class StrSub(str): ... -assert_type(greeting(StrSub('Monty')), str) +class StrSub(str): + ... + + +assert_type(greeting(StrSub("Monty")), str) # > Type hints may be built-in classes (including those defined in standard library or third-party @@ -26,10 +31,15 @@ class StrSub(str): ... # > classes (including those defined in the standard library or third-party modules). -class UserDefinedClass: ... +class UserDefinedClass: + ... + + class AbstractBaseClass(abc.ABC): @abc.abstractmethod - def abstract_method(self): ... + def abstract_method(self): + ... + # The following parameter annotations should all be considered # valid and not generate errors. @@ -71,6 +81,7 @@ def valid_annotations( var1 = 3 + # The following parameter annotations should all be considered # invalid and generate errors. def invalid_annotations( @@ -79,7 +90,7 @@ def invalid_annotations( p3: (int, str), p4: [int for i in range(1)], p5: {}, - p6: (lambda : int)(), + p6: (lambda: int)(), p7: [int][0], p8: int if 1 < 3 else str, p9: var1, @@ -88,12 +99,16 @@ def invalid_annotations( p12: -1, p13: int or str, p14: f"int", + p15: types, ): pass # > When used in a type hint, the expression None is considered equivalent to type(None). -def takes_None(x: None) -> None: ... -assert_type(takes_None(None), None) +def takes_None(x: None) -> None: + ... + + +assert_type(takes_None(None), None)
Type annotations
     annotations_typeexprPartialDoes not reject call expressions in type annotation.
Does not reject call lambda expression in type annotation.
Does not reject list expression in type annotation.
Does not reject ternary expression in type annotation.
Does not reject f-string in type annotation.
     annotations_coroutinesPartialDoes not evaluate correct type for async function.
     annotations_forward_refsPartialDoes not reject some illegal type expression forms when quoted.
Incorrectly generates error for quoted type defined in class scope.
Evaluates incorrect type for class variable annotated with quoted type expression.
     annotations_generatorsPartialDoes not report invalid return type for generator when function implicitly returns None.
Reports invalid error when return type of generator is annotated as a compatible protocol.
Does not report type violation in `yield from` statement.
     annotations_methodsPass
     annotations_typeexprPartialDoes not reject call expressions in type annotation.
Does not reject call lambda expression in type annotation.
Does not reject list expression in type annotation.
Does not reject ternary expression in type annotation.
Does not reject f-string in type annotation.
Does not reject module in type annotation.
Special types in annotations