From a6b4ad606a1ef66e6e4c04cce672033b9a0075f3 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 30 Dec 2023 00:31:57 -0700 Subject: [PATCH] Added link to conformance results. Added tests for `@final` decorator. Added tests for `Final` annotation. Updated pyright test results for latest version (1.1.344). Added tests for Annotated. --- README.md | 2 + .../results/mypy/qualifiers_annotated.toml | 26 +++ .../mypy/qualifiers_final_annotation.toml | 38 +++++ .../mypy/qualifiers_final_decorator.toml | 17 ++ conformance/results/mypy/version.toml | 2 +- .../results/pyre/qualifiers_annotated.toml | 18 ++ .../pyre/qualifiers_final_annotation.toml | 34 ++++ .../pyre/qualifiers_final_decorator.toml | 16 ++ conformance/results/pyre/version.toml | 2 +- .../results/pyright/aliases_explicit.toml | 10 +- .../results/pyright/aliases_implicit.toml | 10 +- .../results/pyright/aliases_newtype.toml | 17 +- .../pyright/aliases_type_statement.toml | 33 ++-- .../pyright/aliases_typealiastype.toml | 30 ++-- .../results/pyright/annotations_typeexpr.toml | 1 - .../results/pyright/callables_protocol.toml | 8 +- .../results/pyright/dataclasses_postinit.toml | 7 +- .../results/pyright/qualifiers_annotated.toml | 23 +++ .../pyright/qualifiers_final_annotation.toml | 38 +++++ .../pyright/qualifiers_final_decorator.toml | 15 ++ conformance/results/pyright/version.toml | 4 +- .../results/pytype/qualifiers_annotated.toml | 27 +++ .../pytype/qualifiers_final_annotation.toml | 45 +++++ .../pytype/qualifiers_final_decorator.toml | 31 ++++ conformance/results/pytype/version.toml | 2 +- conformance/results/results.html | 46 ++++-- .../tests/_qualifiers_final_decorator.pyi | 29 ++++ conformance/tests/qualifiers_annotated.py | 96 +++++++++++ .../tests/qualifiers_final_annotation.py | 155 ++++++++++++++++++ .../tests/qualifiers_final_decorator.py | 126 ++++++++++++++ 30 files changed, 826 insertions(+), 82 deletions(-) create mode 100644 conformance/results/mypy/qualifiers_annotated.toml create mode 100644 conformance/results/mypy/qualifiers_final_annotation.toml create mode 100644 conformance/results/mypy/qualifiers_final_decorator.toml create mode 100644 conformance/results/pyre/qualifiers_annotated.toml create mode 100644 conformance/results/pyre/qualifiers_final_annotation.toml create mode 100644 conformance/results/pyre/qualifiers_final_decorator.toml create mode 100644 conformance/results/pyright/qualifiers_annotated.toml create mode 100644 conformance/results/pyright/qualifiers_final_annotation.toml create mode 100644 conformance/results/pyright/qualifiers_final_decorator.toml create mode 100644 conformance/results/pytype/qualifiers_annotated.toml create mode 100644 conformance/results/pytype/qualifiers_final_annotation.toml create mode 100644 conformance/results/pytype/qualifiers_final_decorator.toml create mode 100644 conformance/tests/_qualifiers_final_decorator.pyi create mode 100644 conformance/tests/qualifiers_annotated.py create mode 100644 conformance/tests/qualifiers_final_annotation.py create mode 100644 conformance/tests/qualifiers_final_decorator.py diff --git a/README.md b/README.md index 9809cd697..eb7472be0 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ This GitHub repository is used for several things: - A [discussion forum](https://github.com/python/typing/discussions) for typing-related user help is hosted here. +- [Conformance test](https://github.com/python/typing/blob/main/conformance/README.md) for Python static type checkers. The [latest conformance test results](https://htmlpreview.github.io/?https://github.com/python/typing/blob/main/conformance/results/results.html) are here. + Historically, this repository also hosted: - The `typing_extensions` package, which now lives in the diff --git a/conformance/results/mypy/qualifiers_annotated.toml b/conformance/results/mypy/qualifiers_annotated.toml new file mode 100644 index 000000000..44adc1ec8 --- /dev/null +++ b/conformance/results/mypy/qualifiers_annotated.toml @@ -0,0 +1,26 @@ +conformant = "Partial" +notes = """ +Does not allow ClassVar to be nested within Annotated. +Does not allow Final to be nested within Annotated. +Does not allow Required and NotRequired to be nested within Annotated. +""" +output = """ +qualifiers_annotated.py:41: error: Bracketed expression "[...]" is not valid as a type [valid-type] +qualifiers_annotated.py:42: error: Syntax error in type annotation [syntax] +qualifiers_annotated.py:42: note: Suggestion: Is there a spurious trailing comma? +qualifiers_annotated.py:43: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:44: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:45: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:46: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:47: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:48: error: Name "var1" is not defined [name-defined] +qualifiers_annotated.py:49: error: Invalid type: try using Literal[True] instead? [valid-type] +qualifiers_annotated.py:50: error: Invalid type: try using Literal[1] instead? [valid-type] +qualifiers_annotated.py:51: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:52: error: Invalid type comment or annotation [valid-type] +qualifiers_annotated.py:62: error: Annotated[...] must have exactly one type argument and at least one annotation [valid-type] +qualifiers_annotated.py:73: error: Invalid type: ClassVar nested inside other type [valid-type] +qualifiers_annotated.py:75: error: Final can be only used as an outermost qualifier in a variable annotation [valid-type] +qualifiers_annotated.py:85: error: Required[] can be only used in a TypedDict definition [valid-type] +qualifiers_annotated.py:87: error: NotRequired[] can be only used in a TypedDict definition [valid-type] +""" diff --git a/conformance/results/mypy/qualifiers_final_annotation.toml b/conformance/results/mypy/qualifiers_final_annotation.toml new file mode 100644 index 000000000..f5295752e --- /dev/null +++ b/conformance/results/mypy/qualifiers_final_annotation.toml @@ -0,0 +1,38 @@ +conformant = "Partial" +notes = """ +Does not treat use of Final name as if it was replaced by the literal in NamedTuple definition. +Does not allow conditional assignment of Final instance variable in __init__ method. +Does not allow redefinition of private class variable that is marked Final in parent class. +Does not report modification of local Final variable via "for" statement. +""" +output = """ +qualifiers_final_annotation.py:16: error: Type in Final[...] can only be omitted if there is an initializer [misc] +qualifiers_final_annotation.py:18: error: Final[...] takes at most one type argument [misc] +qualifiers_final_annotation.py:34: error: Type in Final[...] can only be omitted if there is an initializer [misc] +qualifiers_final_annotation.py:38: error: Final name must be initialized with a value [misc] +qualifiers_final_annotation.py:54: error: Cannot assign to final attribute "ID5" [misc] +qualifiers_final_annotation.py:59: error: Cannot assign to final attribute "ID6" [misc] +qualifiers_final_annotation.py:62: error: Can only declare a final attribute in class body or __init__ [misc] +qualifiers_final_annotation.py:63: error: Can only declare a final attribute in class body or __init__ [misc] +qualifiers_final_annotation.py:65: error: Cannot assign to final attribute "ID7" [misc] +qualifiers_final_annotation.py:67: error: Cannot assign to final attribute "ID7" [misc] +qualifiers_final_annotation.py:71: error: Cannot assign to final name "RATE" [misc] +qualifiers_final_annotation.py:81: error: Cannot assign to final attribute "DEFAULT_ID" [misc] +qualifiers_final_annotation.py:94: error: Cannot assign to final name "BORDER_WIDTH" [misc] +qualifiers_final_annotation.py:96: error: Cannot assign to final name "__private" [misc] +qualifiers_final_annotation.py:107: error: Final can be only used as an outermost qualifier in a variable annotation [valid-type] +qualifiers_final_annotation.py:108: error: Variable should not be annotated with both ClassVar and Final [misc] +qualifiers_final_annotation.py:118: error: Final can be only used as an outermost qualifier in a variable annotation [valid-type] +qualifiers_final_annotation.py:121: error: Final can be only used as an outermost qualifier in a variable annotation [valid-type] +qualifiers_final_annotation.py:131: error: Invalid "NamedTuple()" field name [misc] +qualifiers_final_annotation.py:133: error: Unexpected keyword argument "x" for "N" [call-arg] +qualifiers_final_annotation.py:133: error: Unexpected keyword argument "y" for "N" [call-arg] +qualifiers_final_annotation.py:134: error: Unexpected keyword argument "a" for "N" [call-arg] +qualifiers_final_annotation.py:135: error: Unexpected keyword argument "x" for "N" [call-arg] +qualifiers_final_annotation.py:135: error: Unexpected keyword argument "y" for "N" [call-arg] +qualifiers_final_annotation.py:141: error: Cannot assign to final name "ID1" [misc] +qualifiers_final_annotation.py:145: error: Cannot assign to final name "x" [misc] +qualifiers_final_annotation.py:147: error: Cannot assign to final name "x" [misc] +qualifiers_final_annotation.py:152: error: Incompatible types in assignment (expression has type "TextIOWrapper", variable has type "int") [assignment] +qualifiers_final_annotation.py:155: error: Cannot assign to final name "x" [misc] +""" diff --git a/conformance/results/mypy/qualifiers_final_decorator.toml b/conformance/results/mypy/qualifiers_final_decorator.toml new file mode 100644 index 000000000..a87a322ba --- /dev/null +++ b/conformance/results/mypy/qualifiers_final_decorator.toml @@ -0,0 +1,17 @@ +conformant = "Pass" +output = """ +qualifiers_final_decorator.py:21: error: Cannot inherit from final class "Base1" [misc] +qualifiers_final_decorator.py:56: error: Cannot override final attribute "method1" (previously declared in base class "Base2") [misc] +qualifiers_final_decorator.py:59: error: Cannot override final attribute "method2" (previously declared in base class "Base2") [misc] +qualifiers_final_decorator.py:63: error: Cannot override final attribute "method3" (previously declared in base class "Base2") [misc] +qualifiers_final_decorator.py:67: error: Cannot override final attribute "method4" (previously declared in base class "Base2") [misc] +qualifiers_final_decorator.py:80: error: Cannot override final attribute "method" (previously declared in base class "Base3") [misc] +qualifiers_final_decorator.py:93: error: Cannot override final attribute "method" (previously declared in base class "Base4") [misc] +qualifiers_final_decorator.py:117: error: Cannot override final attribute "method" (previously declared in base class "Base5_2") [misc] +qualifiers_final_decorator.py:117: error: Signature of "method" incompatible with supertype "Base5_2" [override] +qualifiers_final_decorator.py:117: note: Superclass: +qualifiers_final_decorator.py:117: note: def method(self, v: int) -> None +qualifiers_final_decorator.py:117: note: Subclass: +qualifiers_final_decorator.py:117: note: def method(self) -> None +qualifiers_final_decorator.py:124: error: @final cannot be used with non-method functions [misc] +""" diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml index 63c2f4d79..ef8f9d6fd 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.3814089298248291 +test_duration = 0.4777989387512207 diff --git a/conformance/results/pyre/qualifiers_annotated.toml b/conformance/results/pyre/qualifiers_annotated.toml new file mode 100644 index 000000000..e0d4e1149 --- /dev/null +++ b/conformance/results/pyre/qualifiers_annotated.toml @@ -0,0 +1,18 @@ +conformant = "Partial" +notes = """ +Does not reject Annotated with a single parameter. +""" +output = """ +qualifiers_annotated.py:41:6 Undefined or invalid type [11]: Annotation `` is not defined as a type. +qualifiers_annotated.py:42:6 Invalid type [31]: Expression `typing.Annotated[(((int, str)), "")]` is not a valid type. +qualifiers_annotated.py:43:6 Invalid type [31]: Expression `typing.Annotated[(comprehension(int for generators(generator($target$i in range(1) if ))), "")]` is not a valid type. +qualifiers_annotated.py:44:6 Invalid type [31]: Expression `typing.Annotated[({ "a":"b" }, "")]` is not a valid type. +qualifiers_annotated.py:45:6 Invalid type [31]: Expression `typing.Annotated[(lambda () (int)(), "")]` is not a valid type. +qualifiers_annotated.py:46:6 Invalid type [31]: Expression `typing.Annotated[([int][0], "")]` is not a valid type. +qualifiers_annotated.py:47:6 Invalid type [31]: Expression `typing.Annotated[(int if 1 < 3 else str, "")]` is not a valid type. +qualifiers_annotated.py:48:16 Unbound name [10]: Name `var1` is used but not defined in the current scope. +qualifiers_annotated.py:49:6 Invalid type [31]: Expression `typing.Annotated[(True, "")]` is not a valid type. +qualifiers_annotated.py:50:7 Invalid type [31]: Expression `typing.Annotated[(1, "")]` is not a valid type. +qualifiers_annotated.py:51:7 Invalid type [31]: Expression `typing.Annotated[(list or set, "")]` is not a valid type. +qualifiers_annotated.py:52:7 Invalid type [31]: Expression `typing.Annotated[(f"{"int"}", "")]` is not a valid type. +""" diff --git a/conformance/results/pyre/qualifiers_final_annotation.toml b/conformance/results/pyre/qualifiers_final_annotation.toml new file mode 100644 index 000000000..79bd08fdb --- /dev/null +++ b/conformance/results/pyre/qualifiers_final_annotation.toml @@ -0,0 +1,34 @@ +conformant = "Partial" +notes = """ +Does not report Final variable with missing initialization in module scope. +Does not report error for invalid nesting of Final and ClassVar. +Does not treat use of Final name as if it was replaced by the literal in NamedTuple definition. +""" +output = """ +qualifiers_final_annotation.py:18:6 Invalid type parameters [24]: Generic type `Final` expects 1 type parameter, received 2. +qualifiers_final_annotation.py:28:0 Uninitialized attribute [13]: Attribute `ID3` is declared in class `ClassA` to have type `int` but is never initialized. +qualifiers_final_annotation.py:34:4 Invalid assignment [41]: Cannot reassign final attribute `ClassA.ID2`. +qualifiers_final_annotation.py:54:8 Invalid assignment [41]: Cannot reassign final attribute `self.ID5`. +qualifiers_final_annotation.py:62:8 Undefined attribute [16]: `ClassA` has no attribute `id3`. +qualifiers_final_annotation.py:63:8 Undefined attribute [16]: `ClassA` has no attribute `id4`. +qualifiers_final_annotation.py:65:8 Invalid assignment [41]: Cannot reassign final attribute `self.ID7`. +qualifiers_final_annotation.py:67:8 Invalid assignment [41]: Cannot reassign final attribute `self.ID7`. +qualifiers_final_annotation.py:71:0 Invalid assignment [41]: Cannot reassign final attribute `RATE`. +qualifiers_final_annotation.py:81:0 Invalid assignment [41]: Cannot reassign final attribute `ClassB.DEFAULT_ID`. +qualifiers_final_annotation.py:94:4 Invalid assignment [41]: Cannot reassign final attribute `BORDER_WIDTH`. +qualifiers_final_annotation.py:107:4 Incompatible attribute type [8]: Attribute `VALUE2` declared in class `ClassD` has type `Final` but is used as type `int`. +qualifiers_final_annotation.py:107:4 Invalid type [31]: Expression `Final` is not a valid type. Final cannot be nested. +qualifiers_final_annotation.py:118:0 Invalid type [31]: Expression `typing.List[Final[int]]` is not a valid type. Final cannot be nested. +qualifiers_final_annotation.py:121:10 Invalid type [31]: Parameter `x` cannot be annotated with Final. +qualifiers_final_annotation.py:131:0 Uninitialized attribute [13]: Attribute `($local_qualifiers_final_annotation$X, int)` is declared in class `N` to have type `typing.Any` but is never initialized. +qualifiers_final_annotation.py:131:0 Uninitialized attribute [13]: Attribute `($local_qualifiers_final_annotation$Y, int)` is declared in class `N` to have type `typing.Any` but is never initialized. +qualifiers_final_annotation.py:133:0 Unexpected keyword [28]: Unexpected keyword argument `x` to call `N.__init__`. +qualifiers_final_annotation.py:134:0 Unexpected keyword [28]: Unexpected keyword argument `a` to call `N.__init__`. +qualifiers_final_annotation.py:135:0 Unexpected keyword [28]: Unexpected keyword argument `x` to call `N.__init__`. +qualifiers_final_annotation.py:141:4 Invalid assignment [41]: Cannot reassign final attribute `ID1`. +qualifiers_final_annotation.py:145:4 Invalid assignment [41]: Cannot reassign final attribute `x`. +qualifiers_final_annotation.py:147:9 Invalid assignment [41]: Cannot reassign final attribute `x`. +qualifiers_final_annotation.py:149:8 Invalid assignment [41]: Cannot reassign final attribute `x`. +qualifiers_final_annotation.py:152:29 Invalid assignment [41]: Cannot reassign final attribute `x`. +qualifiers_final_annotation.py:155:8 Invalid assignment [41]: Cannot reassign final attribute `x`. +""" diff --git a/conformance/results/pyre/qualifiers_final_decorator.toml b/conformance/results/pyre/qualifiers_final_decorator.toml new file mode 100644 index 000000000..d94748c03 --- /dev/null +++ b/conformance/results/pyre/qualifiers_final_decorator.toml @@ -0,0 +1,16 @@ +conformant = "Partial" +notes = """ +Reports error for overloaded method implementation marked @final if its overloads do not. +Does not report error for overloaded @final method defined in stub file. +""" +output = """ +qualifiers_final_decorator.py:21:0 Invalid inheritance [39]: Cannot inherit from final class `Base1`. +qualifiers_final_decorator.py:51:4 Incompatible overload [43]: This definition does not have the same decorators as the preceding overload(s). +qualifiers_final_decorator.py:56:4 Invalid override [40]: `qualifiers_final_decorator.Derived2.method1` cannot override final method defined in `Base2`. +qualifiers_final_decorator.py:60:4 Invalid override [40]: `qualifiers_final_decorator.Derived2.method2` cannot override final method defined in `Base2`. +qualifiers_final_decorator.py:64:4 Invalid override [40]: `qualifiers_final_decorator.Derived2.method3` cannot override final method defined in `Base2`. +qualifiers_final_decorator.py:75:4 Invalid override [40]: `qualifiers_final_decorator.Derived2.method4` cannot override final method defined in `Base2`. +qualifiers_final_decorator.py:117:4 Inconsistent override [14]: `qualifiers_final_decorator.Derived5.method` overrides method defined in `Base5_2` inconsistently. Could not find parameter `v` in overriding signature. +qualifiers_final_decorator.py:117:4 Invalid override [40]: `qualifiers_final_decorator.Derived5.method` cannot override final method defined in `Base5_2`. +qualifiers_final_decorator.py:125:0 Invalid inheritance [39]: `final` cannot be used with non-method functions. +""" diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml index 91daa0eeb..283a04d6d 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.5496571063995361 +test_duration = 1.6688978672027588 diff --git a/conformance/results/pyright/aliases_explicit.toml b/conformance/results/pyright/aliases_explicit.toml index a69c20491..a90f7e995 100644 --- a/conformance/results/pyright/aliases_explicit.toml +++ b/conformance/results/pyright/aliases_explicit.toml @@ -1,10 +1,5 @@ -conformant = "Partial" -notes = """ -Incorrectly evaluates type of specialized type alias parameterized with ParamSpec. -Allows some illegal annotation forms to be interpreted as valid type aliases. -""" +conformant = "Pass" output = """ -aliases_explicit.py:57:17 - error: "assert_type" mismatch: expected "(int, str, str) -> None" but received "(int, str, str) -> None" (reportGeneralTypeIssues) aliases_explicit.py:67:24 - error: Expected no type arguments for class "int" (reportGeneralTypeIssues) aliases_explicit.py:67:24 - error: Expected no type arguments for class "NoneType" (reportGeneralTypeIssues) aliases_explicit.py:68:9 - error: Type "list[int | None]" is already specialized (reportGeneralTypeIssues) @@ -20,7 +15,6 @@ aliases_explicit.py:80:21 - error: Expected type expression but received "list[U aliases_explicit.py:81:21 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_explicit.py:81:21 - 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) -aliases_explicit.py:81:21 - error: Expected type expression but received "tuple[tuple[type[int], type[str]]]" (reportGeneralTypeIssues) aliases_explicit.py:82:21 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_explicit.py:82:21 - 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) @@ -31,6 +25,7 @@ aliases_explicit.py:83:21 - error: Dictionary expression not allowed in type ann aliases_explicit.py:83:21 - error: Expected type expression but received "dict[str, str]" (reportGeneralTypeIssues) aliases_explicit.py:84:21 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_explicit.py:84:21 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +aliases_explicit.py:85:21 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_explicit.py:85:21 - 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) aliases_explicit.py:85:21 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) @@ -40,6 +35,7 @@ aliases_explicit.py:87:21 - error: Variable not allowed in type expression (repo aliases_explicit.py:88:22 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) aliases_explicit.py:89:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_explicit.py:89:22 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) +aliases_explicit.py:90:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_explicit.py:90:22 - error: Binary operator not allowed in type annotation aliases_explicit.py:91:22 - error: Expected expression aliases_explicit.py:91:22 - error: Tuple expression not allowed in type annotation diff --git a/conformance/results/pyright/aliases_implicit.toml b/conformance/results/pyright/aliases_implicit.toml index be26d5c86..c7a06c929 100644 --- a/conformance/results/pyright/aliases_implicit.toml +++ b/conformance/results/pyright/aliases_implicit.toml @@ -1,10 +1,5 @@ -conformant = "Partial" -notes = """ -Incorrectly evaluates type of specialized type alias parameterized with ParamSpec. -Allows some illegal annotation forms to be interpreted as valid type aliases. -""" +conformant = "Pass" output = """ -aliases_implicit.py:68:17 - error: "assert_type" mismatch: expected "(int, str, str) -> None" but received "(int, str, str) -> None" (reportGeneralTypeIssues) aliases_implicit.py:76:24 - error: Expected no type arguments for class "int" (reportGeneralTypeIssues) aliases_implicit.py:76:24 - error: Expected no type arguments for class "NoneType" (reportGeneralTypeIssues) aliases_implicit.py:77:9 - error: Type "list[int | None]" is already specialized (reportGeneralTypeIssues) @@ -19,10 +14,13 @@ aliases_implicit.py:107:9 - error: Variable not allowed in type expression (repo aliases_implicit.py:108:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:109:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:110:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) +aliases_implicit.py:111:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) +aliases_implicit.py:112:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:113:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:114:9 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:115:10 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:116:10 - error: Variable not allowed in type expression (reportGeneralTypeIssues) +aliases_implicit.py:117:10 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:118:10 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:119:10 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_implicit.py:133:6 - error: Object of type "type[list[Unknown]] | type[set[Unknown]]" is not callable (reportGeneralTypeIssues) diff --git a/conformance/results/pyright/aliases_newtype.toml b/conformance/results/pyright/aliases_newtype.toml index 5024de109..ffffb1adf 100644 --- a/conformance/results/pyright/aliases_newtype.toml +++ b/conformance/results/pyright/aliases_newtype.toml @@ -1,21 +1,20 @@ -conformant = "Partial" -notes = """ -Does not reject use of NewType in `isinstance` call. -Does not report inconsistency between name of NewType and assigned identifier name. -Does not reject use of NewType with TypedDict class. -Does not reject use of NewType with another NewType. -Does not reject use of NewType with Any. -""" +conformant = "Pass" output = """ aliases_newtype.py:11:8 - error: Argument of type "Literal['user']" cannot be assigned to parameter "_x" of type "int" in function "__init__"   "Literal['user']" is incompatible with "int" (reportGeneralTypeIssues) aliases_newtype.py:12:14 - error: Expression of type "Literal[42]" cannot be assigned to declared type "UserId"   "Literal[42]" is incompatible with "UserId" (reportGeneralTypeIssues) +aliases_newtype.py:20:16 - error: Second argument to "isinstance" must be a class or tuple of classes +  Class created with NewType cannot be used with instance and class checks (reportGeneralTypeIssues) aliases_newtype.py:23:21 - error: Base class "UserId" is marked final and cannot be subclassed +aliases_newtype.py:32:1 - error: NewType must be assigned to a variable with the same name (reportGeneralTypeIssues) aliases_newtype.py:36:19 - error: Expected no type arguments for class "GoodNewType1" (reportGeneralTypeIssues) aliases_newtype.py:42:38 - error: Expected class as second argument to NewType aliases_newtype.py:45:43 - error: Type variable "T" has no meaning in this context (reportGeneralTypeIssues) -aliases_newtype.py:47:38 - error: NewType cannot be used with protocol class +aliases_newtype.py:47:38 - error: NewType cannot be used with structural type (a protocol or TypedDict class) aliases_newtype.py:49:38 - error: NewType cannot be used with Literal type +aliases_newtype.py:56:38 - error: NewType cannot be used with structural type (a protocol or TypedDict class) +aliases_newtype.py:58:38 - error: NewType cannot be used with a class created with NewType aliases_newtype.py:60:15 - error: NewType requires two positional arguments (reportGeneralTypeIssues) +aliases_newtype.py:62:38 - error: The second argument to NewType must be a known class, not Any or Unknown (reportGeneralTypeIssues) """ diff --git a/conformance/results/pyright/aliases_type_statement.toml b/conformance/results/pyright/aliases_type_statement.toml index abc0dc775..0c987a446 100644 --- a/conformance/results/pyright/aliases_type_statement.toml +++ b/conformance/results/pyright/aliases_type_statement.toml @@ -1,10 +1,5 @@ -conformant = "Partial" -notes = """ -Does not reject binary expression when used in type alias definition. -""" +conformant = "Pass" output = """ -aliases_type_statement.py:44:26 - error: Statements must be separated by newlines or semicolons -aliases_type_statement.py:44:35 - error: Expected ":" aliases_type_statement.py:17:12 - error: Cannot access member "bit_count" for type "TypeAliasType"   Member "bit_count" is unknown (reportGeneralTypeIssues) aliases_type_statement.py:19:1 - error: Object of type "TypeAliasType" is not callable (reportGeneralTypeIssues) @@ -16,22 +11,30 @@ aliases_type_statement.py:31:22 - error: Argument of type "TypeAliasType" cannot     "TypeAliasType" is incompatible with "type"     "TypeAliasType" is incompatible with "UnionType"     "TypeAliasType" is incompatible with "tuple[_ClassInfo, ...]" (reportGeneralTypeIssues) -aliases_type_statement.py:37:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) -aliases_type_statement.py:38:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) +aliases_type_statement.py:37:22 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +aliases_type_statement.py:38:22 - 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) aliases_type_statement.py:38:22 - error: Expected type expression but received "list[Unknown]" (reportGeneralTypeIssues) -aliases_type_statement.py:39:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) -aliases_type_statement.py:39:22 - error: Expected type expression but received "tuple[tuple[type[int], type[str]]]" (reportGeneralTypeIssues) -aliases_type_statement.py:40:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) +aliases_type_statement.py:39:22 - 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) +aliases_type_statement.py:40:22 - 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) aliases_type_statement.py:40:22 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) -aliases_type_statement.py:41:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) +aliases_type_statement.py:41:22 - error: Dictionary expression not allowed in type annotation +  Use Dict[T1, T2] to indicate a dictionary type (reportGeneralTypeIssues) aliases_type_statement.py:41:22 - error: Expected type expression but received "dict[str, str]" (reportGeneralTypeIssues) -aliases_type_statement.py:42:22 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) +aliases_type_statement.py:42:22 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +aliases_type_statement.py:43:22 - 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) aliases_type_statement.py:43:22 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) -aliases_type_statement.py:45:22 - error: Expected type expression but received "int" (reportGeneralTypeIssues) +aliases_type_statement.py:44:22 - error: Ternary expression not allowed in type annotation +aliases_type_statement.py:45:22 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_type_statement.py:46:23 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) -aliases_type_statement.py:47:23 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_type_statement.py:47:23 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) +aliases_type_statement.py:48:23 - error: Binary operator not allowed in type annotation aliases_type_statement.py:49:23 - error: Expected expression +aliases_type_statement.py:49:23 - 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) aliases_type_statement.py:58:10 - error: A type statement can be used only within a module or class scope aliases_type_statement.py:64:23 - error: Type parameter "V" is not included in the type parameter list for "TA1" (reportGeneralTypeIssues) aliases_type_statement.py:69:17 - error: Type parameter "T1" is not included in the type parameter list for "TA2" (reportGeneralTypeIssues) diff --git a/conformance/results/pyright/aliases_typealiastype.toml b/conformance/results/pyright/aliases_typealiastype.toml index 34329cf9d..a71693625 100644 --- a/conformance/results/pyright/aliases_typealiastype.toml +++ b/conformance/results/pyright/aliases_typealiastype.toml @@ -1,37 +1,31 @@ -conformant = "Partial" -notes = """ -Does not reject type alias with TypeVar that is not in scope and not in `type_params`. -Does not allow access to `__value__` attribute of type alias. -Allows some illegal annotation forms to be interpreted as valid type aliases. -""" +conformant = "Pass" output = """ -aliases_typealiastype.py:30:18 - error: Cannot access member "__value__" for type "GoodAlias1" -  Member "__value__" is unknown (reportGeneralTypeIssues) -aliases_typealiastype.py:32:18 - error: Cannot access member "other_attrib" for type "GoodAlias1" +aliases_typealiastype.py:32:18 - error: Cannot access member "other_attrib" for type "TypeAliasType"   Member "other_attrib" is unknown (reportGeneralTypeIssues) aliases_typealiastype.py:40:5 - error: Could not specialize type "GoodAlias5[S@GoodAlias5, TStr@GoodAlias5, P@GoodAlias5, Ts@GoodAlias5]"   Type "int" cannot be assigned to type "str"     "int" is incompatible with "str" aliases_typealiastype.py:44:23 - error: Type variable "S" has no meaning in this context (reportGeneralTypeIssues) +aliases_typealiastype.py:46:45 - error: Type variable "S" has no meaning in this context (reportGeneralTypeIssues) aliases_typealiastype.py:48:35 - error: Type parameter list must be a tuple containing only TypeVar, TypeVarTuple, or ParamSpec aliases_typealiastype.py:50:40 - error: Type alias "BadAlias4" cannot use itself in its definition (reportGeneralTypeIssues) aliases_typealiastype.py:52:18 - error: Type alias "BadAlias5" cannot use itself in its definition (reportGeneralTypeIssues) aliases_typealiastype.py:54:40 - error: Type alias "BadAlias6" cannot use itself in its definition (reportGeneralTypeIssues) -aliases_typealiastype.py:58:40 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) -aliases_typealiastype.py:59:40 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) +aliases_typealiastype.py:58:40 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) aliases_typealiastype.py:59:40 - error: Expected type expression but received "list[Unknown]" (reportGeneralTypeIssues) -aliases_typealiastype.py:60:42 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_typealiastype.py:60:42 - error: Expected type expression but received "tuple[tuple[type[int], type[str]]]" (reportGeneralTypeIssues) -aliases_typealiastype.py:61:42 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_typealiastype.py:61:42 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) -aliases_typealiastype.py:62:42 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_typealiastype.py:62:42 - error: Expected type expression but received "dict[str, str]" (reportGeneralTypeIssues) -aliases_typealiastype.py:63:42 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) +aliases_typealiastype.py:63:42 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +aliases_typealiastype.py:64:42 - 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) aliases_typealiastype.py:64:42 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) -aliases_typealiastype.py:65:42 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) -aliases_typealiastype.py:66:42 - error: Expected type expression but received "int" (reportGeneralTypeIssues) +aliases_typealiastype.py:65:42 - error: Ternary expression not allowed in type annotation +aliases_typealiastype.py:66:42 - error: Variable not allowed in type expression (reportGeneralTypeIssues) aliases_typealiastype.py:67:42 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) -aliases_typealiastype.py:68:42 - error: Invalid expression form for type alias definition (reportGeneralTypeIssues) aliases_typealiastype.py:68:42 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) +aliases_typealiastype.py:69:42 - error: Binary operator not allowed in type annotation aliases_typealiastype.py:70:42 - error: Expected expression +aliases_typealiastype.py:70:42 - 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) """ diff --git a/conformance/results/pyright/annotations_typeexpr.toml b/conformance/results/pyright/annotations_typeexpr.toml index f1bd93080..d09b9c0c3 100644 --- a/conformance/results/pyright/annotations_typeexpr.toml +++ b/conformance/results/pyright/annotations_typeexpr.toml @@ -6,7 +6,6 @@ annotations_typeexpr.py:78:9 - error: List expression not allowed in type annota 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   Use Tuple[T1, ..., Tn] to indicate a tuple type or Union[T1, T2] to indicate a union type (reportGeneralTypeIssues) -annotations_typeexpr.py:79:9 - error: Expected type expression but received "tuple[type[int], type[str]]" (reportGeneralTypeIssues) annotations_typeexpr.py:80: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) diff --git a/conformance/results/pyright/callables_protocol.toml b/conformance/results/pyright/callables_protocol.toml index 7e548a2a7..c4393daa5 100644 --- a/conformance/results/pyright/callables_protocol.toml +++ b/conformance/results/pyright/callables_protocol.toml @@ -1,7 +1,4 @@ -conformant = "Partial" -notes = """ -Does not report type incompatibility for callback protocol with positional-only parameters. -""" +conformant = "Pass" output = """ callables_protocol.py:35:7 - error: Expression of type "(*vals: bytes, max_items: int | None) -> list[bytes]" cannot be assigned to declared type "Proto1"   Type "(*vals: bytes, max_items: int | None) -> list[bytes]" cannot be assigned to type "(*vals: bytes, max_len: int | None = None) -> list[bytes]" @@ -47,6 +44,9 @@ callables_protocol.py:187:15 - error: Cannot assign member "xxx" for type "Proto   Member "xxx" is unknown (reportGeneralTypeIssues) callables_protocol.py:197:16 - error: Cannot access member "other_attribute2" for type "Proto9[(x: int), str]"   Member "other_attribute2" is unknown (reportGeneralTypeIssues) +callables_protocol.py:238:8 - error: Expression of type "(x: int, y: str, /) -> Any" cannot be assigned to declared type "Proto11" +  Type "(x: int, y: str, /) -> Any" cannot be assigned to type "(x: int, /, y: str) -> Any" +    Position-only parameter mismatch; parameter "y" is not position-only (reportGeneralTypeIssues) callables_protocol.py:260:8 - error: Expression of type "(*args: Any, kwarg0: Any) -> None" cannot be assigned to declared type "Proto12"   Type "(*args: Any, kwarg0: Any) -> None" cannot be assigned to type "(*args: Any, kwarg0: Any, kwarg1: Any) -> None"     Keyword parameter "kwarg1" is missing in source (reportGeneralTypeIssues) diff --git a/conformance/results/pyright/dataclasses_postinit.toml b/conformance/results/pyright/dataclasses_postinit.toml index 3ac995fe2..8dd024294 100644 --- a/conformance/results/pyright/dataclasses_postinit.toml +++ b/conformance/results/pyright/dataclasses_postinit.toml @@ -1,7 +1,4 @@ -conformant = "Partial" -notes = """ -Reports incorrect error for incompatible `__post_init__` method override. -""" +conformant = "Pass" output = """ dataclasses_postinit.py:19:40 - error: Dataclass __post_init__ method parameter type mismatch for field "y"   "str" is incompatible with "int" (reportGeneralTypeIssues) @@ -10,6 +7,4 @@ dataclasses_postinit.py:28:11 - error: Cannot access member "x" for type "DC1" dataclasses_postinit.py:29:11 - error: Cannot access member "y" for type "DC1"   Member "y" is an init-only field (reportGeneralTypeIssues) dataclasses_postinit.py:36:9 - error: Dataclass __post_init__ incorrect parameter count; number of InitVar fields is 2 (reportGeneralTypeIssues) -dataclasses_postinit.py:54:9 - error: Method "__post_init__" overrides class "DC3" in an incompatible manner -  Positional parameter count mismatch; base method has 2, but override has 3 (reportIncompatibleMethodOverride) """ diff --git a/conformance/results/pyright/qualifiers_annotated.toml b/conformance/results/pyright/qualifiers_annotated.toml new file mode 100644 index 000000000..820d04b68 --- /dev/null +++ b/conformance/results/pyright/qualifiers_annotated.toml @@ -0,0 +1,23 @@ +conformant = "Partial" +notes = """ +Does not reject all invalid type expressions within Annotated. +""" +output = """ +qualifiers_annotated.py:42:17 - error: Expected type expression but received "tuple[tuple[type[int], type[str]]]" (reportGeneralTypeIssues) +qualifiers_annotated.py:43:18 - error: Expected type expression but received "Generator[type[int], None, None]" (reportGeneralTypeIssues) +qualifiers_annotated.py:44:17 - error: Expected type expression but received "dict[str, str]" (reportGeneralTypeIssues) +qualifiers_annotated.py:44:17 - error: Dictionary expression not allowed in type annotation +qualifiers_annotated.py:45:17 - error: Call expression not allowed in type expression (reportGeneralTypeIssues) +qualifiers_annotated.py:46:17 - 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) +qualifiers_annotated.py:46:17 - error: Expected type expression but received "list[type[int]]" (reportGeneralTypeIssues) +qualifiers_annotated.py:47:17 - error: Ternary expression not allowed in type annotation +qualifiers_annotated.py:48:17 - error: "var1" is not defined (reportUndefinedVariable) +qualifiers_annotated.py:49:17 - error: Expected type expression but received "Literal[True]" (reportGeneralTypeIssues) +qualifiers_annotated.py:50:18 - error: Expected type expression but received "Literal[1]" (reportGeneralTypeIssues) +qualifiers_annotated.py:51:18 - error: Binary operator not allowed in type annotation +qualifiers_annotated.py:52:18 - error: Expected expression +qualifiers_annotated.py:52:18 - 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) +qualifiers_annotated.py:62:8 - error: Expected one type argument and one or more annotations for "Annotated" +""" diff --git a/conformance/results/pyright/qualifiers_final_annotation.toml b/conformance/results/pyright/qualifiers_final_annotation.toml new file mode 100644 index 000000000..ee0ee3729 --- /dev/null +++ b/conformance/results/pyright/qualifiers_final_annotation.toml @@ -0,0 +1,38 @@ +conformant = "Partial" +notes = """ +Does not treat use of Final name as if it was replaced by the literal in NamedTuple definition. +""" +output = """ +qualifiers_final_annotation.py:18:7 - error: Expected a single type argument after "Final" +qualifiers_final_annotation.py:54:14 - error: Cannot assign member "ID5" for type "ClassA*" +  Member "ID5" cannot be assigned through a class instance because it is a ClassVar +    Member "__set__" is unknown (reportGeneralTypeIssues) +qualifiers_final_annotation.py:62:19 - error: "Final" is not allowed in this context +qualifiers_final_annotation.py:63:19 - error: "Final" is not allowed in this context +qualifiers_final_annotation.py:65:14 - error: Cannot assign member "ID7" for type "ClassA*" +  Member "ID7" cannot be assigned through a class instance because it is a ClassVar +  "ID7" is declared as Final and cannot be reassigned +    Member "__set__" is unknown (reportGeneralTypeIssues) +qualifiers_final_annotation.py:67:14 - error: Cannot assign member "ID7" for type "ClassA*" +  Member "ID7" cannot be assigned through a class instance because it is a ClassVar +  "ID7" is declared as Final and cannot be reassigned +    Member "__set__" is unknown (reportGeneralTypeIssues) +qualifiers_final_annotation.py:81:8 - error: Cannot assign member "DEFAULT_ID" for type "type[ClassB]" +  "DEFAULT_ID" is declared as Final and cannot be reassigned +    Member "__set__" is unknown (reportGeneralTypeIssues) +qualifiers_final_annotation.py:94:5 - error: "BORDER_WIDTH" cannot be redeclared because parent class "ClassC" declares it as Final +qualifiers_final_annotation.py:107:22 - error: "Final" is not allowed in this context +qualifiers_final_annotation.py:108:19 - error: "ClassVar" is not allowed in this context +qualifiers_final_annotation.py:118:9 - error: "Final" is not allowed in this context +qualifiers_final_annotation.py:121:14 - error: "Final" is not allowed in this context +qualifiers_final_annotation.py:145:5 - error: "x" is declared as Final and cannot be reassigned (reportGeneralTypeIssues) +qualifiers_final_annotation.py:147:10 - error: "x" is declared as Final and cannot be reassigned (reportGeneralTypeIssues) +qualifiers_final_annotation.py:149:9 - error: "x" is declared as Final and cannot be reassigned (reportGeneralTypeIssues) +qualifiers_final_annotation.py:152:30 - error: "x" is declared as Final and cannot be reassigned (reportGeneralTypeIssues) +qualifiers_final_annotation.py:155:9 - error: "x" is declared as Final and cannot be reassigned (reportGeneralTypeIssues) +qualifiers_final_annotation.py:141:5 - error: "ID1" is declared as Final and cannot be reassigned +qualifiers_final_annotation.py:16:1 - error: "BAD1" is declared Final, but value is not assigned +qualifiers_final_annotation.py:71:1 - error: "RATE" is declared as Final and cannot be reassigned +qualifiers_final_annotation.py:34:5 - error: "ID2" is declared Final, but value is not assigned +qualifiers_final_annotation.py:38:5 - error: "ID3" is declared Final, but value is not assigned +""" diff --git a/conformance/results/pyright/qualifiers_final_decorator.toml b/conformance/results/pyright/qualifiers_final_decorator.toml new file mode 100644 index 000000000..231389648 --- /dev/null +++ b/conformance/results/pyright/qualifiers_final_decorator.toml @@ -0,0 +1,15 @@ +conformant = "Partial" +notes = """ +Does not report override of overloaded method marked @final. +Does not report error for non-method function marked @final. +""" +output = """ +qualifiers_final_decorator.py:8:6 - warning: Import "_qualifiers_final_decorator" could not be resolved from source (reportMissingModuleSource) +qualifiers_final_decorator.py:21:16 - error: Base class "Base1" is marked final and cannot be subclassed +qualifiers_final_decorator.py:56:9 - error: Method "method1" cannot override final method defined in class "Base2" +qualifiers_final_decorator.py:60:9 - error: Method "method2" cannot override final method defined in class "Base2" +qualifiers_final_decorator.py:64:9 - error: Method "method3" cannot override final method defined in class "Base2" +qualifiers_final_decorator.py:117:9 - error: Method "method" overrides class "Base5_2" in an incompatible manner +  Positional parameter count mismatch; base method has 2, but override has 1 (reportIncompatibleMethodOverride) +qualifiers_final_decorator.py:117:9 - error: Method "method" cannot override final method defined in class "Base5_2" +""" diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml index 281a67b40..30f4a8d74 100644 --- a/conformance/results/pyright/version.toml +++ b/conformance/results/pyright/version.toml @@ -1,2 +1,2 @@ -version = "pyright 1.1.343" -test_duration = 1.0995278358459473 +version = "pyright 1.1.344" +test_duration = 1.0010731220245361 diff --git a/conformance/results/pytype/qualifiers_annotated.toml b/conformance/results/pytype/qualifiers_annotated.toml new file mode 100644 index 000000000..bf0534a02 --- /dev/null +++ b/conformance/results/pytype/qualifiers_annotated.toml @@ -0,0 +1,27 @@ +conformant = "Partial" +notes = """ +Does not reject some illegal type expression forms used in Annotated. +Does not allow TypeVar to be used in type alias when wrapped with Annotated. +""" +output = """ +File "qualifiers_annotated.py", line 10, in : typing.NotRequired not supported yet [not-supported-yet] +File "qualifiers_annotated.py", line 10, in : typing.Required not supported yet [not-supported-yet] +File "qualifiers_annotated.py", line 41, in : Invalid type annotation '[int, str]' for Bad1 [invalid-annotation] + Not a type +File "qualifiers_annotated.py", line 42, in : Invalid type annotation '((int, str),)' for Bad2 [invalid-annotation] + Not a type +File "qualifiers_annotated.py", line 43, in : Invalid type annotation '' for Bad3 [invalid-annotation] + Not a type +File "qualifiers_annotated.py", line 44, in : Invalid type annotation "{'a': 'b'}" for Bad4 [invalid-annotation] + Not a type +File "qualifiers_annotated.py", line 48, in : Name 'var1' is not defined [name-error] +File "qualifiers_annotated.py", line 49, in : Invalid type annotation 'True' for Bad9 [invalid-annotation] + Not a type +File "qualifiers_annotated.py", line 50, in : Invalid type annotation '1' for Bad10 [invalid-annotation] + Not a type +File "qualifiers_annotated.py", line 52, in : Invalid type annotation '' for Bad12 [invalid-annotation] + Must be constant +File "qualifiers_annotated.py", line 62, in : Invalid type annotation 'Annotated' [invalid-annotation] + typing.Annotated must have at least 1 annotation +File "qualifiers_annotated.py", line 96, in : Invalid TypeVar: TypeVar('T') must be stored as 'T', not 'TA3' [invalid-typevar] +""" diff --git a/conformance/results/pytype/qualifiers_final_annotation.toml b/conformance/results/pytype/qualifiers_final_annotation.toml new file mode 100644 index 000000000..c8996bfe2 --- /dev/null +++ b/conformance/results/pytype/qualifiers_final_annotation.toml @@ -0,0 +1,45 @@ +conformant = "Partial" +notes = """ +Does not report Final variable with missing initialization. +Does not reject Final instance variable declared outside of __init__ method. +Does not reject modification of global variable declared Final. +Does not reject modification of local variable declared Final. +""" +output = """ +File "qualifiers_final_annotation.py", line 18, in : Invalid type annotation 'Final[str, int]' [invalid-annotation] + Invalid type annotation 'Final' + typing.Final must wrap a single type +File "qualifiers_final_annotation.py", line 18, in : Invalid type annotation 'Final' [invalid-annotation] + typing.Final must wrap a single type +File "qualifiers_final_annotation.py", line 54, in __init__: Assigning to attribute ID5, which was annotated with Final [final-error] +File "qualifiers_final_annotation.py", line 65, in method1: Assigning to attribute ID7, which was annotated with Final [final-error] +File "qualifiers_final_annotation.py", line 67, in method1: Assigning to attribute ID7, which was annotated with Final [final-error] +File "qualifiers_final_annotation.py", line 71, in : Assigning to variable RATE, which was annotated with Final [final-error] +File "qualifiers_final_annotation.py", line 81, in : Assigning to attribute DEFAULT_ID, which was annotated with Final [final-error] +File "qualifiers_final_annotation.py", line 93, in : Class ClassCChild overrides final class attribute BORDER_WIDTH, defined in base class ClassC [final-error] +File "qualifiers_final_annotation.py", line 107, in ClassD: Invalid type annotation 'ClassVar[Final]' [invalid-annotation] + Invalid use of typing.Final + Final may only be used as the outermost type in assignments or variable annotations. +File "qualifiers_final_annotation.py", line 107, in ClassD: Invalid use of typing.Final [final-error] + Final may only be used as the outermost type in assignments or variable annotations. +File "qualifiers_final_annotation.py", line 107, in ClassD: Type annotation for VALUE2 does not match type of assignment [annotation-type-mismatch] + Annotation: Final + Assignment: int +File "qualifiers_final_annotation.py", line 108, in ClassD: Type annotation for VALUE3 does not match type of assignment [annotation-type-mismatch] + Annotation: ClassVar + Assignment: int +File "qualifiers_final_annotation.py", line 118, in : Invalid type annotation 'list[Final[int]]' [invalid-annotation] + Invalid use of typing.Final + Final may only be used as the outermost type in assignments or variable annotations. +File "qualifiers_final_annotation.py", line 118, in : Invalid use of typing.Final [final-error] + Final may only be used as the outermost type in assignments or variable annotations. +File "qualifiers_final_annotation.py", line 121, in : Invalid use of typing.Final [final-error] + Final may only be used as the outermost type in assignments or variable annotations. +File "qualifiers_final_annotation.py", line 134, in : Invalid keyword argument a to function N.__new__ [wrong-keyword-args] + Expected: (cls, x, y) + Actually passed: (cls, a) +File "qualifiers_final_annotation.py", line 135, in : Function N.__new__ was called with the wrong arguments [wrong-arg-types] + Expected: (cls, x: int, ...) + Actually passed: (cls, x: str, ...) +File "qualifiers_final_annotation.py", line 145, in func2: Assigning to variable x, which was annotated with Final [final-error] +""" diff --git a/conformance/results/pytype/qualifiers_final_decorator.toml b/conformance/results/pytype/qualifiers_final_decorator.toml new file mode 100644 index 000000000..f86be3d80 --- /dev/null +++ b/conformance/results/pytype/qualifiers_final_decorator.toml @@ -0,0 +1,31 @@ +conformant = "Partial" +notes = """ +Does not report error for overloaded @final method defined in stub file. +""" +output = """ +File "qualifiers_final_decorator.py", line 8, in : Can't find module '_qualifiers_final_decorator'. [import-error] +File "qualifiers_final_decorator.py", line 21, in : Cannot subclass final class: Base1 [final-error] +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 method4, 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 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 method3, defined in base class Base2 [final-error] +File "qualifiers_final_decorator.py", line 76, in method4: bad return type [bad-return-type] + Expected: str + Actually returned: int +File "qualifiers_final_decorator.py", line 89, in method: bad return type [bad-return-type] + Expected: str + Actually returned: int +File "qualifiers_final_decorator.py", line 102, in method: bad return type [bad-return-type] + Expected: str + Actually returned: int +File "qualifiers_final_decorator.py", line 116, in : Class Derived5 overrides final method method, defined in base class Base5_2 [final-error] +File "qualifiers_final_decorator.py", line 117, in Derived5: Overriding method signature mismatch [signature-mismatch] + Base signature: 'def Base5_2.method(self, v: int) -> None'. + Subclass signature: 'def Derived5.method(self) -> None'. + Not enough positional parameters in overriding method. +File "qualifiers_final_decorator.py", line 125, in : Cannot apply @final decorator to func1 [final-error] + @final can only be applied to classes and methods. +""" diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml index 6bfa30f74..92ec41634 100644 --- a/conformance/results/pytype/version.toml +++ b/conformance/results/pytype/version.toml @@ -1,2 +1,2 @@ version = "pytype 2023.12.18" -test_duration = 51.5667941570282 +test_duration = 54.82685399055481 diff --git a/conformance/results/results.html b/conformance/results/results.html index b33903903..02ebc00cd 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -127,7 +127,7 @@

Python Type System Conformance Test Results

-
mypy 1.8.0(0.40sec) +
mypy 1.8.0(0.48sec)
@@ -144,6 +144,12 @@

Python Type System Conformance Test Results

+ + + + + @@ -198,7 +204,7 @@

Python Type System Conformance Test Results

     generics_self_usagePass
+Type qualifiers
     qualifiers_annotatedPartialDoes not allow ClassVar to be nested within Annotated.
Does not allow Final to be nested within Annotated.
Does not allow Required and NotRequired to be nested within Annotated.
     qualifiers_final_annotationPartialDoes not treat use of Final name as if it was replaced by the literal in NamedTuple definition.
Does not allow conditional assignment of Final instance variable in __init__ method.
Does not allow redefinition of private class variable that is marked Final in parent class.
Does not report modification of local Final variable via "for" statement.
     qualifiers_final_decoratorPass
Type aliases
     aliases_explicitPartialDoes not reject specialization of type alias that has already been implicitly specialized.
     aliases_implicitPass
     narrowing_typeguardPass
-
pyright 1.1.343(1.01sec) +
pyright 1.1.344(1.00sec)
@@ -215,13 +221,19 @@

Python Type System Conformance Test Results

+ + + + + - - - + + + - - + + - + @@ -245,7 +257,7 @@

Python Type System Conformance Test Results

- + @@ -269,7 +281,7 @@

Python Type System Conformance Test Results

     generics_self_usagePass
+Type qualifiers
     qualifiers_annotatedPartialDoes not reject all invalid type expressions within Annotated.
     qualifiers_final_annotationPartialDoes not treat use of Final name as if it was replaced by the literal in NamedTuple definition.
     qualifiers_final_decoratorPartialDoes not report override of overloaded method marked @final.
Does not report error for non-method function marked @final.
Type aliases
     aliases_explicitPartialIncorrectly evaluates type of specialized type alias parameterized with ParamSpec.
Allows some illegal annotation forms to be interpreted as valid type aliases.
     aliases_implicitPartialIncorrectly evaluates type of specialized type alias parameterized with ParamSpec.
Allows some illegal annotation forms to be interpreted as valid type aliases.
     aliases_newtypePartialDoes not reject use of NewType in `isinstance` call.
Does not report inconsistency between name of NewType and assigned identifier name.
Does not reject use of NewType with TypedDict class.
Does not reject use of NewType with another NewType.
Does not reject use of NewType with Any.
     aliases_explicitPass
     aliases_implicitPass
     aliases_newtypePass
     aliases_recursivePass
     aliases_type_statementPartialDoes not reject binary expression when used in type alias definition.
     aliases_typealiastypePartialDoes not reject type alias expression that uses TypeVar that is not in scope and not in `type_params`.
Does not allow access to `__value__` attribute of type alias.
Allows some illegal annotation forms to be interpreted as valid type aliases.
     aliases_type_statementPass
     aliases_typealiastypePass
     aliases_variancePass
@@ -235,7 +247,7 @@

Python Type System Conformance Test Results

Callables
     callables_annotationPass
     callables_kwargsPass
     callables_protocolPartialDoes not report type incompatibility for callback protocol with positional-only parameters.
     callables_protocolPass
Dataclasses
     dataclasses_inheritancePass
     dataclasses_kwonlyPass
     dataclasses_orderPass
     dataclasses_postinitPartialReports incorrect error for incompatible `__post_init__` method override.
     dataclasses_postinitPass
     dataclasses_slotsPass
     dataclasses_transform_classPass
     dataclasses_transform_fieldPass
     narrowing_typeguardPass
-
pyre 0.9.19(1.40sec) +
pyre 0.9.19(1.67sec)
@@ -286,6 +298,12 @@

Python Type System Conformance Test Results

+ + + + + @@ -340,7 +358,7 @@

Python Type System Conformance Test Results

     generics_self_usageUnsupportedDoes not understand `Self` type.
+Type qualifiers
     qualifiers_annotatedPartialDoes not reject Annotated with a single parameter.
     qualifiers_final_annotationPartialDoes not report Final variable with missing initialization in module scope.
Does not report error for invalid nesting of Final and ClassVar.
Does not treat use of Final name as if it was replaced by the literal in NamedTuple definition.
     qualifiers_final_decoratorPartialReports error for overloaded method implementation marked @final if its overloads do not.
Does not report error for overloaded @final method defined in stub file.
Type aliases
     aliases_explicitPartialIncorrectly reports error for type alias defined with ParamSpec.
Incorrectly rejects some valid type aliases when used in annotations.
Incorrectly evaluates generic type alias with ParamSpec with missing type argument.
Does not report some illegal annotation forms as invalid type aliases.
Does not report invalid specialization of generic type aliases.
Incorrectly rejects import alias of `TypeAlias` when used to define type alias.
Does not report invalid specialization of already-specialized generic type alias.
     aliases_implicitPartialIncorrectly reports error for type alias defined with ParamSpec.
Incorrectly rejects some valid type aliases when used in annotations.
Incorrectly evaluates generic type alias with ParamSpec with missing type argument.
Does not report invalid specialization of generic type aliases.
Does not report error for attempt to instantiate union type alias.
Does not report invalid specialization of already-specialized generic type alias.
     narrowing_typeguardPartialDoes not support `tuple` in `assert_type` call.
Does not reject TypeGuard method with too few parameters.
-
pytype 2023.12.18(51.57sec) +
pytype 2023.12.18(54.83sec)
@@ -357,6 +375,12 @@

Python Type System Conformance Test Results

+ + + + + diff --git a/conformance/tests/_qualifiers_final_decorator.pyi b/conformance/tests/_qualifiers_final_decorator.pyi new file mode 100644 index 000000000..63577adb8 --- /dev/null +++ b/conformance/tests/_qualifiers_final_decorator.pyi @@ -0,0 +1,29 @@ +""" +Support stub file for @final tests. +""" + +from typing import final, overload + + +class Base3: + # > For overloaded methods, @final should be placed on the implementation + # > (or on the first overload, for stubs): + @final + @overload + def method(self, x: int) -> int: + ... + + @overload + def method(self, x: str) -> str: + ... + +class Base4: + # (Swap the order of overload and final decorators.) + @overload + @final + def method(self, x: int) -> int: + ... + + @overload + def method(self, x: str) -> str: + ... diff --git a/conformance/tests/qualifiers_annotated.py b/conformance/tests/qualifiers_annotated.py new file mode 100644 index 000000000..efb5d2941 --- /dev/null +++ b/conformance/tests/qualifiers_annotated.py @@ -0,0 +1,96 @@ +""" +Tests the typing.Annotated special form. +""" + +# Specification: https://typing.readthedocs.io/en/latest/spec/qualifiers.html#annotated + +# > The first argument to Annotated must be a valid type + +from dataclasses import InitVar, dataclass +from typing import ( + Annotated, + Any, + Callable, + ClassVar, + Final, + Literal, + NotRequired, + Required, + TypeAlias, + TypeVar, + TypedDict, + Union, +) + + +Good1: Annotated[Union[int, str], ""] +Good2: Annotated[int | None, ""] +Good3: Annotated[list[int], ""] +Good4: Annotated[Any, ""] +Good5: Annotated[tuple[int, ...] | list[int], ""] +Good6: Annotated[Callable[..., int], ""] +Good7: Annotated["int | str", ""] +Good8: Annotated[list["int | str"], ""] +Good9: Annotated[Literal[3, 4, 5, None], x:=3] + + +async def func3() -> None: + Good10: Annotated[str, await func3()] + + +Bad1: Annotated[[int, str], ""] # Type error: invalid type expression +Bad2: Annotated[((int, str),), ""] # Type error: invalid type expression +Bad3: Annotated[[int for i in range(1)], ""] # Type error: invalid type expression +Bad4: Annotated[{"a": "b"}, ""] # Type error: invalid type expression +Bad5: Annotated[(lambda: int)(), ""] # Type error: invalid type expression +Bad6: Annotated[[int][0], ""] # Type error: invalid type expression +Bad7: Annotated[int if 1 < 3 else str, ""] # Type error: invalid type expression +Bad8: Annotated[var1, ""] # Type error: invalid type expression +Bad9: Annotated[True, ""] # Type error: invalid type expression +Bad10: Annotated[1, ""] # Type error: invalid type expression +Bad11: Annotated[list or set, ""] # Type error: invalid type expression +Bad12: Annotated[f"{'int'}", ""] # Type error: invalid type expression + + +# > Multiple type annotations are supported (Annotated supports variadic arguments): + +Multi1: Annotated[int | str, 3, ""] +Multi2: Annotated[int | str, 3, "", lambda x: x, max(1, 2)] + +# > Annotated must be called with at least two arguments ( Annotated[int] is not valid) + +Bad13: Annotated[int] # Type error: requires at least two arguments + + +# Annotated types can be nested + +Nested1: list[Annotated[dict[str, Annotated[str, ""]], ""]] +Nested2: Annotated[list[Annotated[dict[str, Annotated[Literal[1, 2, 3], ""]], ""]], ""] + + +class ClassA: + a: ClassVar[Annotated[int, ""]] = 1 + b: Annotated[ClassVar[int], ""] = 1 + c: Final[Annotated[int, ""]] = 1 + d: Annotated[Final[int], ""] = 1 + + +@dataclass +class ClassB: + a: InitVar[Annotated[int, ""]] + b: Annotated[InitVar[int], ""] + + +class ClassC(TypedDict): + a: Annotated[Required[int], ""] + b: Required[Annotated[int, ""]] + c: Annotated[NotRequired[int], ""] + d: NotRequired[Annotated[int, ""]] + + +TA1: TypeAlias = Annotated[int | str, ""] +TA2 = Annotated[Literal[1, 2], ""] + +T = TypeVar("T") + +TA3 = Annotated[T, ""] diff --git a/conformance/tests/qualifiers_final_annotation.py b/conformance/tests/qualifiers_final_annotation.py new file mode 100644 index 000000000..876e3a910 --- /dev/null +++ b/conformance/tests/qualifiers_final_annotation.py @@ -0,0 +1,155 @@ +""" +Tests the typing.Final special form. +""" + +from typing import ClassVar, Final, Literal, NamedTuple, assert_type + +# Specification: https://typing.readthedocs.io/en/latest/spec/qualifiers.html#id1 + +ID1: Final[int] = 1 + +ID2: Final = 1 +assert_type(ID2, Literal[1]) + +# > If the right hand side is omitted, there must be an explicit type argument to Final. + +BAD1: Final # Type error: missing assignment + +BAD2: Final[str, int] = "" # Type error: only one type argument allowed + +# > There can be at most one final declaration per module or class for a given +# > attribute. + +# > As self.id: Final = 1 (also optionally with a type in square brackets). +# > This is allowed only in __init__ methods, so that the final instance +# > attribute is assigned only once when an instance is created. + + +class ClassA: + ID1: Final = 1 + + # > In class bodies and stub files you can omit the right hand side and just + # > write ID: Final[float]. If the right hand side is omitted, there must be + # > an explicit type argument to Final. + ID2: Final # Type error: missing initialization + + # > A final attribute declared in a class body without an initializer must + # > be initialized in the __init__ method (except in stub files): + ID3: Final[int] # Type error: missing initialization + + ID4: Final[int] # OK because initialized in __init__ + + ID5: Final[int] = 0 + + ID6: Final[int] + + ID7: Final[int] = 0 + + def __init__(self, cond: bool) -> None: + self.id1: Final = 1 + self.id2: Final[int] = 1 + + self.ID4 = 1 + + self.ID5 = 0 # Type error: Already initialized + + if cond: + self.ID6 = 1 + else: + self.ID6 = 2 + + def method1(self) -> None: + self.id3: Final = 1 # Type error: not allowed outside of __init__ method. + self.id4: Final[int] = 1 # Type error: not allowed outside of __init__ method. + + self.ID7 = 0 # Type error: cannot modify Final value + + self.ID7 += 1 # Type error: cannot modify Final value + + +RATE: Final = 3000 +RATE = 300 # Type error: Cannot redefine Final value + +# > There can’t be separate class-level and instance-level constants +# > with the same name. + + +class ClassB: + DEFAULT_ID: Final = 0 + + +ClassB.DEFAULT_ID = 0 # Type error: Cannot redefined value + + +# > A type checker should prevent final attributes from being overridden in a subclass: + + +class ClassC: + BORDER_WIDTH: Final = 2.5 + + __private: Final = 0 + + +class ClassCChild(ClassC): + BORDER_WIDTH = 2.5 # Type error: Cannot override Final value + + __private = 0 # OK + + +# > Type checkers should infer a final attribute that is initialized in a class +# > body as being a class variable. Variables should not be annotated with both +# > ClassVar and Final. + + +class ClassD: + VALUE1: Final = 1 + + VALUE2: ClassVar[Final] = 1 # Type error: Final cannot be used with ClassVar + VALUE3: Final[ClassVar] = 1 # Type error: Final cannot be used with ClassVar + + +ClassD.VALUE1 # OK + + +# > Final may only be used as the outermost type in assignments or variable +# > annotations. Using it in any other position is an error. In particular, +# > Final can’t be used in annotations for function arguments. + +x: list[Final[int]] = [] # Type error + + +def func1(x: Final[list[int]]) -> None: # Type error + ... + + +# > Type checkers should treat uses of a final name that was initialized with +# > a literal as if it was replaced by the literal. For example, the following +# > should be allowed: + +X: Final = "x" +Y: Final = "y" +N = NamedTuple("N", [(X, int), (Y, int)]) + +N(x=3, y=4) # OK +N(a=1) # Type error +N(x="", y="") # Type error + + +def func2() -> None: + global ID1 + + ID1 = 2 # Type error: cannot modify Final value + + x: Final = 3 + + x += 1 # Type error: cannot modify Final value + + a = (x := 4) # Type error: cannot modify Final value + + for x in [1, 2, 3]: # Type error: cannot modify Final value + pass + + with open("FileName") as x: # Type error: cannot modify Final value + pass + + (a, x) = (1, 2) # Type error: cannot modify Final value diff --git a/conformance/tests/qualifiers_final_decorator.py b/conformance/tests/qualifiers_final_decorator.py new file mode 100644 index 000000000..12d805150 --- /dev/null +++ b/conformance/tests/qualifiers_final_decorator.py @@ -0,0 +1,126 @@ +""" +Tests the @final decorator. +""" + +# Specification: https://typing.readthedocs.io/en/latest/spec/qualifiers.html#final + +from typing import final, overload +from _qualifiers_final_decorator import Base3, Base4 + +# > A type checker should prohibit any class decorated with @final from being +# > subclassed and any method decorated with @final from being overridden in a +# > subclass. The method decorator version may be used with all of instance +# > methods, class methods, static methods, and properties. + + +@final +class Base1: + ... + + +class Derived1(Base1): # Type error: Cannot inherit from final class "Base" + ... + + +class Base2: + @final + def method1(self) -> None: + pass + + @final + @classmethod + def method2(cls) -> None: + pass + + @final + @staticmethod + def method3() -> None: + pass + + # > For overloaded methods, @final should be placed on the implementation. + + @overload + def method4(self, x: int) -> int: + ... + + @overload + def method4(self, x: str) -> str: + ... + + @final + def method4(self, x: int | str) -> int | str: + return 0 + + +class Derived2(Base2): + def method1(self) -> None: # Type error + pass + + @classmethod + def method2(cls) -> None: # Type error + pass + + @staticmethod + def method3() -> None: # Type error + pass + + @overload + def method4(self, x: int) -> int: + ... + + @overload + def method4(self, x: str) -> str: + ... + + def method4(self, x: int | str) -> int | str: # Type error + return 0 + + +class Derived3(Base3): + @overload + def method(self, x: int) -> int: + ... + + @overload + def method(self, x: str) -> str: + ... + + def method(self, x: int | str) -> int | str: # Type error + return 0 + + +class Derived4(Base4): + @overload + def method(self, x: int) -> int: + ... + + @overload + def method(self, x: str) -> str: + ... + + def method(self, x: int | str) -> int | str: # Type error + return 0 + + +class Base5_1: + ... + + +class Base5_2: + @final + def method(self, v: int) -> None: + ... + + +# Test multiple inheritance case. +class Derived5(Base5_1, Base5_2): + def method(self) -> None: # Type error + ... + + +# > It is an error to use @final on a non-method function. + + +@final +def func1() -> int: # Type error: not allowed on non-method function. + return 0
     generics_self_usageUnsupportedDoes not understand `Self` type.
+Type qualifiers
     qualifiers_annotatedPartialDoes not reject some illegal type expression forms used in Annotated.
Does not allow TypeVar to be used in type alias when wrapped with Annotated.
     qualifiers_final_annotationPartialDoes not report Final variable with missing initialization.
Does not reject Final instance variable declared outside of __init__ method.
Does not reject modification of global variable declared Final.
Does not reject modification of local variable declared Final.
     qualifiers_final_decoratorPartialDoes not report error for overloaded @final method defined in stub file.
Type aliases
     aliases_explicitPartialIncorrectly reports error for type alias defined with ParamSpec.
Does not report invalid specialization of generic type alias with bound TypeVar.
Incorrectly evaluates generic type alias with ParamSpec with missing type argument.
Does not report some illegal annotation forms as invalid type aliases.
Does not report invalid specialization of already-specialized generic type alias.
     aliases_implicitPartialIncorrectly reports error for type alias defined with ParamSpec.
Does not report invalid specialization of generic type alias with bound TypeVar.
Incorrectly evaluates generic type alias with ParamSpec with missing type argument.
Allows some illegal annotation forms to be interpreted as valid type aliases.
Does not report invalid specialization of already-specialized generic type alias.