|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import random |
3 | 4 | from typing import (
|
4 | 5 | TYPE_CHECKING,
|
5 | 6 | Any,
|
6 |
| - Literal, |
7 | 7 | Union,
|
8 | 8 | )
|
9 | 9 |
|
|
14 | 14 | import pytest
|
15 | 15 | from typing_extensions import assert_type
|
16 | 16 |
|
| 17 | +from pandas._libs.missing import NAType |
| 18 | +from pandas._libs.tslibs import NaTType |
17 | 19 | from pandas._typing import Scalar
|
18 | 20 |
|
19 | 21 | from tests import check
|
@@ -133,18 +135,42 @@ def test_isna() -> None:
|
133 | 135 | idx2 = pd.Index([1, 2])
|
134 | 136 | check(assert_type(pd.notna(idx2), npt.NDArray[np.bool_]), np.ndarray, np.bool_)
|
135 | 137 |
|
136 |
| - assert check(assert_type(pd.isna(pd.NA), Literal[True]), bool) |
137 |
| - assert not check(assert_type(pd.notna(pd.NA), Literal[False]), bool) |
| 138 | + assert check(assert_type(pd.isna(pd.NA), bool), bool) |
| 139 | + assert not check(assert_type(pd.notna(pd.NA), bool), bool) |
138 | 140 |
|
139 |
| - assert check(assert_type(pd.isna(pd.NaT), Literal[True]), bool) |
140 |
| - assert not check(assert_type(pd.notna(pd.NaT), Literal[False]), bool) |
| 141 | + assert check(assert_type(pd.isna(pd.NaT), bool), bool) |
| 142 | + assert not check(assert_type(pd.notna(pd.NaT), bool), bool) |
141 | 143 |
|
142 |
| - assert check(assert_type(pd.isna(None), Literal[True]), bool) |
143 |
| - assert not check(assert_type(pd.notna(None), Literal[False]), bool) |
| 144 | + assert check(assert_type(pd.isna(None), bool), bool) |
| 145 | + assert not check(assert_type(pd.notna(None), bool), bool) |
144 | 146 |
|
145 | 147 | check(assert_type(pd.isna(2.5), bool), bool)
|
146 | 148 | check(assert_type(pd.notna(2.5), bool), bool)
|
147 | 149 |
|
| 150 | + # Check type guard functionality |
| 151 | + nullable1 = random.choice(["value", None, pd.NA, pd.NaT]) |
| 152 | + if pd.notna(nullable1): |
| 153 | + check(assert_type(nullable1, str), str) |
| 154 | + if pd.isna(nullable1): |
| 155 | + assert_type(nullable1, Union[NaTType, NAType, None]) |
| 156 | + |
| 157 | + nullable2 = random.choice([2, None]) |
| 158 | + if pd.notna(nullable2): |
| 159 | + check(assert_type(nullable2, int), int) |
| 160 | + if pd.isna(nullable2): |
| 161 | + # TODO: Due to limitations in TypeGuard spec, the true annotation is not viable at this time |
| 162 | + # There is a proposal being floated for a StrictTypeGuard that will have more rigid narrowing semantics |
| 163 | + # assert_type(nullable2, None) |
| 164 | + assert_type(nullable2, Union[NaTType, NAType, None]) |
| 165 | + |
| 166 | + nullable3 = random.choice([2, None, pd.NA]) |
| 167 | + if pd.notna(nullable3): |
| 168 | + check(assert_type(nullable3, int), int) |
| 169 | + if pd.isna(nullable3): |
| 170 | + # TODO: See comment above about the limitations of TypeGuard |
| 171 | + # assert_type(nullable3, Union[NAType, None]) |
| 172 | + assert_type(nullable3, Union[NaTType, NAType, None]) |
| 173 | + |
148 | 174 |
|
149 | 175 | # GH 55
|
150 | 176 | def test_read_xml() -> None:
|
|
0 commit comments