Skip to content

Commit e06a33b

Browse files
committed
Turn isna() and notna() into TypeGuards
1 parent 46ee67b commit e06a33b

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

pandas-stubs/core/dtypes/missing.pyi

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ from pandas import (
1010
Index,
1111
Series,
1212
)
13+
from typing_extensions import TypeGuard
1314

1415
from pandas._libs.missing import NAType
1516
from pandas._libs.tslibs import NaTType
1617
from pandas._typing import (
1718
ArrayLike,
1819
Scalar,
20+
ScalarT,
1921
)
2022

2123
isposinf_scalar = ...
@@ -28,9 +30,17 @@ def isna(obj: Series) -> Series[bool]: ...
2830
@overload
2931
def isna(obj: Index | list | ArrayLike) -> npt.NDArray[np.bool_]: ...
3032
@overload
31-
def isna(obj: Scalar) -> bool: ...
32-
@overload
3333
def isna(obj: NaTType | NAType | None) -> Literal[True]: ...
34+
@overload
35+
def isna(
36+
obj: Scalar | NaTType | NAType | None,
37+
) -> TypeGuard[NaTType | NAType | None]: ...
38+
@overload
39+
def isna(obj: Scalar | NaTType) -> TypeGuard[NaTType]: ...
40+
@overload
41+
def isna(obj: Scalar | NAType) -> TypeGuard[NAType]: ...
42+
@overload
43+
def isna(obj: Scalar | None) -> TypeGuard[None]: ...
3444

3545
isnull = isna
3646

@@ -41,8 +51,8 @@ def notna(obj: Series) -> Series[bool]: ...
4151
@overload
4252
def notna(obj: Index | list | ArrayLike) -> npt.NDArray[np.bool_]: ...
4353
@overload
44-
def notna(obj: Scalar) -> bool: ...
45-
@overload
4654
def notna(obj: NaTType | NAType | None) -> Literal[False]: ...
55+
@overload
56+
def notna(obj: ScalarT | NaTType | NAType | None) -> TypeGuard[ScalarT]: ...
4757

4858
notnull = notna

tests/test_pandas.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import random
34
from typing import (
45
TYPE_CHECKING,
56
Any,
@@ -13,6 +14,9 @@
1314
from pandas.api.extensions import ExtensionArray
1415
from typing_extensions import assert_type
1516

17+
from pandas._libs.missing import NAType
18+
from pandas._libs.tslibs import NaTType
19+
1620
from tests import check
1721

1822

@@ -142,6 +146,25 @@ def test_isna() -> None:
142146
check(assert_type(pd.isna(2.5), bool), bool)
143147
check(assert_type(pd.notna(2.5), bool), bool)
144148

149+
# Check type guard functionality
150+
nullable1 = random.choice(["value", None, pd.NA, pd.NaT])
151+
if pd.notna(nullable1):
152+
check(assert_type(nullable1, str), str)
153+
if pd.isna(nullable1):
154+
assert_type(nullable1, Union[NaTType, NAType, None])
155+
156+
nullable2 = random.choice([2, None])
157+
if pd.notna(nullable2):
158+
check(assert_type(nullable2, int), int)
159+
if pd.isna(nullable2):
160+
assert_type(nullable2, None)
161+
162+
nullable3 = random.choice([2, None, pd.NA])
163+
if pd.notna(nullable3):
164+
check(assert_type(nullable3, int), int)
165+
if pd.isna(nullable3):
166+
assert_type(nullable3, Union[NAType, None])
167+
145168

146169
# GH 55
147170
def test_read_xml() -> None:

0 commit comments

Comments
 (0)