8
8
from typing import Any
9
9
10
10
if TYPE_CHECKING :
11
- import numpy as np
12
- import sqlframe
13
-
14
- if sys .version_info >= (3 , 10 ):
15
- from typing import TypeGuard
16
- else :
17
- from typing_extensions import TypeGuard
18
11
import cudf
19
12
import dask .dataframe as dd
20
13
import duckdb
21
14
import ibis
22
15
import modin .pandas as mpd
16
+ import numpy as np
23
17
import pandas as pd
24
18
import polars as pl
25
19
import pyarrow as pa
26
20
import pyspark .sql as pyspark_sql
21
+ import sqlframe
22
+ from typing_extensions import TypeGuard
27
23
from typing_extensions import TypeIs
28
24
29
25
from narwhals .dataframe import DataFrame
30
26
from narwhals .dataframe import LazyFrame
31
27
from narwhals .series import Series
32
- from narwhals .typing import IntoSeries
28
+ from narwhals .typing import DataFrameT
29
+ from narwhals .typing import FrameT
30
+ from narwhals .typing import IntoDataFrameT
31
+ from narwhals .typing import IntoSeriesT
33
32
from narwhals .typing import _1DArray
34
33
from narwhals .typing import _2DArray
35
34
from narwhals .typing import _NDArray
@@ -118,7 +117,7 @@ def get_sqlframe() -> Any:
118
117
return sys .modules .get ("sqlframe" , None )
119
118
120
119
121
- def is_pandas_dataframe (df : Any ) -> TypeGuard [pd .DataFrame ]:
120
+ def is_pandas_dataframe (df : Any ) -> TypeIs [pd .DataFrame ]:
122
121
"""Check whether `df` is a pandas DataFrame without importing pandas."""
123
122
return ((pd := get_pandas ()) is not None and isinstance (df , pd .DataFrame )) or any (
124
123
(mod := sys .modules .get (module_name , None )) is not None
@@ -127,7 +126,7 @@ def is_pandas_dataframe(df: Any) -> TypeGuard[pd.DataFrame]:
127
126
)
128
127
129
128
130
- def is_pandas_series (ser : Any ) -> TypeGuard [pd .Series [Any ]]:
129
+ def is_pandas_series (ser : Any ) -> TypeIs [pd .Series [Any ]]:
131
130
"""Check whether `ser` is a pandas Series without importing pandas."""
132
131
return ((pd := get_pandas ()) is not None and isinstance (ser , pd .Series )) or any (
133
132
(mod := sys .modules .get (module_name , None )) is not None
@@ -136,7 +135,7 @@ def is_pandas_series(ser: Any) -> TypeGuard[pd.Series[Any]]:
136
135
)
137
136
138
137
139
- def is_pandas_index (index : Any ) -> TypeGuard [pd .Index ]:
138
+ def is_pandas_index (index : Any ) -> TypeIs [pd .Index ]:
140
139
"""Check whether `index` is a pandas Index without importing pandas."""
141
140
return ((pd := get_pandas ()) is not None and isinstance (index , pd .Index )) or any (
142
141
(mod := sys .modules .get (module_name , None )) is not None
@@ -145,91 +144,91 @@ def is_pandas_index(index: Any) -> TypeGuard[pd.Index]:
145
144
)
146
145
147
146
148
- def is_modin_dataframe (df : Any ) -> TypeGuard [mpd .DataFrame ]:
147
+ def is_modin_dataframe (df : Any ) -> TypeIs [mpd .DataFrame ]:
149
148
"""Check whether `df` is a modin DataFrame without importing modin."""
150
149
return (mpd := get_modin ()) is not None and isinstance (df , mpd .DataFrame )
151
150
152
151
153
- def is_modin_series (ser : Any ) -> TypeGuard [mpd .Series ]:
152
+ def is_modin_series (ser : Any ) -> TypeIs [mpd .Series ]:
154
153
"""Check whether `ser` is a modin Series without importing modin."""
155
154
return (mpd := get_modin ()) is not None and isinstance (ser , mpd .Series )
156
155
157
156
158
- def is_modin_index (index : Any ) -> TypeGuard [mpd .Index ]:
157
+ def is_modin_index (index : Any ) -> TypeIs [mpd .Index ]:
159
158
"""Check whether `index` is a modin Index without importing modin."""
160
159
return (mpd := get_modin ()) is not None and isinstance (
161
160
index , mpd .Index
162
161
) # pragma: no cover
163
162
164
163
165
- def is_cudf_dataframe (df : Any ) -> TypeGuard [cudf .DataFrame ]:
164
+ def is_cudf_dataframe (df : Any ) -> TypeIs [cudf .DataFrame ]:
166
165
"""Check whether `df` is a cudf DataFrame without importing cudf."""
167
166
return (cudf := get_cudf ()) is not None and isinstance (df , cudf .DataFrame )
168
167
169
168
170
- def is_cudf_series (ser : Any ) -> TypeGuard [cudf .Series [Any ]]:
169
+ def is_cudf_series (ser : Any ) -> TypeIs [cudf .Series [Any ]]:
171
170
"""Check whether `ser` is a cudf Series without importing cudf."""
172
171
return (cudf := get_cudf ()) is not None and isinstance (ser , cudf .Series )
173
172
174
173
175
- def is_cudf_index (index : Any ) -> TypeGuard [cudf .Index ]:
174
+ def is_cudf_index (index : Any ) -> TypeIs [cudf .Index ]:
176
175
"""Check whether `index` is a cudf Index without importing cudf."""
177
176
return (cudf := get_cudf ()) is not None and isinstance (
178
177
index , cudf .Index
179
178
) # pragma: no cover
180
179
181
180
182
- def is_dask_dataframe (df : Any ) -> TypeGuard [dd .DataFrame ]:
181
+ def is_dask_dataframe (df : Any ) -> TypeIs [dd .DataFrame ]:
183
182
"""Check whether `df` is a Dask DataFrame without importing Dask."""
184
183
return (dd := get_dask_dataframe ()) is not None and isinstance (df , dd .DataFrame )
185
184
186
185
187
- def is_duckdb_relation (df : Any ) -> TypeGuard [duckdb .DuckDBPyRelation ]:
186
+ def is_duckdb_relation (df : Any ) -> TypeIs [duckdb .DuckDBPyRelation ]:
188
187
"""Check whether `df` is a DuckDB Relation without importing DuckDB."""
189
188
return (duckdb := get_duckdb ()) is not None and isinstance (
190
189
df , duckdb .DuckDBPyRelation
191
190
)
192
191
193
192
194
- def is_ibis_table (df : Any ) -> TypeGuard [ibis .Table ]:
193
+ def is_ibis_table (df : Any ) -> TypeIs [ibis .Table ]:
195
194
"""Check whether `df` is a Ibis Table without importing Ibis."""
196
195
return (ibis := get_ibis ()) is not None and isinstance (df , ibis .expr .types .Table )
197
196
198
197
199
- def is_polars_dataframe (df : Any ) -> TypeGuard [pl .DataFrame ]:
198
+ def is_polars_dataframe (df : Any ) -> TypeIs [pl .DataFrame ]:
200
199
"""Check whether `df` is a Polars DataFrame without importing Polars."""
201
200
return (pl := get_polars ()) is not None and isinstance (df , pl .DataFrame )
202
201
203
202
204
- def is_polars_lazyframe (df : Any ) -> TypeGuard [pl .LazyFrame ]:
203
+ def is_polars_lazyframe (df : Any ) -> TypeIs [pl .LazyFrame ]:
205
204
"""Check whether `df` is a Polars LazyFrame without importing Polars."""
206
205
return (pl := get_polars ()) is not None and isinstance (df , pl .LazyFrame )
207
206
208
207
209
- def is_polars_series (ser : Any ) -> TypeGuard [pl .Series ]:
208
+ def is_polars_series (ser : Any ) -> TypeIs [pl .Series ]:
210
209
"""Check whether `ser` is a Polars Series without importing Polars."""
211
210
return (pl := get_polars ()) is not None and isinstance (ser , pl .Series )
212
211
213
212
214
- def is_pyarrow_chunked_array (ser : Any ) -> TypeGuard [pa .ChunkedArray ]:
213
+ def is_pyarrow_chunked_array (ser : Any ) -> TypeIs [pa .ChunkedArray ]:
215
214
"""Check whether `ser` is a PyArrow ChunkedArray without importing PyArrow."""
216
215
return (pa := get_pyarrow ()) is not None and isinstance (ser , pa .ChunkedArray )
217
216
218
217
219
- def is_pyarrow_table (df : Any ) -> TypeGuard [pa .Table ]:
218
+ def is_pyarrow_table (df : Any ) -> TypeIs [pa .Table ]:
220
219
"""Check whether `df` is a PyArrow Table without importing PyArrow."""
221
220
return (pa := get_pyarrow ()) is not None and isinstance (df , pa .Table )
222
221
223
222
224
- def is_pyspark_dataframe (df : Any ) -> TypeGuard [pyspark_sql .DataFrame ]:
223
+ def is_pyspark_dataframe (df : Any ) -> TypeIs [pyspark_sql .DataFrame ]:
225
224
"""Check whether `df` is a PySpark DataFrame without importing PySpark."""
226
225
return bool (
227
226
(pyspark_sql := get_pyspark_sql ()) is not None
228
227
and isinstance (df , pyspark_sql .DataFrame )
229
228
)
230
229
231
230
232
- def is_sqlframe_dataframe (df : Any ) -> TypeGuard [sqlframe .base .dataframe .BaseDataFrame ]:
231
+ def is_sqlframe_dataframe (df : Any ) -> TypeIs [sqlframe .base .dataframe .BaseDataFrame ]:
233
232
"""Check whether `df` is a SQLFrame DataFrame without importing SQLFrame."""
234
233
return bool (
235
234
(sqlframe := get_sqlframe ()) is not None
@@ -254,6 +253,9 @@ def is_numpy_array_2d(arr: Any) -> TypeIs[_2DArray]:
254
253
255
254
def is_numpy_scalar (scalar : Any ) -> TypeGuard [np .generic ]:
256
255
"""Check whether `scalar` is a NumPy Scalar without importing NumPy."""
256
+ # NOTE: Needs to stay as `TypeGuard`
257
+ # - Used in `Series.__getitem__`, but not annotated
258
+ # - `TypeGuard` is *hiding* that the check introduces an intersection
257
259
return (np := get_numpy ()) is not None and np .isscalar (scalar )
258
260
259
261
@@ -283,7 +285,7 @@ def is_pandas_like_index(index: Any) -> bool:
283
285
) # pragma: no cover
284
286
285
287
286
- def is_into_series (native_series : IntoSeries ) -> bool :
288
+ def is_into_series (native_series : Any | IntoSeriesT ) -> TypeIs [ IntoSeriesT ] :
287
289
"""Check whether `native_series` can be converted to a Narwhals Series.
288
290
289
291
Arguments:
@@ -320,7 +322,7 @@ def is_into_series(native_series: IntoSeries) -> bool:
320
322
)
321
323
322
324
323
- def is_into_dataframe (native_dataframe : Any ) -> bool :
325
+ def is_into_dataframe (native_dataframe : Any | IntoDataFrameT ) -> TypeIs [ IntoDataFrameT ] :
324
326
"""Check whether `native_dataframe` can be converted to a Narwhals DataFrame.
325
327
326
328
Arguments:
@@ -357,7 +359,9 @@ def is_into_dataframe(native_dataframe: Any) -> bool:
357
359
)
358
360
359
361
360
- def is_narwhals_dataframe (df : Any ) -> TypeGuard [DataFrame [Any ]]:
362
+ def is_narwhals_dataframe (
363
+ df : Any | DataFrame [DataFrameT ],
364
+ ) -> TypeIs [DataFrame [DataFrameT ]]:
361
365
"""Check whether `df` is a Narwhals DataFrame.
362
366
363
367
This is useful if you expect a user to pass in a Narwhals
@@ -369,7 +373,7 @@ def is_narwhals_dataframe(df: Any) -> TypeGuard[DataFrame[Any]]:
369
373
return isinstance (df , DataFrame )
370
374
371
375
372
- def is_narwhals_lazyframe (lf : Any ) -> TypeGuard [LazyFrame [Any ]]:
376
+ def is_narwhals_lazyframe (lf : Any | LazyFrame [ FrameT ] ) -> TypeIs [LazyFrame [FrameT ]]:
373
377
"""Check whether `lf` is a Narwhals LazyFrame.
374
378
375
379
This is useful if you expect a user to pass in a Narwhals
@@ -381,7 +385,7 @@ def is_narwhals_lazyframe(lf: Any) -> TypeGuard[LazyFrame[Any]]:
381
385
return isinstance (lf , LazyFrame )
382
386
383
387
384
- def is_narwhals_series (ser : Any ) -> TypeGuard [Series [Any ]]:
388
+ def is_narwhals_series (ser : Any | Series [ IntoSeriesT ] ) -> TypeIs [Series [IntoSeriesT ]]:
385
389
"""Check whether `ser` is a Narwhals Series.
386
390
387
391
This is useful if you expect a user to pass in a Narwhals
0 commit comments