Skip to content

Commit

Permalink
Do not say "Callable"; add test case for callable protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed Feb 23, 2024
1 parent b6f97f2 commit 7c4851e
Show file tree
Hide file tree
Showing 10 changed files with 36 additions and 7 deletions.
1 change: 1 addition & 0 deletions conformance/results/mypy/narrowing_typeguard.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ output = """
narrowing_typeguard.py:102: error: TypeGuard functions must have a positional argument [valid-type]
narrowing_typeguard.py:107: error: TypeGuard functions must have a positional argument [valid-type]
narrowing_typeguard.py:128: error: Argument 1 to "takes_callable_str" has incompatible type "Callable[[object], TypeGuard[int]]"; expected "Callable[[object], str]" [arg-type]
narrowing_typeguard.py:148: error: Argument 1 to "takes_callable_str_proto" has incompatible type "Callable[[object], TypeGuard[int]]"; expected "CallableStrProto" [arg-type]
"""
2 changes: 1 addition & 1 deletion conformance/results/mypy/version.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = "mypy 1.8.0"
test_duration = 1.4
test_duration = 1.5
1 change: 1 addition & 0 deletions conformance/results/pyre/narrowing_typeguard.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ output = """
narrowing_typeguard.py:17:33 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T_co](covariant)]` but got `Tuple[Type[str], Type[str]]`.
narrowing_typeguard.py:19:33 Incompatible parameter type [6]: In call `typing.GenericMeta.__getitem__`, for 1st positional argument, expected `Type[Variable[_T_co](covariant)]` but got `Tuple[Type[str], typing.Any]`.
narrowing_typeguard.py:128:19 Incompatible parameter type [6]: In call `takes_callable_str`, for 1st positional argument, expected `typing.Callable[[object], str]` but got `typing.Callable(simple_typeguard)[[Named(val, object)], TypeGuard[int]]`.
narrowing_typeguard.py:148:25 Incompatible parameter type [6]: In call `takes_callable_str_proto`, for 1st positional argument, expected `CallableStrProto` but got `typing.Callable(simple_typeguard)[[Named(val, object)], TypeGuard[int]]`.
"""
5 changes: 5 additions & 0 deletions conformance/results/pyright/narrowing_typeguard.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@ narrowing_typeguard.py:128:20 - error: Argument of type "(val: object) -> TypeGu
    Function return type "TypeGuard[int]" is incompatible with type "str"
      "TypeGuard[int]" is incompatible with "str"
      "bool" is incompatible with "str" (reportArgumentType)
narrowing_typeguard.py:148:26 - error: Argument of type "(val: object) -> TypeGuard[int]" cannot be assigned to parameter "f" of type "CallableStrProto" in function "takes_callable_str_proto"
  Type "(val: object) -> TypeGuard[int]" cannot be assigned to type "(val: object) -> str"
    Function return type "TypeGuard[int]" is incompatible with type "str"
      "TypeGuard[int]" is incompatible with "str"
      "bool" is incompatible with "str" (reportArgumentType)
"""
2 changes: 1 addition & 1 deletion conformance/results/pyright/version.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = "pyright 1.1.351"
test_duration = 1.5
test_duration = 1.6
1 change: 1 addition & 0 deletions conformance/results/pytype/narrowing_typeguard.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ Does not reject TypeGuard method with too few parameters.
"""
output = """
File "narrowing_typeguard.py", line 128, in <module>: Function takes_callable_str was called with the wrong arguments [wrong-arg-types]
File "narrowing_typeguard.py", line 148, in <module>: Function takes_callable_str_proto was called with the wrong arguments [wrong-arg-types]
"""
2 changes: 1 addition & 1 deletion conformance/results/pytype/version.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = "pytype 2024.02.13"
test_duration = 42.7
test_duration = 42.5
2 changes: 1 addition & 1 deletion conformance/results/results.html

Large diffs are not rendered by default.

22 changes: 21 additions & 1 deletion conformance/tests/narrowing_typeguard.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Specification: https://typing.readthedocs.io/en/latest/spec/narrowing.html#typeguard

from typing import Any, Callable, Self, TypeGuard, TypeVar, assert_type
from typing import Any, Callable, Protocol, Self, TypeGuard, TypeVar, assert_type


T = TypeVar("T")
Expand Down Expand Up @@ -126,3 +126,23 @@ def simple_typeguard(val: object) -> TypeGuard[int]:

takes_callable_bool(simple_typeguard) # OK
takes_callable_str(simple_typeguard) # Error


class CallableBoolProto(Protocol):
def __call__(self, val: object) -> bool: ...


class CallableStrProto(Protocol):
def __call__(self, val: object) -> str: ...


def takes_callable_bool_proto(f: CallableBoolProto) -> None:
pass


def takes_callable_str_proto(f: CallableStrProto) -> None:
pass


takes_callable_bool_proto(simple_typeguard) # OK
takes_callable_str_proto(simple_typeguard) # Error
5 changes: 3 additions & 2 deletions docs/spec/narrowing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ user-defined type guard function. Return statements within a type guard function
should return bool values, and type checkers should verify that all return paths
return a bool.

``TypeGuard`` is also valid as the return type of a ``Callable`` type. In that
context, it is treated as a subtype of bool. For example, ``Callable[..., TypeGuard[int]]``
``TypeGuard`` is also valid as the return type of a callable, for example
in callback protocols and in the ``Callable`` special form. In these
contexts, it is treated as a subtype of bool. For example, ``Callable[..., TypeGuard[int]]``
is assignable to ``Callable[..., bool]``.

When ``TypeGuard`` is used to annotate the return type of a function or
Expand Down

0 comments on commit 7c4851e

Please sign in to comment.