Skip to content

Commit 92d4739

Browse files
Specify that assert_type() uses equivalence (#2011)
* Specify that assert_type() uses equivalence * more lenient * updates * pyright is passing * rerun * Regenerate results. --------- Co-authored-by: Rebecca Chen <[email protected]>
1 parent f903377 commit 92d4739

File tree

6 files changed

+49
-23
lines changed

6 files changed

+49
-23
lines changed

conformance/results/mypy/directives_assert_type.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
conformant = "Pass"
22
output = """
33
directives_assert_type.py:27: error: Expression is of type "int | str", not "int" [assert-type]
4-
directives_assert_type.py:28: error: Expression is of type "Any", not "int" [assert-type]
5-
directives_assert_type.py:29: error: Expression is of type "Literal[4]", not "int" [assert-type]
6-
directives_assert_type.py:31: error: "assert_type" expects 2 arguments [misc]
7-
directives_assert_type.py:31: error: Too few arguments for "assert_type" [call-arg]
8-
directives_assert_type.py:32: error: Expression is of type "Literal['']", not "int" [assert-type]
9-
directives_assert_type.py:33: error: "assert_type" expects 2 arguments [misc]
10-
directives_assert_type.py:33: error: Too many arguments for "assert_type" [call-arg]
4+
directives_assert_type.py:28: error: Expression is of type "int | str", not "Any" [assert-type]
5+
directives_assert_type.py:29: error: Expression is of type "Any", not "int" [assert-type]
6+
directives_assert_type.py:30: error: Expression is of type "Literal[4]", not "int" [assert-type]
7+
directives_assert_type.py:32: error: "assert_type" expects 2 arguments [misc]
8+
directives_assert_type.py:32: error: Too few arguments for "assert_type" [call-arg]
9+
directives_assert_type.py:33: error: Expression is of type "Literal['']", not "int" [assert-type]
10+
directives_assert_type.py:34: error: "assert_type" expects 2 arguments [misc]
11+
directives_assert_type.py:34: error: Too many arguments for "assert_type" [call-arg]
1112
"""
1213
conformance_automated = "Pass"
1314
errors_diff = """

conformance/results/pyrefly/directives_assert_type.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ errors_diff = """
44
"""
55
output = """
66
ERROR directives_assert_type.py:27:16-24: assert_type(int | str, int) failed [assert-type]
7-
ERROR directives_assert_type.py:28:16-24: assert_type(Any, int) failed [assert-type]
8-
ERROR directives_assert_type.py:29:16-24: assert_type(Literal[4], int) failed [assert-type]
9-
ERROR directives_assert_type.py:31:16-18: assert_type needs 2 positional arguments, got 0 [bad-argument-count]
10-
ERROR directives_assert_type.py:32:16-25: assert_type(Literal[''], int) failed [assert-type]
11-
ERROR directives_assert_type.py:33:16-33: assert_type needs 2 positional arguments, got 3 [bad-argument-count]
7+
ERROR directives_assert_type.py:28:16-24: assert_type(int | str, Any) failed [assert-type]
8+
ERROR directives_assert_type.py:29:16-24: assert_type(Any, int) failed [assert-type]
9+
ERROR directives_assert_type.py:30:16-24: assert_type(Literal[4], int) failed [assert-type]
10+
ERROR directives_assert_type.py:32:16-18: assert_type needs 2 positional arguments, got 0 [bad-argument-count]
11+
ERROR directives_assert_type.py:33:16-25: assert_type(Literal[''], int) failed [assert-type]
12+
ERROR directives_assert_type.py:34:16-33: assert_type needs 2 positional arguments, got 3 [bad-argument-count]
1213
"""

conformance/results/pyright/directives_assert_type.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
conformant = "Pass"
22
output = """
33
directives_assert_type.py:27:17 - error: "assert_type" mismatch: expected "int" but received "int | str" (reportAssertTypeFailure)
4-
directives_assert_type.py:28:17 - error: "assert_type" mismatch: expected "int" but received "Any" (reportAssertTypeFailure)
5-
directives_assert_type.py:29:17 - error: "assert_type" mismatch: expected "int" but received "Literal[4]" (reportAssertTypeFailure)
6-
directives_assert_type.py:31:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
7-
directives_assert_type.py:32:17 - error: "assert_type" mismatch: expected "int" but received "Literal['']" (reportAssertTypeFailure)
8-
directives_assert_type.py:33:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
4+
directives_assert_type.py:28:17 - error: "assert_type" mismatch: expected "Any" but received "int | str" (reportAssertTypeFailure)
5+
directives_assert_type.py:29:17 - error: "assert_type" mismatch: expected "int" but received "Any" (reportAssertTypeFailure)
6+
directives_assert_type.py:30:17 - error: "assert_type" mismatch: expected "int" but received "Literal[4]" (reportAssertTypeFailure)
7+
directives_assert_type.py:32:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
8+
directives_assert_type.py:33:17 - error: "assert_type" mismatch: expected "int" but received "Literal['']" (reportAssertTypeFailure)
9+
directives_assert_type.py:34:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
10+
directives_assert_type.py:41:17 - error: "assert_type" mismatch: expected "str | Literal['spam']" but received "str" (reportAssertTypeFailure)
911
"""
1012
conformance_automated = "Pass"
1113
errors_diff = """

conformance/results/zuban/directives_assert_type.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ errors_diff = """
33
"""
44
output = """
55
directives_assert_type.py:27: error: Expression is of type "int | str", not "int" [misc]
6-
directives_assert_type.py:28: error: Expression is of type "Any", not "int" [misc]
7-
directives_assert_type.py:29: error: Expression is of type "Literal[4]", not "int" [misc]
8-
directives_assert_type.py:31: error: "assert_type" expects 2 arguments [call-arg]
9-
directives_assert_type.py:32: error: Expression is of type "Literal['']", not "int" [misc]
10-
directives_assert_type.py:33: error: "assert_type" expects 2 arguments [call-arg]
6+
directives_assert_type.py:28: error: Expression is of type "int | str", not "Any" [misc]
7+
directives_assert_type.py:29: error: Expression is of type "Any", not "int" [misc]
8+
directives_assert_type.py:30: error: Expression is of type "Literal[4]", not "int" [misc]
9+
directives_assert_type.py:32: error: "assert_type" expects 2 arguments [call-arg]
10+
directives_assert_type.py:33: error: Expression is of type "Literal['']", not "int" [misc]
11+
directives_assert_type.py:34: error: "assert_type" expects 2 arguments [call-arg]
12+
directives_assert_type.py:41: error: Expression is of type "str", not "str | Literal['spam']" [misc]
1113
"""

conformance/tests/directives_assert_type.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def func1(
2525
assert_type(e, Literal[4]) # OK
2626

2727
assert_type(a, int) # E: Type mismatch
28+
assert_type(a, Any) # E: Type mismatch
2829
assert_type(c, int) # E: Type mismatch
2930
assert_type(e, int) # E: Type mismatch
3031

@@ -33,5 +34,12 @@ def func1(
3334
assert_type(a, int | str, a) # E: too many arguments
3435

3536

37+
# > If the two types are :term:`equivalent` but syntactically different,
38+
# > the type checker may reject the ``assert_type()`` call::
39+
40+
def func2(name: str):
41+
assert_type(name, str | Literal["spam"]) # E?: Equivalent but not identical
42+
43+
3644
class ForwardReference:
3745
pass

docs/spec/directives.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Type checker directives
99
-----------------
1010

1111
The function ``typing.assert_type(val, typ)`` allows users to
12-
ask a static type checker to confirm that *val* has an inferred type of *typ*.
12+
ask a static type checker to confirm that the inferred type of *val*
13+
is :term:`equivalent` to *typ*.
1314

1415
When a type checker encounters a call to ``assert_type()``, it
1516
should emit an error if the value is not of the specified type::
@@ -18,6 +19,17 @@ should emit an error if the value is not of the specified type::
1819
assert_type(name, str) # OK, inferred type of `name` is `str`
1920
assert_type(name, int) # type checker error
2021

22+
If the two types are :term:`equivalent` but syntactically different,
23+
the type checker may reject the ``assert_type()`` call::
24+
25+
from typing import assert_type, Literal
26+
27+
def greet(name: str) -> None:
28+
assert_type(name, str | Literal["spam"]) # type checker may error
29+
30+
Type checkers should aim to minimize cases where they reject
31+
``assert_type()`` calls that use equivalent types.
32+
2133
The second argument must be a valid :term:`type expression`.
2234

2335
.. _`reveal-type`:

0 commit comments

Comments
 (0)