Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Proposed spec and test suite change
Browse files Browse the repository at this point in the history
JelleZijlstra committed Feb 21, 2024
1 parent 01ed042 commit e9b2fd1
Showing 2 changed files with 28 additions and 8 deletions.
30 changes: 25 additions & 5 deletions conformance/tests/narrowing_typeguard.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@

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

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


T = TypeVar("T")
@@ -39,18 +39,18 @@ def func2(val: set[object]):
class A:
def tg_1(self, val: object) -> TypeGuard[int]:
return isinstance(val, int)

@classmethod
def tg_2(cls, val: object) -> TypeGuard[int]:
return isinstance(val, int)

@staticmethod
def tg_3(val: object) -> TypeGuard[int]:
return isinstance(val, int)

def tg4(self, val: object) -> TypeGuard[Self]:
return isinstance(val, type(self))

def tg5(self: T_A, val: object) -> TypeGuard[T_A]:
return isinstance(val, type(self))

@@ -101,8 +101,28 @@ class C:
# Type checker should emit error here.
def tg_1(self) -> TypeGuard[int]:
return False

@classmethod
# Type checker should emit error here.
def tg_2(cls) -> TypeGuard[int]:
return False

# > ``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]]``
# > is assignable to ``Callable[..., bool]``.


def takes_callable_bool(f: Callable[[object], bool]) -> None:
pass


def takes_callable_str(f: Callable[[object], str]) -> None:
pass


def simple_typeguard(val: object) -> TypeGuard[int]:
return isinstance(val, int)


takes_callable_bool(simple_typeguard) # OK
takes_callable_str(simple_typeguard) # Error
6 changes: 3 additions & 3 deletions docs/spec/narrowing.rst
Original file line number Diff line number Diff line change
@@ -19,9 +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.

In all other respects, ``TypeGuard`` is a distinct type from bool. It is not a
subtype of bool. Therefore, ``Callable[..., TypeGuard[int]]`` is not assignable
to ``Callable[..., 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]]``
is assignable to ``Callable[..., bool]``.

When ``TypeGuard`` is used to annotate the return type of a function or
method that accepts at least one parameter, that function or method is

0 comments on commit e9b2fd1

Please sign in to comment.