Skip to content

Commit 534f518

Browse files
committed
Adjust TypeGuard tests to document limitations of notna/isna type narrowing
1 parent 4a329f3 commit 534f518

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

tests/test_pandas.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,29 +259,56 @@ def test_isna() -> None:
259259
assert not check(assert_type(pd.isna(2.5), bool), bool)
260260
assert check(assert_type(pd.notna(2.5), bool), bool)
261261

262-
# Check type guard functionality
262+
# Check TypeGuard type narrowing functionality
263+
# TODO: Due to limitations in TypeGuard spec, the true annotations are not always viable
264+
# and as a result the type narrowing does not always work as it intuitively should
265+
# There is a proposal being floated for a StrictTypeGuard that will have more rigid narrowing semantics
266+
# In the test cases below, a commented out assertion will be included to document the optimal test result
263267
nullable1 = random.choice(["value", None, pd.NA, pd.NaT])
264268
if pd.notna(nullable1):
265269
check(assert_type(nullable1, str), str)
270+
if not pd.isna(nullable1):
271+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
272+
# check(assert_type(nullable1, str), str)
273+
check(assert_type(nullable1, Union[str, NaTType, NAType, None]), str)
266274
if pd.isna(nullable1):
267275
assert_type(nullable1, Union[NaTType, NAType, None])
276+
if not pd.notna(nullable1):
277+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
278+
# assert_type(nullable1, Union[NaTType, NAType, None])
279+
assert_type(nullable1, Union[str, NaTType, NAType, None])
268280

269281
nullable2 = random.choice([2, None])
270282
if pd.notna(nullable2):
271283
check(assert_type(nullable2, int), int)
284+
if not pd.isna(nullable2):
285+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
286+
# check(assert_type(nullable2, int), int)
287+
check(assert_type(nullable2, Union[int, None]), int)
272288
if pd.isna(nullable2):
273-
# TODO: Due to limitations in TypeGuard spec, the true annotation is not viable at this time
274-
# There is a proposal being floated for a StrictTypeGuard that will have more rigid narrowing semantics
275-
# assert_type(nullable2, None)
276-
assert_type(nullable2, Union[NaTType, NAType, None])
277-
278-
nullable3 = random.choice([2, None, pd.NA])
289+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
290+
# check(assert_type(nullable2, None), type(None))
291+
check(assert_type(nullable2, Union[NaTType, NAType, None]), type(None))
292+
if not pd.notna(nullable2):
293+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
294+
# check(assert_type(nullable2, None), type(None))
295+
assert_type(nullable2, Union[int, NaTType, NAType, None])
296+
297+
nullable3 = random.choice([True, None, pd.NA])
279298
if pd.notna(nullable3):
280-
check(assert_type(nullable3, int), int)
299+
check(assert_type(nullable3, bool), bool)
300+
if not pd.isna(nullable3):
301+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
302+
# check(assert_type(nullable3, bool), bool)
303+
check(assert_type(nullable3, Union[bool, NAType, None]), bool)
281304
if pd.isna(nullable3):
282-
# TODO: See comment above about the limitations of TypeGuard
305+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
283306
# assert_type(nullable3, Union[NAType, None])
284307
assert_type(nullable3, Union[NaTType, NAType, None])
308+
if not pd.notna(nullable3):
309+
# TODO: This is the true type (see comments above on the limitations of TypeGuard)
310+
# assert_type(nullable3, Union[NAType, None])
311+
assert_type(nullable3, Union[bool, NaTType, NAType, None])
285312

286313

287314
# GH 55

0 commit comments

Comments
 (0)