Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions conformance/results/mypy/directives_assert_type.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
conformant = "Pass"
output = """
directives_assert_type.py:27: error: Expression is of type "int | str", not "int" [assert-type]
directives_assert_type.py:28: error: Expression is of type "Any", not "int" [assert-type]
directives_assert_type.py:29: error: Expression is of type "Literal[4]", not "int" [assert-type]
directives_assert_type.py:31: error: "assert_type" expects 2 arguments [misc]
directives_assert_type.py:31: error: Too few arguments for "assert_type" [call-arg]
directives_assert_type.py:32: error: Expression is of type "Literal['']", not "int" [assert-type]
directives_assert_type.py:33: error: "assert_type" expects 2 arguments [misc]
directives_assert_type.py:33: error: Too many arguments for "assert_type" [call-arg]
directives_assert_type.py:28: error: Expression is of type "int | str", not "Any" [assert-type]
directives_assert_type.py:29: error: Expression is of type "Any", not "int" [assert-type]
directives_assert_type.py:30: error: Expression is of type "Literal[4]", not "int" [assert-type]
directives_assert_type.py:32: error: "assert_type" expects 2 arguments [misc]
directives_assert_type.py:32: error: Too few arguments for "assert_type" [call-arg]
directives_assert_type.py:33: error: Expression is of type "Literal['']", not "int" [assert-type]
directives_assert_type.py:34: error: "assert_type" expects 2 arguments [misc]
directives_assert_type.py:34: error: Too many arguments for "assert_type" [call-arg]
"""
conformance_automated = "Pass"
errors_diff = """
Expand Down
11 changes: 6 additions & 5 deletions conformance/results/pyrefly/directives_assert_type.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ errors_diff = """
"""
output = """
ERROR directives_assert_type.py:27:16-24: assert_type(int | str, int) failed [assert-type]
ERROR directives_assert_type.py:28:16-24: assert_type(Any, int) failed [assert-type]
ERROR directives_assert_type.py:29:16-24: assert_type(Literal[4], int) failed [assert-type]
ERROR directives_assert_type.py:31:16-18: assert_type needs 2 positional arguments, got 0 [bad-argument-count]
ERROR directives_assert_type.py:32:16-25: assert_type(Literal[''], int) failed [assert-type]
ERROR directives_assert_type.py:33:16-33: assert_type needs 2 positional arguments, got 3 [bad-argument-count]
ERROR directives_assert_type.py:28:16-24: assert_type(int | str, Any) failed [assert-type]
ERROR directives_assert_type.py:29:16-24: assert_type(Any, int) failed [assert-type]
ERROR directives_assert_type.py:30:16-24: assert_type(Literal[4], int) failed [assert-type]
ERROR directives_assert_type.py:32:16-18: assert_type needs 2 positional arguments, got 0 [bad-argument-count]
ERROR directives_assert_type.py:33:16-25: assert_type(Literal[''], int) failed [assert-type]
ERROR directives_assert_type.py:34:16-33: assert_type needs 2 positional arguments, got 3 [bad-argument-count]
"""
12 changes: 7 additions & 5 deletions conformance/results/pyright/directives_assert_type.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
conformant = "Pass"
output = """
directives_assert_type.py:27:17 - error: "assert_type" mismatch: expected "int" but received "int | str" (reportAssertTypeFailure)
directives_assert_type.py:28:17 - error: "assert_type" mismatch: expected "int" but received "Any" (reportAssertTypeFailure)
directives_assert_type.py:29:17 - error: "assert_type" mismatch: expected "int" but received "Literal[4]" (reportAssertTypeFailure)
directives_assert_type.py:31:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
directives_assert_type.py:32:17 - error: "assert_type" mismatch: expected "int" but received "Literal['']" (reportAssertTypeFailure)
directives_assert_type.py:33:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
directives_assert_type.py:28:17 - error: "assert_type" mismatch: expected "Any" but received "int | str" (reportAssertTypeFailure)
directives_assert_type.py:29:17 - error: "assert_type" mismatch: expected "int" but received "Any" (reportAssertTypeFailure)
directives_assert_type.py:30:17 - error: "assert_type" mismatch: expected "int" but received "Literal[4]" (reportAssertTypeFailure)
directives_assert_type.py:32:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
directives_assert_type.py:33:17 - error: "assert_type" mismatch: expected "int" but received "Literal['']" (reportAssertTypeFailure)
directives_assert_type.py:34:5 - error: "assert_type" expects two positional arguments (reportCallIssue)
directives_assert_type.py:41:17 - error: "assert_type" mismatch: expected "str | Literal['spam']" but received "str" (reportAssertTypeFailure)
"""
conformance_automated = "Pass"
errors_diff = """
Expand Down
12 changes: 7 additions & 5 deletions conformance/results/zuban/directives_assert_type.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ errors_diff = """
"""
output = """
directives_assert_type.py:27: error: Expression is of type "int | str", not "int" [misc]
directives_assert_type.py:28: error: Expression is of type "Any", not "int" [misc]
directives_assert_type.py:29: error: Expression is of type "Literal[4]", not "int" [misc]
directives_assert_type.py:31: error: "assert_type" expects 2 arguments [call-arg]
directives_assert_type.py:32: error: Expression is of type "Literal['']", not "int" [misc]
directives_assert_type.py:33: error: "assert_type" expects 2 arguments [call-arg]
directives_assert_type.py:28: error: Expression is of type "int | str", not "Any" [misc]
directives_assert_type.py:29: error: Expression is of type "Any", not "int" [misc]
directives_assert_type.py:30: error: Expression is of type "Literal[4]", not "int" [misc]
directives_assert_type.py:32: error: "assert_type" expects 2 arguments [call-arg]
directives_assert_type.py:33: error: Expression is of type "Literal['']", not "int" [misc]
directives_assert_type.py:34: error: "assert_type" expects 2 arguments [call-arg]
directives_assert_type.py:41: error: Expression is of type "str", not "str | Literal['spam']" [misc]
"""
8 changes: 8 additions & 0 deletions conformance/tests/directives_assert_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def func1(
assert_type(e, Literal[4]) # OK

assert_type(a, int) # E: Type mismatch
assert_type(a, Any) # E: Type mismatch
assert_type(c, int) # E: Type mismatch
assert_type(e, int) # E: Type mismatch

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


# > If the two types are :term:`equivalent` but syntactically different,
# > the type checker may reject the ``assert_type()`` call::

def func2(name: str):
assert_type(name, str | Literal["spam"]) # E?: Equivalent but not identical


class ForwardReference:
pass
14 changes: 13 additions & 1 deletion docs/spec/directives.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Type checker directives
-----------------

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

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

If the two types are :term:`equivalent` but syntactically different,
the type checker may reject the ``assert_type()`` call::

from typing import assert_type, Literal

def greet(name: str) -> None:
assert_type(name, str | Literal["spam"]) # type checker may error

Type checkers should aim to minimize cases where they reject
``assert_type()`` calls that use equivalent types.

The second argument must be a valid :term:`type expression`.

.. _`reveal-type`:
Expand Down