Skip to content

Commit 556c6a6

Browse files
refactor(typing): Add _native.py (#3086)
Co-authored-by: Francesco Bruzzesi <[email protected]>
1 parent 48a4900 commit 556c6a6

File tree

15 files changed

+548
-524
lines changed

15 files changed

+548
-524
lines changed

narwhals/_compliant/typing.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,11 @@
2323
from narwhals._compliant.namespace import CompliantNamespace, EagerNamespace
2424
from narwhals._compliant.series import CompliantSeries, EagerSeries
2525
from narwhals._compliant.window import WindowInputs
26+
from narwhals._native import NativeDataFrame, NativeFrame, NativeSeries
2627
from narwhals.typing import (
2728
FillNullStrategy,
2829
IntoLazyFrame,
2930
ModeKeepStrategy,
30-
NativeDataFrame,
31-
NativeFrame,
32-
NativeSeries,
3331
RankMethod,
3432
RollingInterpolationMethod,
3533
)

narwhals/_namespace.py

Lines changed: 41 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,50 @@
22

33
from __future__ import annotations
44

5-
from typing import (
6-
TYPE_CHECKING,
7-
Any,
8-
Callable,
9-
Generic,
10-
Protocol,
11-
TypeVar,
12-
cast,
13-
overload,
14-
)
5+
from typing import TYPE_CHECKING, Any, ClassVar, Generic, overload
156

167
from narwhals._compliant.typing import CompliantNamespaceAny, CompliantNamespaceT_co
17-
from narwhals._utils import Implementation, Version
18-
from narwhals.dependencies import (
19-
get_cudf,
20-
get_modin,
21-
get_pandas,
22-
get_polars,
23-
get_pyarrow,
24-
is_dask_dataframe,
25-
is_duckdb_relation,
26-
is_ibis_table,
27-
is_pyspark_connect_dataframe,
28-
is_pyspark_dataframe,
29-
is_sqlframe_dataframe,
8+
from narwhals._native import (
9+
NativeAny,
10+
NativeArrow,
11+
NativeCuDF,
12+
NativeDask,
13+
NativeDuckDB,
14+
NativeIbis,
15+
NativeModin,
16+
NativePandas,
17+
NativePandasLike,
18+
NativePolars,
19+
NativeSparkLike,
20+
NativeUnknown,
21+
_CuDFDataFrame,
22+
_CuDFSeries,
23+
_ModinDataFrame,
24+
_ModinSeries,
25+
is_native_arrow,
26+
is_native_cudf,
27+
is_native_dask,
28+
is_native_duckdb,
29+
is_native_ibis,
30+
is_native_modin,
31+
is_native_pandas,
32+
is_native_polars,
33+
is_native_pyspark_connect,
34+
is_native_spark_like,
35+
is_native_sqlframe,
3036
)
37+
from narwhals._utils import Implementation, Version
3138

3239
if TYPE_CHECKING:
33-
from collections.abc import Collection, Sized
34-
from typing import ClassVar
35-
36-
import duckdb
3740
import pandas as pd
38-
import polars as pl
39-
import pyarrow as pa
40-
from typing_extensions import Self, TypeAlias, TypeIs
41+
from typing_extensions import TypeAlias
4142

4243
from narwhals._arrow.namespace import ArrowNamespace
4344
from narwhals._dask.namespace import DaskNamespace
4445
from narwhals._duckdb.namespace import DuckDBNamespace
4546
from narwhals._ibis.namespace import IbisNamespace
4647
from narwhals._pandas_like.namespace import PandasLikeNamespace
4748
from narwhals._polars.namespace import PolarsNamespace
48-
from narwhals._spark_like.dataframe import SQLFrameDataFrame
4949
from narwhals._spark_like.namespace import SparkLikeNamespace
5050
from narwhals._typing import (
5151
Arrow,
@@ -59,87 +59,8 @@
5959
Polars,
6060
SparkLike,
6161
)
62-
from narwhals.typing import NativeDataFrame, NativeLazyFrame, NativeSeries
63-
64-
T = TypeVar("T")
65-
66-
_Guard: TypeAlias = "Callable[[Any], TypeIs[T]]"
6762

6863
EagerAllowedNamespace: TypeAlias = "Namespace[PandasLikeNamespace] | Namespace[ArrowNamespace] | Namespace[PolarsNamespace]"
69-
Incomplete: TypeAlias = Any
70-
71-
class _BasePandasLike(Sized, Protocol):
72-
index: Any
73-
"""`mypy` doesn't like the asymmetric `property` setter in `pandas`."""
74-
75-
def __getitem__(self, key: Any, /) -> Any: ...
76-
def __mul__(self, other: float | Collection[float] | Self, /) -> Self: ...
77-
def __floordiv__(self, other: float | Collection[float] | Self, /) -> Self: ...
78-
@property
79-
def loc(self) -> Any: ...
80-
@property
81-
def shape(self) -> tuple[int, ...]: ...
82-
def set_axis(self, labels: Any, *, axis: Any = ..., copy: bool = ...) -> Self: ...
83-
def copy(self, deep: bool = ...) -> Self: ... # noqa: FBT001
84-
def rename(self, *args: Any, **kwds: Any) -> Self | Incomplete:
85-
"""`mypy` & `pyright` disagree on overloads.
86-
87-
`Incomplete` used to fix [more important issue](https://github.com/narwhals-dev/narwhals/pull/3016#discussion_r2296139744).
88-
"""
89-
90-
class _BasePandasLikeFrame(NativeDataFrame, _BasePandasLike, Protocol): ...
91-
92-
class _BasePandasLikeSeries(NativeSeries, _BasePandasLike, Protocol):
93-
def where(self, cond: Any, other: Any = ..., /) -> Self | Incomplete: ...
94-
95-
class _NativeDask(NativeLazyFrame, Protocol):
96-
_partition_type: type[pd.DataFrame]
97-
98-
class _CuDFDataFrame(_BasePandasLikeFrame, Protocol):
99-
def to_pylibcudf(self, *args: Any, **kwds: Any) -> Any: ...
100-
101-
class _CuDFSeries(_BasePandasLikeSeries, Protocol):
102-
def to_pylibcudf(self, *args: Any, **kwds: Any) -> Any: ...
103-
104-
class _NativeIbis(Protocol):
105-
def sql(self, *args: Any, **kwds: Any) -> Any: ...
106-
def __pyarrow_result__(self, *args: Any, **kwds: Any) -> Any: ...
107-
def __pandas_result__(self, *args: Any, **kwds: Any) -> Any: ...
108-
def __polars_result__(self, *args: Any, **kwds: Any) -> Any: ...
109-
110-
class _ModinDataFrame(_BasePandasLikeFrame, Protocol):
111-
_pandas_class: type[pd.DataFrame]
112-
113-
class _ModinSeries(_BasePandasLikeSeries, Protocol):
114-
_pandas_class: type[pd.Series[Any]]
115-
116-
# NOTE: Using `pyspark.sql.DataFrame` creates false positives in overloads when not installed
117-
class _PySparkDataFrame(NativeLazyFrame, Protocol):
118-
# Arbitrary method that `sqlframe` doesn't have and unlikely to appear anywhere else
119-
# https://github.com/apache/spark/blob/8530444e25b83971da4314c608aa7d763adeceb3/python/pyspark/sql/dataframe.py#L4875
120-
def dropDuplicatesWithinWatermark(self, *arg: Any, **kwargs: Any) -> Any: ... # noqa: N802
121-
122-
_NativePolars: TypeAlias = "pl.DataFrame | pl.LazyFrame | pl.Series"
123-
_NativeArrow: TypeAlias = "pa.Table | pa.ChunkedArray[Any]"
124-
_NativeDuckDB: TypeAlias = "duckdb.DuckDBPyRelation"
125-
_NativePandas: TypeAlias = "pd.DataFrame | pd.Series[Any]"
126-
_NativeModin: TypeAlias = "_ModinDataFrame | _ModinSeries"
127-
_NativeCuDF: TypeAlias = "_CuDFDataFrame | _CuDFSeries"
128-
_NativePandasLikeSeries: TypeAlias = "pd.Series[Any] | _CuDFSeries | _ModinSeries"
129-
_NativePandasLikeDataFrame: TypeAlias = (
130-
"pd.DataFrame | _CuDFDataFrame | _ModinDataFrame"
131-
)
132-
_NativePandasLike: TypeAlias = "_NativePandasLikeDataFrame |_NativePandasLikeSeries"
133-
_NativeSQLFrame: TypeAlias = "SQLFrameDataFrame"
134-
_NativePySpark: TypeAlias = _PySparkDataFrame
135-
_NativePySparkConnect: TypeAlias = _PySparkDataFrame
136-
_NativeSparkLike: TypeAlias = (
137-
"_NativeSQLFrame | _NativePySpark | _NativePySparkConnect"
138-
)
139-
140-
NativeKnown: TypeAlias = "_NativePolars | _NativeArrow | _NativePandasLike | _NativeSparkLike | _NativeDuckDB | _NativeDask | _NativeIbis"
141-
NativeUnknown: TypeAlias = "NativeDataFrame | NativeSeries | NativeLazyFrame"
142-
NativeAny: TypeAlias = "NativeKnown | NativeUnknown"
14364

14465
__all__ = ["Namespace"]
14566

@@ -268,55 +189,55 @@ def from_backend(
268189
@overload
269190
@classmethod
270191
def from_native_object(
271-
cls, native: _NativePolars, /
192+
cls, native: NativePolars, /
272193
) -> Namespace[PolarsNamespace]: ...
273194

274195
@overload
275196
@classmethod
276197
def from_native_object(
277-
cls, native: _NativePandas, /
198+
cls, native: NativePandas, /
278199
) -> Namespace[PandasLikeNamespace[pd.DataFrame, pd.Series[Any]]]: ...
279200

280201
@overload
281202
@classmethod
282-
def from_native_object(cls, native: _NativeArrow, /) -> Namespace[ArrowNamespace]: ...
203+
def from_native_object(cls, native: NativeArrow, /) -> Namespace[ArrowNamespace]: ...
283204

284205
@overload
285206
@classmethod
286207
def from_native_object(
287-
cls, native: _NativeSparkLike, /
208+
cls, native: NativeSparkLike, /
288209
) -> Namespace[SparkLikeNamespace]: ...
289210

290211
@overload
291212
@classmethod
292213
def from_native_object(
293-
cls, native: _NativeDuckDB, /
214+
cls, native: NativeDuckDB, /
294215
) -> Namespace[DuckDBNamespace]: ...
295216

296217
@overload
297218
@classmethod
298-
def from_native_object(cls, native: _NativeDask, /) -> Namespace[DaskNamespace]: ...
219+
def from_native_object(cls, native: NativeDask, /) -> Namespace[DaskNamespace]: ...
299220

300221
@overload
301222
@classmethod
302-
def from_native_object(cls, native: _NativeIbis, /) -> Namespace[IbisNamespace]: ...
223+
def from_native_object(cls, native: NativeIbis, /) -> Namespace[IbisNamespace]: ...
303224

304225
@overload
305226
@classmethod
306227
def from_native_object(
307-
cls, native: _NativeModin, /
228+
cls, native: NativeModin, /
308229
) -> Namespace[PandasLikeNamespace[_ModinDataFrame, _ModinSeries]]: ...
309230

310231
@overload
311232
@classmethod
312233
def from_native_object(
313-
cls, native: _NativeCuDF, /
234+
cls, native: NativeCuDF, /
314235
) -> Namespace[PandasLikeNamespace[_CuDFDataFrame, _CuDFSeries]]: ...
315236

316237
@overload
317238
@classmethod
318239
def from_native_object(
319-
cls, native: _NativePandasLike, /
240+
cls, native: NativePandasLike, /
320241
) -> Namespace[PandasLikeNamespace[Any, Any]]: ...
321242

322243
@overload
@@ -358,61 +279,3 @@ def from_native_object(
358279
msg = f"Unsupported type: {type(native).__qualname__!r}"
359280
raise TypeError(msg)
360281
return cls.from_backend(impl)
361-
362-
363-
def is_native_polars(obj: Any) -> TypeIs[_NativePolars]:
364-
return (pl := get_polars()) is not None and isinstance(
365-
obj, (pl.DataFrame, pl.Series, pl.LazyFrame)
366-
)
367-
368-
369-
def is_native_arrow(obj: Any) -> TypeIs[_NativeArrow]:
370-
return (pa := get_pyarrow()) is not None and isinstance(
371-
obj, (pa.Table, pa.ChunkedArray)
372-
)
373-
374-
375-
def is_native_dask(obj: Any) -> TypeIs[_NativeDask]:
376-
return is_dask_dataframe(obj)
377-
378-
379-
is_native_duckdb: _Guard[_NativeDuckDB] = is_duckdb_relation
380-
is_native_sqlframe: _Guard[_NativeSQLFrame] = is_sqlframe_dataframe
381-
is_native_pyspark = cast("_Guard[_NativePySpark]", is_pyspark_dataframe)
382-
is_native_pyspark_connect = cast(
383-
"_Guard[_NativePySparkConnect]", is_pyspark_connect_dataframe
384-
)
385-
386-
387-
def is_native_pandas(obj: Any) -> TypeIs[_NativePandas]:
388-
return (pd := get_pandas()) is not None and isinstance(obj, (pd.DataFrame, pd.Series))
389-
390-
391-
def is_native_modin(obj: Any) -> TypeIs[_NativeModin]:
392-
return (mpd := get_modin()) is not None and isinstance(
393-
obj, (mpd.DataFrame, mpd.Series)
394-
) # pragma: no cover
395-
396-
397-
def is_native_cudf(obj: Any) -> TypeIs[_NativeCuDF]:
398-
return (cudf := get_cudf()) is not None and isinstance(
399-
obj, (cudf.DataFrame, cudf.Series)
400-
) # pragma: no cover
401-
402-
403-
def is_native_pandas_like(obj: Any) -> TypeIs[_NativePandasLike]:
404-
return (
405-
is_native_pandas(obj) or is_native_cudf(obj) or is_native_modin(obj)
406-
) # pragma: no cover
407-
408-
409-
def is_native_spark_like(obj: Any) -> TypeIs[_NativeSparkLike]:
410-
return (
411-
is_native_sqlframe(obj)
412-
or is_native_pyspark(obj)
413-
or is_native_pyspark_connect(obj)
414-
)
415-
416-
417-
def is_native_ibis(obj: Any) -> TypeIs[_NativeIbis]:
418-
return is_ibis_table(obj)

0 commit comments

Comments
 (0)