Skip to content

Commit 01f1802

Browse files
committed
python#1872 issue: Update narrowing_typeguar.py Update narrowing_typeis.py
1 parent fafcdeb commit 01f1802

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

conformance/tests/narrowing_typeguard.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"""
2-
Tests TypeGuard functionality.
2+
Tests TypeGuard functionality, including async support.
33
"""
44

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

7-
from typing import Any, Callable, Protocol, Self, TypeGuard, TypeVar, assert_type
7+
from typing import Any, Callable, Protocol, Self, TypeGuard, TypeVar, assert_type, Awaitable
88

99

1010
T = TypeVar("T")
@@ -165,3 +165,16 @@ def bool_typeguard(val: object) -> TypeGuard[bool]:
165165

166166
takes_int_typeguard(int_typeguard) # OK
167167
takes_int_typeguard(bool_typeguard) # OK
168+
169+
# -------------------- ASYNC TYPEGUARD SUPPORT --------------------
170+
171+
async def async_typeguard_test(val: object) -> TypeGuard[int]:
172+
return isinstance(val, int)
173+
174+
async def test_async_typeguard():
175+
val: int | str = 10
176+
if await async_typeguard_test(val): # Ensure narrowing works here
177+
assert_type(val, int)
178+
else:
179+
assert_type(val, str)
180+

conformance/tests/narrowing_typeis.py

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Tests TypeIs functionality.
2+
Tests TypeIs functionality, including async support.
33
"""
44

55
# Specification: https://typing.readthedocs.io/en/latest/spec/narrowing.html#typeis
@@ -20,7 +20,6 @@ def func1(names: tuple[str, ...]):
2020
else:
2121
assert_type(names, tuple[str, ...])
2222

23-
2423
# > The final narrowed type may be narrower than **R**, due to the constraints of the
2524
# > argument's previously-known type
2625

@@ -37,7 +36,6 @@ async def func2(val: int | Awaitable[int]):
3736
else:
3837
assert_type(val, int)
3938

40-
4139
T_A = TypeVar("T_A", bound="A")
4240

4341
class A:
@@ -65,7 +63,6 @@ class B(A):
6563
# > passed to the function. The function may accept additional arguments,
6664
# > but they are not affected by type narrowing.
6765

68-
6966
def func3() -> None:
7067
val1 = object()
7168
if A().tg_1(val1):
@@ -95,7 +92,6 @@ def func3() -> None:
9592
if B().tg4(val7):
9693
assert_type(val7, B)
9794

98-
9995
# > If a type narrowing function
10096
# > is implemented as an instance method or class method, the first positional
10197
# > argument maps to the second parameter (after self or cls).
@@ -115,39 +111,30 @@ def tg_2(cls) -> TypeIs[int]: # E
115111
# > contexts, it is treated as a subtype of bool. For example, ``Callable[..., TypeIs[int]]``
116112
# > is assignable to ``Callable[..., bool]``.
117113

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

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

126-
127120
def simple_typeguard(val: object) -> TypeIs[int]:
128121
return isinstance(val, int)
129122

130-
131123
takes_callable_bool(simple_typeguard) # OK
132124
takes_callable_str(simple_typeguard) # E
133125

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

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

142-
143132
def takes_callable_bool_proto(f: CallableBoolProto) -> None:
144133
pass
145134

146-
147135
def takes_callable_str_proto(f: CallableStrProto) -> None:
148136
pass
149137

150-
151138
takes_callable_bool_proto(simple_typeguard) # OK
152139
takes_callable_str_proto(simple_typeguard) # E
153140

@@ -170,23 +157,19 @@ def is_int_typeguard(val: object) -> TypeGuard[int]:
170157
takes_typeis(is_int_typeguard) # E
171158
takes_typeis(is_int_typeis) # OK
172159

173-
174160
# > Unlike ``TypeGuard``, ``TypeIs`` is invariant in its argument type:
175161
# > ``TypeIs[B]`` is not a subtype of ``TypeIs[A]``,
176162
# > even if ``B`` is a subtype of ``A``.
177163

178164
def takes_int_typeis(f: Callable[[object], TypeIs[int]]) -> None:
179165
pass
180166

181-
182167
def int_typeis(val: object) -> TypeIs[int]:
183168
return isinstance(val, int)
184169

185-
186170
def bool_typeis(val: object) -> TypeIs[bool]:
187171
return isinstance(val, bool)
188172

189-
190173
takes_int_typeis(int_typeis) # OK
191174
takes_int_typeis(bool_typeis) # E
192175

@@ -195,6 +178,18 @@ def bool_typeis(val: object) -> TypeIs[bool]:
195178
def bad_typeis(x: int) -> TypeIs[str]: # E
196179
return isinstance(x, str)
197180

198-
199181
def bad_typeis_variance(x: list[object]) -> TypeIs[list[int]]: # E
200182
return all(isinstance(x, int) for x in x)
183+
184+
# -------------------- ASYNC TYPEIS SUPPORT --------------------
185+
186+
async def async_typeis_test(val: object) -> TypeIs[int]:
187+
return isinstance(val, int)
188+
189+
async def test_async_typeis():
190+
val: int | str = 10
191+
if await async_typeis_test(val): # Ensure narrowing works here
192+
assert_type(val, int)
193+
else:
194+
assert_type(val, str)
195+

0 commit comments

Comments
 (0)