From d9961b268ef676ae20ddb239b4db6dcb042f1c9c Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 30 Apr 2026 21:22:50 -0700 Subject: [PATCH 1/5] Add sentinels (PEP 661) to the spec --- .../results/mypy/specialtypes_sentinels.toml | 23 +++++++++++ .../pyrefly/specialtypes_sentinels.toml | 23 +++++++++++ .../pyright/specialtypes_sentinels.toml | 24 +++++++++++ conformance/results/results.html | 7 ++++ .../results/ty/specialtypes_sentinels.toml | 21 ++++++++++ .../results/zuban/specialtypes_sentinels.toml | 25 ++++++++++++ conformance/tests/specialtypes_sentinels.py | 37 +++++++++++++++++ docs/spec/annotations.rst | 2 +- docs/spec/special-types.rst | 40 +++++++++++++++++++ 9 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 conformance/results/mypy/specialtypes_sentinels.toml create mode 100644 conformance/results/pyrefly/specialtypes_sentinels.toml create mode 100644 conformance/results/pyright/specialtypes_sentinels.toml create mode 100644 conformance/results/ty/specialtypes_sentinels.toml create mode 100644 conformance/results/zuban/specialtypes_sentinels.toml create mode 100644 conformance/tests/specialtypes_sentinels.py diff --git a/conformance/results/mypy/specialtypes_sentinels.toml b/conformance/results/mypy/specialtypes_sentinels.toml new file mode 100644 index 000000000..23cf9129b --- /dev/null +++ b/conformance/results/mypy/specialtypes_sentinels.toml @@ -0,0 +1,23 @@ +conformant = "Unsupported" +conformance_automated = "Fail" +errors_diff = """ +Line 33: Expected 1 errors +Line 36: Expected 1 errors +Line 18: Unexpected errors ['specialtypes_sentinels.py:18: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20: error: Expression is of type "Any", not MISSING? [assert-type]', 'specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type]', 'specialtypes_sentinels.py:26: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] +""" +output = """ +specialtypes_sentinels.py:15: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] +specialtypes_sentinels.py:18: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:18: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:20: error: Expression is of type "Any", not MISSING? [assert-type] +specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:24: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:26: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type] +specialtypes_sentinels.py:26: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:26: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +""" diff --git a/conformance/results/pyrefly/specialtypes_sentinels.toml b/conformance/results/pyrefly/specialtypes_sentinels.toml new file mode 100644 index 000000000..082c59e51 --- /dev/null +++ b/conformance/results/pyrefly/specialtypes_sentinels.toml @@ -0,0 +1,23 @@ +conformant = "Unsupported" +conformance_automated = "Fail" +errors_diff = """ +Line 33: Expected 1 errors +Line 36: Expected 1 errors +Line 18: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] +Line 20: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] +Line 22: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] +Line 24: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] +Line 26: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] +Line 28: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] +""" +output = """ +ERROR specialtypes_sentinels.py:15:20-27: Default `Sentinel` is not assignable to parameter `x` with type `int` [bad-function-definition] +ERROR specialtypes_sentinels.py:18:14-27: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] +ERROR specialtypes_sentinels.py:20:20-32: assert_type(Sentinel, Unknown) failed [assert-type] +ERROR specialtypes_sentinels.py:20:24-31: Expected a type form, got instance of `Sentinel` [not-a-type] +ERROR specialtypes_sentinels.py:22:20-28: assert_type(Unknown, int) failed [assert-type] +ERROR specialtypes_sentinels.py:24:14-32: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] +ERROR specialtypes_sentinels.py:26:20-37: assert_type(Sentinel, Unknown) failed [assert-type] +ERROR specialtypes_sentinels.py:26:24-36: Expected a type form, got instance of `Sentinel` [not-a-type] +ERROR specialtypes_sentinels.py:28:20-28: assert_type(Unknown, int) failed [assert-type] +""" diff --git a/conformance/results/pyright/specialtypes_sentinels.toml b/conformance/results/pyright/specialtypes_sentinels.toml new file mode 100644 index 000000000..271435b0b --- /dev/null +++ b/conformance/results/pyright/specialtypes_sentinels.toml @@ -0,0 +1,24 @@ +conformant = "Unsupported" +conformance_automated = "Fail" +errors_diff = """ +Line 33: Expected 1 errors +Line 36: Expected 1 errors +Line 18: Unexpected errors ['specialtypes_sentinels.py:18:20 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:20:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:26:28 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] +""" +output = """ +specialtypes_sentinels.py:15:20 - error: Expression of type "Sentinel" cannot be assigned to parameter of type "int" +  "Sentinel" is not assignable to "int" (reportArgumentType) +specialtypes_sentinels.py:18:20 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:20:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:20:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:22:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:24:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:26:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:26:28 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:28:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) +""" diff --git a/conformance/results/results.html b/conformance/results/results.html index 1740f4cfc..e74e87e3f 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -262,6 +262,13 @@

Python Type System Conformance Test Results

Pass Pass +     specialtypes_sentinels +Unsupported +Unsupported +Unsupported +Unsupported +Unsupported +      specialtypes_type
Partial

Does not treat `type` same as `type[Any]` for assert_type.

Does not allow access to unknown attributes from object of type `type[Any]`.

Pass diff --git a/conformance/results/ty/specialtypes_sentinels.toml b/conformance/results/ty/specialtypes_sentinels.toml new file mode 100644 index 000000000..33eb77eef --- /dev/null +++ b/conformance/results/ty/specialtypes_sentinels.toml @@ -0,0 +1,21 @@ +conformant = "Unsupported" +conformance_automated = "Fail" +errors_diff = """ +Line 33: Expected 1 errors +Line 36: Expected 1 errors +Line 18: Unexpected errors ['specialtypes_sentinels.py:18:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] +""" +output = """ +specialtypes_sentinels.py:15:11: error[invalid-parameter-default] Default value of type `Sentinel` is not assignable to annotated parameter type `int` +specialtypes_sentinels.py:18:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:20:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` +specialtypes_sentinels.py:22:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` +specialtypes_sentinels.py:24:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:26:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` +specialtypes_sentinels.py:28:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` +""" diff --git a/conformance/results/zuban/specialtypes_sentinels.toml b/conformance/results/zuban/specialtypes_sentinels.toml new file mode 100644 index 000000000..f26fe3a11 --- /dev/null +++ b/conformance/results/zuban/specialtypes_sentinels.toml @@ -0,0 +1,25 @@ +conformant = "Unsupported" +conformance_automated = "Fail" +errors_diff = """ +Line 33: Expected 1 errors +Line 36: Expected 1 errors +Line 18: Unexpected errors ['specialtypes_sentinels.py:18: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22: error: Expression is of type "int | Any", not "int" [misc]'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28: error: Expression is of type "int | Any", not "int" [misc]'] +""" +output = """ +specialtypes_sentinels.py:15: error: Incompatible default for argument "x" (default has type "Sentinel", argument has type "int") [assignment] +specialtypes_sentinels.py:18: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:18: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:22: error: Expression is of type "int | Any", not "int" [misc] +specialtypes_sentinels.py:24: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:26: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:26: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:28: error: Expression is of type "int | Any", not "int" [misc] +""" diff --git a/conformance/tests/specialtypes_sentinels.py b/conformance/tests/specialtypes_sentinels.py new file mode 100644 index 000000000..72be77ab6 --- /dev/null +++ b/conformance/tests/specialtypes_sentinels.py @@ -0,0 +1,37 @@ +from unittest.mock import sentinel + +from typing_extensions import Sentinel, assert_type + +# > Sentinel objects may be used in type annotations if they are defined using +# > a simple assignment of the form ``NAME = sentinel('NAME')`` in the +# > global scope or in a class body that is not within a function. + +MISSING = Sentinel("MISSING") + +class Cls: + IN_CLASS = Sentinel("Cls.IN_CLASS") + + +def func1(x: int = MISSING) -> None: # E: incompatible default + pass + +def func2(x: int | MISSING = MISSING) -> None: + if x is MISSING: + assert_type(x, MISSING) + else: + assert_type(x, int) + +def func3(x: int | Cls.IN_CLASS = Cls.IN_CLASS) -> None: + if x is Cls.IN_CLASS: + assert_type(x, Cls.IN_CLASS) + else: + assert_type(x, int) + + +func2(1) # ok +func2(MISSING) # ok +func2(Cls.IN_CLASS) # E: incompatible argument + +func3(1) # ok +func3(MISSING) # E: incompatible argument +func3(Cls.IN_CLASS) # ok diff --git a/docs/spec/annotations.rst b/docs/spec/annotations.rst index 085d9277b..558b9b700 100644 --- a/docs/spec/annotations.rst +++ b/docs/spec/annotations.rst @@ -139,7 +139,7 @@ The following grammar describes the allowed elements of type and annotation expr : | : | name : (where name must refer to a valid in-scope class, - : type alias, or TypeVar) + : type alias, TypeVar, or sentinel object) : | name '[' (`maybe_unpacked` | `type_expression_list`) : (',' (`maybe_unpacked` | `type_expression_list`))* ']' : (the `type_expression_list` form is valid only when diff --git a/docs/spec/special-types.rst b/docs/spec/special-types.rst index eab658b07..d1ea06e1a 100644 --- a/docs/spec/special-types.rst +++ b/docs/spec/special-types.rst @@ -53,6 +53,46 @@ are highly dynamic. When used in a type hint, the expression ``None`` is considered equivalent to ``type(None)``. +.. _ `sentinels`: + +Sentinels +--------- + +Sentinel objects may be used in type annotations to represent themselves:: + + MISSING = sentinel('MISSING') + OTHER = sentinel('OTHER') + + def f(x: int | MISSING = MISSING) -> int: + if x is MISSING: + return 0 + return x + + f(OTHER) # Error, OTHER is not an int or MISSING + f(MISSING) # OK, MISSING is a valid argument + +Sentinels may be created using the ``sentinel()`` built-in in Python 3.15 +and higher. ``typing_extensions`` provides a backport of this function. For +historical reasons the object was first introduced under the name +``typing_extensions.Sentinel``, and later ``typing_extensions.sentinel`` was +added as an alias; type checkers should support both. + +Sentinel objects may be used in type annotations if they are defined using +a simple assignment of the form ``NAME = sentinel('NAME')`` in the +global scope or in a class body that is not within a function. The name of the +variable need not match the string argument passed to ``sentinel()`` but it is +conventional to do so for names in the global scope. + +Type checkers must support narrowing union types involving sentinels using the +``is`` or ``is not`` operators:: + + def g(x: int | MISSING) -> None: + if x is MISSING: + assert_type(x, MISSING) + else: + assert_type(x, int) + + .. _`noreturn`: ``NoReturn`` From de6d9eabaa5cc288f0ded5710e569669ad9415b5 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 30 Apr 2026 21:31:58 -0700 Subject: [PATCH 2/5] . --- .../results/mypy/specialtypes_sentinels.toml | 30 ++++++++-------- .../pyrefly/specialtypes_sentinels.toml | 30 ++++++++-------- .../pyright/specialtypes_sentinels.toml | 30 ++++++++-------- .../results/ty/specialtypes_sentinels.toml | 26 +++++++------- .../results/zuban/specialtypes_sentinels.toml | 34 +++++++++---------- conformance/tests/specialtypes_sentinels.py | 5 ++- docs/spec/special-types.rst | 2 +- 7 files changed, 80 insertions(+), 77 deletions(-) diff --git a/conformance/results/mypy/specialtypes_sentinels.toml b/conformance/results/mypy/specialtypes_sentinels.toml index 23cf9129b..acfe9d228 100644 --- a/conformance/results/mypy/specialtypes_sentinels.toml +++ b/conformance/results/mypy/specialtypes_sentinels.toml @@ -1,23 +1,23 @@ conformant = "Unsupported" conformance_automated = "Fail" errors_diff = """ -Line 33: Expected 1 errors Line 36: Expected 1 errors -Line 18: Unexpected errors ['specialtypes_sentinels.py:18: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 20: Unexpected errors ['specialtypes_sentinels.py:20: error: Expression is of type "Any", not MISSING? [assert-type]', 'specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 24: Unexpected errors ['specialtypes_sentinels.py:24: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] -Line 26: Unexpected errors ['specialtypes_sentinels.py:26: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type]', 'specialtypes_sentinels.py:26: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] +Line 39: Expected 1 errors +Line 21: Unexpected errors ['specialtypes_sentinels.py:21: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 23: Unexpected errors ['specialtypes_sentinels.py:23: error: Expression is of type "Any", not MISSING? [assert-type]', 'specialtypes_sentinels.py:23: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 27: Unexpected errors ['specialtypes_sentinels.py:27: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] +Line 29: Unexpected errors ['specialtypes_sentinels.py:29: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type]', 'specialtypes_sentinels.py:29: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] """ output = """ specialtypes_sentinels.py:15: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] -specialtypes_sentinels.py:18: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:18: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:20: error: Expression is of type "Any", not MISSING? [assert-type] -specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:24: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:26: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type] -specialtypes_sentinels.py:26: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:26: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:21: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:21: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:23: error: Expression is of type "Any", not MISSING? [assert-type] +specialtypes_sentinels.py:23: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:23: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:27: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:27: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:29: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type] +specialtypes_sentinels.py:29: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:29: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases """ diff --git a/conformance/results/pyrefly/specialtypes_sentinels.toml b/conformance/results/pyrefly/specialtypes_sentinels.toml index 082c59e51..0d33bb8e4 100644 --- a/conformance/results/pyrefly/specialtypes_sentinels.toml +++ b/conformance/results/pyrefly/specialtypes_sentinels.toml @@ -1,23 +1,23 @@ conformant = "Unsupported" conformance_automated = "Fail" errors_diff = """ -Line 33: Expected 1 errors Line 36: Expected 1 errors -Line 18: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] -Line 20: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] -Line 22: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] -Line 24: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] -Line 26: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] -Line 28: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] +Line 39: Expected 1 errors +Line 21: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] +Line 23: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] +Line 25: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] +Line 27: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] +Line 29: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] +Line 31: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] """ output = """ ERROR specialtypes_sentinels.py:15:20-27: Default `Sentinel` is not assignable to parameter `x` with type `int` [bad-function-definition] -ERROR specialtypes_sentinels.py:18:14-27: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] -ERROR specialtypes_sentinels.py:20:20-32: assert_type(Sentinel, Unknown) failed [assert-type] -ERROR specialtypes_sentinels.py:20:24-31: Expected a type form, got instance of `Sentinel` [not-a-type] -ERROR specialtypes_sentinels.py:22:20-28: assert_type(Unknown, int) failed [assert-type] -ERROR specialtypes_sentinels.py:24:14-32: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] -ERROR specialtypes_sentinels.py:26:20-37: assert_type(Sentinel, Unknown) failed [assert-type] -ERROR specialtypes_sentinels.py:26:24-36: Expected a type form, got instance of `Sentinel` [not-a-type] -ERROR specialtypes_sentinels.py:28:20-28: assert_type(Unknown, int) failed [assert-type] +ERROR specialtypes_sentinels.py:21:14-27: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] +ERROR specialtypes_sentinels.py:23:20-32: assert_type(Sentinel, Unknown) failed [assert-type] +ERROR specialtypes_sentinels.py:23:24-31: Expected a type form, got instance of `Sentinel` [not-a-type] +ERROR specialtypes_sentinels.py:25:20-28: assert_type(Unknown, int) failed [assert-type] +ERROR specialtypes_sentinels.py:27:14-32: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] +ERROR specialtypes_sentinels.py:29:20-37: assert_type(Sentinel, Unknown) failed [assert-type] +ERROR specialtypes_sentinels.py:29:24-36: Expected a type form, got instance of `Sentinel` [not-a-type] +ERROR specialtypes_sentinels.py:31:20-28: assert_type(Unknown, int) failed [assert-type] """ diff --git a/conformance/results/pyright/specialtypes_sentinels.toml b/conformance/results/pyright/specialtypes_sentinels.toml index 271435b0b..f9f2ad225 100644 --- a/conformance/results/pyright/specialtypes_sentinels.toml +++ b/conformance/results/pyright/specialtypes_sentinels.toml @@ -1,24 +1,24 @@ conformant = "Unsupported" conformance_automated = "Fail" errors_diff = """ -Line 33: Expected 1 errors Line 36: Expected 1 errors -Line 18: Unexpected errors ['specialtypes_sentinels.py:18:20 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 20: Unexpected errors ['specialtypes_sentinels.py:20:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:20:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 22: Unexpected errors ['specialtypes_sentinels.py:22:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] -Line 24: Unexpected errors ['specialtypes_sentinels.py:24:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 26: Unexpected errors ['specialtypes_sentinels.py:26:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:26:28 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 28: Unexpected errors ['specialtypes_sentinels.py:28:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] +Line 39: Expected 1 errors +Line 21: Unexpected errors ['specialtypes_sentinels.py:21:20 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 23: Unexpected errors ['specialtypes_sentinels.py:23:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:23:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 25: Unexpected errors ['specialtypes_sentinels.py:25:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] +Line 27: Unexpected errors ['specialtypes_sentinels.py:27:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 29: Unexpected errors ['specialtypes_sentinels.py:29:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:29:28 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 31: Unexpected errors ['specialtypes_sentinels.py:31:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] """ output = """ specialtypes_sentinels.py:15:20 - error: Expression of type "Sentinel" cannot be assigned to parameter of type "int"   "Sentinel" is not assignable to "int" (reportArgumentType) -specialtypes_sentinels.py:18:20 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:20:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) -specialtypes_sentinels.py:20:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:22:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) -specialtypes_sentinels.py:24:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:26:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) -specialtypes_sentinels.py:26:28 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:28:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:21:20 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:23:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:23:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:25:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:27:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:29:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:29:28 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:31:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) """ diff --git a/conformance/results/ty/specialtypes_sentinels.toml b/conformance/results/ty/specialtypes_sentinels.toml index 33eb77eef..9fbd851ca 100644 --- a/conformance/results/ty/specialtypes_sentinels.toml +++ b/conformance/results/ty/specialtypes_sentinels.toml @@ -1,21 +1,21 @@ conformant = "Unsupported" conformance_automated = "Fail" errors_diff = """ -Line 33: Expected 1 errors Line 36: Expected 1 errors -Line 18: Unexpected errors ['specialtypes_sentinels.py:18:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] -Line 20: Unexpected errors ['specialtypes_sentinels.py:20:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] -Line 22: Unexpected errors ['specialtypes_sentinels.py:22:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] -Line 24: Unexpected errors ['specialtypes_sentinels.py:24:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] -Line 26: Unexpected errors ['specialtypes_sentinels.py:26:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] -Line 28: Unexpected errors ['specialtypes_sentinels.py:28:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] +Line 39: Expected 1 errors +Line 21: Unexpected errors ['specialtypes_sentinels.py:21:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] +Line 23: Unexpected errors ['specialtypes_sentinels.py:23:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] +Line 25: Unexpected errors ['specialtypes_sentinels.py:25:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] +Line 27: Unexpected errors ['specialtypes_sentinels.py:27:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] +Line 29: Unexpected errors ['specialtypes_sentinels.py:29:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] +Line 31: Unexpected errors ['specialtypes_sentinels.py:31:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] """ output = """ specialtypes_sentinels.py:15:11: error[invalid-parameter-default] Default value of type `Sentinel` is not assignable to annotated parameter type `int` -specialtypes_sentinels.py:18:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation -specialtypes_sentinels.py:20:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` -specialtypes_sentinels.py:22:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` -specialtypes_sentinels.py:24:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation -specialtypes_sentinels.py:26:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` -specialtypes_sentinels.py:28:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` +specialtypes_sentinels.py:21:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:23:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` +specialtypes_sentinels.py:25:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` +specialtypes_sentinels.py:27:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:29:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` +specialtypes_sentinels.py:31:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` """ diff --git a/conformance/results/zuban/specialtypes_sentinels.toml b/conformance/results/zuban/specialtypes_sentinels.toml index f26fe3a11..fb8399352 100644 --- a/conformance/results/zuban/specialtypes_sentinels.toml +++ b/conformance/results/zuban/specialtypes_sentinels.toml @@ -1,25 +1,25 @@ conformant = "Unsupported" conformance_automated = "Fail" errors_diff = """ -Line 33: Expected 1 errors Line 36: Expected 1 errors -Line 18: Unexpected errors ['specialtypes_sentinels.py:18: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 20: Unexpected errors ['specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 22: Unexpected errors ['specialtypes_sentinels.py:22: error: Expression is of type "int | Any", not "int" [misc]'] -Line 24: Unexpected errors ['specialtypes_sentinels.py:24: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] -Line 26: Unexpected errors ['specialtypes_sentinels.py:26: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] -Line 28: Unexpected errors ['specialtypes_sentinels.py:28: error: Expression is of type "int | Any", not "int" [misc]'] +Line 39: Expected 1 errors +Line 21: Unexpected errors ['specialtypes_sentinels.py:21: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 23: Unexpected errors ['specialtypes_sentinels.py:23: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 25: Unexpected errors ['specialtypes_sentinels.py:25: error: Expression is of type "int | Any", not "int" [misc]'] +Line 27: Unexpected errors ['specialtypes_sentinels.py:27: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] +Line 29: Unexpected errors ['specialtypes_sentinels.py:29: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] +Line 31: Unexpected errors ['specialtypes_sentinels.py:31: error: Expression is of type "int | Any", not "int" [misc]'] """ output = """ specialtypes_sentinels.py:15: error: Incompatible default for argument "x" (default has type "Sentinel", argument has type "int") [assignment] -specialtypes_sentinels.py:18: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:18: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:22: error: Expression is of type "int | Any", not "int" [misc] -specialtypes_sentinels.py:24: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:26: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:26: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:28: error: Expression is of type "int | Any", not "int" [misc] +specialtypes_sentinels.py:21: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:21: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:23: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:23: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:25: error: Expression is of type "int | Any", not "int" [misc] +specialtypes_sentinels.py:27: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:27: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:29: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:29: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:31: error: Expression is of type "int | Any", not "int" [misc] """ diff --git a/conformance/tests/specialtypes_sentinels.py b/conformance/tests/specialtypes_sentinels.py index 72be77ab6..ab3356475 100644 --- a/conformance/tests/specialtypes_sentinels.py +++ b/conformance/tests/specialtypes_sentinels.py @@ -6,7 +6,7 @@ # > a simple assignment of the form ``NAME = sentinel('NAME')`` in the # > global scope or in a class body that is not within a function. -MISSING = Sentinel("MISSING") +MISSING = Sentinel("") # name is not required to match the variable name class Cls: IN_CLASS = Sentinel("Cls.IN_CLASS") @@ -15,6 +15,9 @@ class Cls: def func1(x: int = MISSING) -> None: # E: incompatible default pass +# > Type checkers must support narrowing union types involving sentinels using the +# > ``is`` and ``is not`` operators + def func2(x: int | MISSING = MISSING) -> None: if x is MISSING: assert_type(x, MISSING) diff --git a/docs/spec/special-types.rst b/docs/spec/special-types.rst index d1ea06e1a..56e61daa2 100644 --- a/docs/spec/special-types.rst +++ b/docs/spec/special-types.rst @@ -84,7 +84,7 @@ variable need not match the string argument passed to ``sentinel()`` but it is conventional to do so for names in the global scope. Type checkers must support narrowing union types involving sentinels using the -``is`` or ``is not`` operators:: +``is`` and ``is not`` operators:: def g(x: int | MISSING) -> None: if x is MISSING: From e6dd6e3b51f1133fd464c3e63a127b4c57b5b0b2 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 2 May 2026 09:45:02 -0700 Subject: [PATCH 3/5] update --- conformance/results/results.html | 1 + conformance/results/zuban/specialtypes_sentinels.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/conformance/results/results.html b/conformance/results/results.html index 3a99af86f..79fd628c3 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -279,6 +279,7 @@

Python Type System Conformance Test Results

Unsupported Unsupported Unsupported +Pass Unsupported      specialtypes_type diff --git a/conformance/results/zuban/specialtypes_sentinels.toml b/conformance/results/zuban/specialtypes_sentinels.toml index fb8399352..e35eeecee 100644 --- a/conformance/results/zuban/specialtypes_sentinels.toml +++ b/conformance/results/zuban/specialtypes_sentinels.toml @@ -11,7 +11,7 @@ Line 29: Unexpected errors ['specialtypes_sentinels.py:29: error: Variable "test Line 31: Unexpected errors ['specialtypes_sentinels.py:31: error: Expression is of type "int | Any", not "int" [misc]'] """ output = """ -specialtypes_sentinels.py:15: error: Incompatible default for argument "x" (default has type "Sentinel", argument has type "int") [assignment] +specialtypes_sentinels.py:15: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] specialtypes_sentinels.py:21: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] specialtypes_sentinels.py:21: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases specialtypes_sentinels.py:23: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] From 84d6fd8fd889fabc69562275a9807203d733bfab Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 2 May 2026 09:45:18 -0700 Subject: [PATCH 4/5] add file --- .../results/pycroscope/specialtypes_sentinels.toml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 conformance/results/pycroscope/specialtypes_sentinels.toml diff --git a/conformance/results/pycroscope/specialtypes_sentinels.toml b/conformance/results/pycroscope/specialtypes_sentinels.toml new file mode 100644 index 000000000..187734993 --- /dev/null +++ b/conformance/results/pycroscope/specialtypes_sentinels.toml @@ -0,0 +1,8 @@ +conformance_automated = "Pass" +errors_diff = """ +""" +output = """ +./specialtypes_sentinels.py:15:10: Default value for argument x incompatible with declared type int [incompatible_default] +./specialtypes_sentinels.py:36:6: Incompatible argument type for x: expected int | Literal[<>] but got [incompatible_argument] +./specialtypes_sentinels.py:39:6: Incompatible argument type for x: expected int | Literal[] but got <> [incompatible_argument] +""" From 36a2158213e9198493b3866b88579e5baf42bdfd Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 2 May 2026 09:46:49 -0700 Subject: [PATCH 5/5] add --- .../results/mypy/specialtypes_sentinels.toml | 34 +++++++++-------- .../pycroscope/specialtypes_sentinels.toml | 4 +- .../pyrefly/specialtypes_sentinels.toml | 30 +++++++-------- .../pyright/specialtypes_sentinels.toml | 31 ++++++++-------- .../results/ty/specialtypes_sentinels.toml | 27 +++++++------- .../results/zuban/specialtypes_sentinels.toml | 37 ++++++++++--------- conformance/tests/specialtypes_sentinels.py | 8 ++-- 7 files changed, 90 insertions(+), 81 deletions(-) diff --git a/conformance/results/mypy/specialtypes_sentinels.toml b/conformance/results/mypy/specialtypes_sentinels.toml index acfe9d228..1ff31a1c9 100644 --- a/conformance/results/mypy/specialtypes_sentinels.toml +++ b/conformance/results/mypy/specialtypes_sentinels.toml @@ -3,21 +3,25 @@ conformance_automated = "Fail" errors_diff = """ Line 36: Expected 1 errors Line 39: Expected 1 errors -Line 21: Unexpected errors ['specialtypes_sentinels.py:21: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 23: Unexpected errors ['specialtypes_sentinels.py:23: error: Expression is of type "Any", not MISSING? [assert-type]', 'specialtypes_sentinels.py:23: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 27: Unexpected errors ['specialtypes_sentinels.py:27: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] -Line 29: Unexpected errors ['specialtypes_sentinels.py:29: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type]', 'specialtypes_sentinels.py:29: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]', 'specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type]'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22: error: Expression is of type "Any", not MISSING? [assert-type]', 'specialtypes_sentinels.py:22: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24: error: Variable "specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type]'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type]', 'specialtypes_sentinels.py:28: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type]'] """ output = """ -specialtypes_sentinels.py:15: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] -specialtypes_sentinels.py:21: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:21: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:23: error: Expression is of type "Any", not MISSING? [assert-type] -specialtypes_sentinels.py:23: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:23: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:27: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:27: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:29: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type] -specialtypes_sentinels.py:29: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:29: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:14: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] +specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:20: error: Variable "specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type] +specialtypes_sentinels.py:22: error: Expression is of type "Any", not MISSING? [assert-type] +specialtypes_sentinels.py:22: error: Variable "specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:22: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:24: error: Variable "specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type] +specialtypes_sentinels.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:26: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:26: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:28: error: Expression is of type "Any", not Cls.IN_CLASS? [assert-type] +specialtypes_sentinels.py:28: error: Variable "specialtypes_sentinels.Cls.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:28: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases """ diff --git a/conformance/results/pycroscope/specialtypes_sentinels.toml b/conformance/results/pycroscope/specialtypes_sentinels.toml index 187734993..4c2425384 100644 --- a/conformance/results/pycroscope/specialtypes_sentinels.toml +++ b/conformance/results/pycroscope/specialtypes_sentinels.toml @@ -2,7 +2,7 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -./specialtypes_sentinels.py:15:10: Default value for argument x incompatible with declared type int [incompatible_default] -./specialtypes_sentinels.py:36:6: Incompatible argument type for x: expected int | Literal[<>] but got [incompatible_argument] +./specialtypes_sentinels.py:14:10: Default value for argument x incompatible with declared type int [incompatible_default] +./specialtypes_sentinels.py:36:6: Incompatible argument type for x: expected int | Literal[<>, ] but got [incompatible_argument] ./specialtypes_sentinels.py:39:6: Incompatible argument type for x: expected int | Literal[] but got <> [incompatible_argument] """ diff --git a/conformance/results/pyrefly/specialtypes_sentinels.toml b/conformance/results/pyrefly/specialtypes_sentinels.toml index 0d33bb8e4..f358b00ce 100644 --- a/conformance/results/pyrefly/specialtypes_sentinels.toml +++ b/conformance/results/pyrefly/specialtypes_sentinels.toml @@ -3,21 +3,21 @@ conformance_automated = "Fail" errors_diff = """ Line 36: Expected 1 errors Line 39: Expected 1 errors -Line 21: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] -Line 23: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] -Line 25: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] -Line 27: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] -Line 29: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] -Line 31: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] +Line 20: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType | Any` [not-a-type]'] +Line 22: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] +Line 24: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] +Line 26: Unexpected errors ['Expected a type form, got instance of `type[int] | UnionType` [not-a-type]'] +Line 28: Unexpected errors ['assert_type(Sentinel, Unknown) failed [assert-type]', 'Expected a type form, got instance of `Sentinel` [not-a-type]'] +Line 30: Unexpected errors ['assert_type(Unknown, int) failed [assert-type]'] """ output = """ -ERROR specialtypes_sentinels.py:15:20-27: Default `Sentinel` is not assignable to parameter `x` with type `int` [bad-function-definition] -ERROR specialtypes_sentinels.py:21:14-27: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] -ERROR specialtypes_sentinels.py:23:20-32: assert_type(Sentinel, Unknown) failed [assert-type] -ERROR specialtypes_sentinels.py:23:24-31: Expected a type form, got instance of `Sentinel` [not-a-type] -ERROR specialtypes_sentinels.py:25:20-28: assert_type(Unknown, int) failed [assert-type] -ERROR specialtypes_sentinels.py:27:14-32: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] -ERROR specialtypes_sentinels.py:29:20-37: assert_type(Sentinel, Unknown) failed [assert-type] -ERROR specialtypes_sentinels.py:29:24-36: Expected a type form, got instance of `Sentinel` [not-a-type] -ERROR specialtypes_sentinels.py:31:20-28: assert_type(Unknown, int) failed [assert-type] +ERROR specialtypes_sentinels.py:14:20-27: Default `Sentinel` is not assignable to parameter `x` with type `int` [bad-function-definition] +ERROR specialtypes_sentinels.py:20:14-37: Expected a type form, got instance of `type[int] | UnionType | Any` [not-a-type] +ERROR specialtypes_sentinels.py:22:20-32: assert_type(Sentinel, Unknown) failed [assert-type] +ERROR specialtypes_sentinels.py:22:24-31: Expected a type form, got instance of `Sentinel` [not-a-type] +ERROR specialtypes_sentinels.py:24:24-37: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] +ERROR specialtypes_sentinels.py:26:14-32: Expected a type form, got instance of `type[int] | UnionType` [not-a-type] +ERROR specialtypes_sentinels.py:28:20-37: assert_type(Sentinel, Unknown) failed [assert-type] +ERROR specialtypes_sentinels.py:28:24-36: Expected a type form, got instance of `Sentinel` [not-a-type] +ERROR specialtypes_sentinels.py:30:20-28: assert_type(Unknown, int) failed [assert-type] """ diff --git a/conformance/results/pyright/specialtypes_sentinels.toml b/conformance/results/pyright/specialtypes_sentinels.toml index f9f2ad225..a5884e796 100644 --- a/conformance/results/pyright/specialtypes_sentinels.toml +++ b/conformance/results/pyright/specialtypes_sentinels.toml @@ -3,22 +3,23 @@ conformance_automated = "Fail" errors_diff = """ Line 36: Expected 1 errors Line 39: Expected 1 errors -Line 21: Unexpected errors ['specialtypes_sentinels.py:21:20 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 23: Unexpected errors ['specialtypes_sentinels.py:23:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:23:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 25: Unexpected errors ['specialtypes_sentinels.py:25:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] -Line 27: Unexpected errors ['specialtypes_sentinels.py:27:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 29: Unexpected errors ['specialtypes_sentinels.py:29:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:29:28 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] -Line 31: Unexpected errors ['specialtypes_sentinels.py:31:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20:20 - error: Variable not allowed in type expression (reportInvalidTypeForm)', 'specialtypes_sentinels.py:20:30 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:22:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24:30 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26:24 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure)', 'specialtypes_sentinels.py:28:28 - error: Variable not allowed in type expression (reportInvalidTypeForm)'] +Line 30: Unexpected errors ['specialtypes_sentinels.py:30:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure)'] """ output = """ -specialtypes_sentinels.py:15:20 - error: Expression of type "Sentinel" cannot be assigned to parameter of type "int" +specialtypes_sentinels.py:14:20 - error: Expression of type "Sentinel" cannot be assigned to parameter of type "int"   "Sentinel" is not assignable to "int" (reportArgumentType) -specialtypes_sentinels.py:21:20 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:23:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) -specialtypes_sentinels.py:23:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:25:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) -specialtypes_sentinels.py:27:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:29:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) -specialtypes_sentinels.py:29:28 - error: Variable not allowed in type expression (reportInvalidTypeForm) -specialtypes_sentinels.py:31:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:20:20 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:20:30 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:22:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:22:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:24:30 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:26:24 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:28:21 - error: "assert_type" mismatch: expected "Unknown" but received "int | Unknown" (reportAssertTypeFailure) +specialtypes_sentinels.py:28:28 - error: Variable not allowed in type expression (reportInvalidTypeForm) +specialtypes_sentinels.py:30:21 - error: "assert_type" mismatch: expected "int" but received "int | Unknown" (reportAssertTypeFailure) """ diff --git a/conformance/results/ty/specialtypes_sentinels.toml b/conformance/results/ty/specialtypes_sentinels.toml index 9fbd851ca..1ae8cc924 100644 --- a/conformance/results/ty/specialtypes_sentinels.toml +++ b/conformance/results/ty/specialtypes_sentinels.toml @@ -3,19 +3,20 @@ conformance_automated = "Fail" errors_diff = """ Line 36: Expected 1 errors Line 39: Expected 1 errors -Line 21: Unexpected errors ['specialtypes_sentinels.py:21:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] -Line 23: Unexpected errors ['specialtypes_sentinels.py:23:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] -Line 25: Unexpected errors ['specialtypes_sentinels.py:25:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] -Line 27: Unexpected errors ['specialtypes_sentinels.py:27:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] -Line 29: Unexpected errors ['specialtypes_sentinels.py:29:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] -Line 31: Unexpected errors ['specialtypes_sentinels.py:31:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation', 'specialtypes_sentinels.py:20:30: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24:30: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a type expression'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo`'] +Line 30: Unexpected errors ['specialtypes_sentinels.py:30:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int`'] """ output = """ -specialtypes_sentinels.py:15:11: error[invalid-parameter-default] Default value of type `Sentinel` is not assignable to annotated parameter type `int` -specialtypes_sentinels.py:21:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation -specialtypes_sentinels.py:23:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` -specialtypes_sentinels.py:25:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` -specialtypes_sentinels.py:27:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation -specialtypes_sentinels.py:29:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` -specialtypes_sentinels.py:31:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` +specialtypes_sentinels.py:14:11: error[invalid-parameter-default] Default value of type `Sentinel` is not assignable to annotated parameter type `int` +specialtypes_sentinels.py:20:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:20:30: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:22:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` +specialtypes_sentinels.py:24:30: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a type expression +specialtypes_sentinels.py:26:20: error[invalid-type-form] Variable of type `Sentinel` is not allowed in a parameter annotation +specialtypes_sentinels.py:28:9: error[type-assertion-failure] Type `(int & Sentinel) | (Unknown & Sentinel)` does not match asserted type `@Todo` +specialtypes_sentinels.py:30:9: error[type-assertion-failure] Type `int | Unknown` does not match asserted type `int` """ diff --git a/conformance/results/zuban/specialtypes_sentinels.toml b/conformance/results/zuban/specialtypes_sentinels.toml index e35eeecee..f97164920 100644 --- a/conformance/results/zuban/specialtypes_sentinels.toml +++ b/conformance/results/zuban/specialtypes_sentinels.toml @@ -3,23 +3,26 @@ conformance_automated = "Fail" errors_diff = """ Line 36: Expected 1 errors Line 39: Expected 1 errors -Line 21: Unexpected errors ['specialtypes_sentinels.py:21: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 23: Unexpected errors ['specialtypes_sentinels.py:23: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] -Line 25: Unexpected errors ['specialtypes_sentinels.py:25: error: Expression is of type "int | Any", not "int" [misc]'] -Line 27: Unexpected errors ['specialtypes_sentinels.py:27: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] -Line 29: Unexpected errors ['specialtypes_sentinels.py:29: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] -Line 31: Unexpected errors ['specialtypes_sentinels.py:31: error: Expression is of type "int | Any", not "int" [misc]'] +Line 20: Unexpected errors ['specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]', 'specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type]'] +Line 22: Unexpected errors ['specialtypes_sentinels.py:22: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type]'] +Line 24: Unexpected errors ['specialtypes_sentinels.py:24: error: Variable "tests.specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type]'] +Line 26: Unexpected errors ['specialtypes_sentinels.py:26: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] +Line 28: Unexpected errors ['specialtypes_sentinels.py:28: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type]'] +Line 30: Unexpected errors ['specialtypes_sentinels.py:30: error: Expression is of type "int | Any", not "int" [misc]'] """ output = """ -specialtypes_sentinels.py:15: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] -specialtypes_sentinels.py:21: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:21: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:23: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] -specialtypes_sentinels.py:23: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:25: error: Expression is of type "int | Any", not "int" [misc] -specialtypes_sentinels.py:27: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:27: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:29: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] -specialtypes_sentinels.py:29: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -specialtypes_sentinels.py:31: error: Expression is of type "int | Any", not "int" [misc] +specialtypes_sentinels.py:14: error: Incompatible default for parameter "x" (default has type "Sentinel", parameter has type "int") [assignment] +specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:20: error: Variable "tests.specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type] +specialtypes_sentinels.py:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:22: error: Variable "tests.specialtypes_sentinels.MISSING" is not valid as a type [valid-type] +specialtypes_sentinels.py:22: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:24: error: Variable "tests.specialtypes_sentinels.SPECIAL" is not valid as a type [valid-type] +specialtypes_sentinels.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:26: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:26: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:28: error: Variable "tests.specialtypes_sentinels.IN_CLASS" is not valid as a type [valid-type] +specialtypes_sentinels.py:28: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +specialtypes_sentinels.py:30: error: Expression is of type "int | Any", not "int" [misc] """ diff --git a/conformance/tests/specialtypes_sentinels.py b/conformance/tests/specialtypes_sentinels.py index ab3356475..73c257017 100644 --- a/conformance/tests/specialtypes_sentinels.py +++ b/conformance/tests/specialtypes_sentinels.py @@ -1,5 +1,3 @@ -from unittest.mock import sentinel - from typing_extensions import Sentinel, assert_type # > Sentinel objects may be used in type annotations if they are defined using @@ -7,6 +5,7 @@ # > global scope or in a class body that is not within a function. MISSING = Sentinel("") # name is not required to match the variable name +SPECIAL = Sentinel("SPECIAL") class Cls: IN_CLASS = Sentinel("Cls.IN_CLASS") @@ -18,11 +17,11 @@ def func1(x: int = MISSING) -> None: # E: incompatible default # > Type checkers must support narrowing union types involving sentinels using the # > ``is`` and ``is not`` operators -def func2(x: int | MISSING = MISSING) -> None: +def func2(x: int | MISSING | SPECIAL = MISSING) -> None: if x is MISSING: assert_type(x, MISSING) else: - assert_type(x, int) + assert_type(x, int | SPECIAL) def func3(x: int | Cls.IN_CLASS = Cls.IN_CLASS) -> None: if x is Cls.IN_CLASS: @@ -33,6 +32,7 @@ def func3(x: int | Cls.IN_CLASS = Cls.IN_CLASS) -> None: func2(1) # ok func2(MISSING) # ok +func2(SPECIAL) # ok func2(Cls.IN_CLASS) # E: incompatible argument func3(1) # ok