Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
aa6578e
fix(typing): Narrow `IntoDataFrame`
dangotbanned Apr 7, 2025
51c5b63
fix(typing): Remove `DataFrame` from `IntoFrame`
dangotbanned Apr 7, 2025
6cbbc74
fix(typing): Narrow `IntoLazyFrame`, `IntoFrame`
dangotbanned Apr 7, 2025
255ab27
fix(typing): Annotate `DataFrame._compliant_frame`
dangotbanned Apr 7, 2025
ba2f6e1
chore: Add missing `CompliantDataFrame.pivot`
dangotbanned Apr 7, 2025
1815752
fix(typing): Ensure `__iter__` is available on group_by
dangotbanned Apr 7, 2025
07deea2
chore(typing): Fix most of `DataFrame`
dangotbanned Apr 7, 2025
3881822
chore(typing): Ignore interchange `[type-var]`
dangotbanned Apr 7, 2025
375fabc
test(typing): Barely fix dodgy spark typing
dangotbanned Apr 7, 2025
21e80ef
fix: Implement `to_numpy` to catch args
dangotbanned Apr 7, 2025
c124985
fix(typing): Annotate `LazyFrame._compliant_frame`
dangotbanned Apr 7, 2025
831a6be
chore(typing): Ignore and add note for `spark_like` cast
dangotbanned Apr 7, 2025
1725f36
chore(typing): Partial `v1` backport
dangotbanned Apr 7, 2025
c4bed59
fix(typing): Just preserve `v1` behavior
dangotbanned Apr 7, 2025
6a9fd91
simplify
dangotbanned Apr 7, 2025
ed65ad2
try old `Union`
dangotbanned Apr 7, 2025
b97149d
Merge remote-tracking branch 'upstream/main' into narrow-type-var-frame
dangotbanned Apr 8, 2025
6a66779
docs(typing): Provide more context on what and why
dangotbanned Apr 8, 2025
675329c
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 8, 2025
5dd7825
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 9, 2025
a1c51ff
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 9, 2025
c2b328b
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 10, 2025
b66d1bf
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 12, 2025
ba525f1
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 12, 2025
c45f1f4
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 12, 2025
322b00d
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 12, 2025
d6cb16b
chore(typing): Use `Sequence[str]` in `pivot`
dangotbanned Apr 12, 2025
cbd60d9
refactor(typing): Use `PivotAgg`
dangotbanned Apr 12, 2025
53722e8
Merge remote-tracking branch 'upstream/main' into narrow-type-var-frame
dangotbanned Apr 12, 2025
e111fc3
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 13, 2025
23158d1
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 13, 2025
bc72941
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 14, 2025
a1fb349
Merge branch 'main' into narrow-type-var-frame
dangotbanned Apr 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions narwhals/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from narwhals.dataframe import DataFrame
from narwhals.dataframe import LazyFrame
from narwhals.series import Series
from narwhals.typing import DataFrameT
from narwhals.typing import FrameT
from narwhals.typing import IntoDataFrameT
from narwhals.typing import IntoSeriesT
Expand Down Expand Up @@ -364,8 +363,8 @@ def is_into_dataframe(native_dataframe: Any | IntoDataFrameT) -> TypeIs[IntoData


def is_narwhals_dataframe(
df: Any | DataFrame[DataFrameT],
) -> TypeIs[DataFrame[DataFrameT]]:
df: DataFrame[IntoDataFrameT] | Any,
) -> TypeIs[DataFrame[IntoDataFrameT]]:
"""Check whether `df` is a Narwhals DataFrame.

This is useful if you expect a user to pass in a Narwhals
Expand Down
27 changes: 7 additions & 20 deletions narwhals/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@
from narwhals.dataframe import DataFrame
from narwhals.dataframe import LazyFrame
from narwhals.series import Series
from narwhals.typing import DataFrameT
from narwhals.typing import IntoDataFrameT
from narwhals.typing import IntoFrame
from narwhals.typing import IntoFrameT
from narwhals.typing import IntoLazyFrameT
from narwhals.typing import IntoSeries
from narwhals.typing import IntoSeriesT
from narwhals.typing import LazyFrameT
from narwhals.typing import SeriesT

T = TypeVar("T")
Expand Down Expand Up @@ -134,14 +136,11 @@ def from_native(native_object: SeriesT, **kwds: Any) -> SeriesT: ...


@overload
def from_native(
native_object: IntoDataFrameT | IntoSeries,
*,
pass_through: Literal[True],
eager_only: Literal[False] = ...,
series_only: Literal[False] = ...,
allow_series: Literal[True],
) -> DataFrame[IntoDataFrameT]: ...
def from_native(native_object: DataFrameT, **kwds: Any) -> DataFrameT: ...


@overload
def from_native(native_object: LazyFrameT, **kwds: Any) -> LazyFrameT: ...


@overload
Expand Down Expand Up @@ -235,7 +234,6 @@ def from_native( # type: ignore[overload-overlap]
) -> LazyFrame[IntoLazyFrameT]: ...


# NOTE: `pl.LazyFrame` originally matched here
@overload
def from_native(
native_object: IntoDataFrameT,
Expand Down Expand Up @@ -280,17 +278,6 @@ def from_native(
) -> Series[IntoSeriesT]: ...


@overload
def from_native(
native_object: IntoFrameT | IntoLazyFrameT,
*,
pass_through: Literal[False] = ...,
eager_only: Literal[False] = ...,
series_only: Literal[False] = ...,
allow_series: None = ...,
) -> DataFrame[IntoFrameT] | LazyFrame[IntoLazyFrameT]: ...


# All params passed in as variables
@overload
def from_native(
Expand Down
8 changes: 3 additions & 5 deletions narwhals/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def __native_namespace__(self) -> ModuleType: ...
which will be interpreted as a `nw.Expr`, e.g. `df.select('a')`.
"""

IntoDataFrame: TypeAlias = Union["NativeFrame", "DataFrame[Any]", "DataFrameLike"]
IntoDataFrame: TypeAlias = Union["NativeFrame", "DataFrameLike"]
"""Anything which can be converted to a Narwhals DataFrame.

Use this if your function accepts a narwhalifiable object but doesn't care about its backend.
Expand All @@ -70,11 +70,9 @@ def __native_namespace__(self) -> ModuleType: ...
... return df.shape
"""

IntoLazyFrame: TypeAlias = "NativeLazyFrame | LazyFrame[Any]"
IntoLazyFrame: TypeAlias = "NativeLazyFrame"

IntoFrame: TypeAlias = Union[
"NativeFrame", "DataFrame[Any]", "LazyFrame[Any]", "DataFrameLike"
]
IntoFrame: TypeAlias = "IntoDataFrame | IntoLazyFrame"
"""Anything which can be converted to a Narwhals DataFrame or LazyFrame.

Use this if your function can accept an object which can be converted to either
Expand Down
42 changes: 42 additions & 0 deletions tests/translate/from_native_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,48 @@ def test_from_native_lazyframe() -> None:
assert isinstance(unstable_lazy, unstable_nw.LazyFrame)


def test_dataframe_recursive() -> None:
pytest.importorskip("polars")
import polars as pl

pl_frame = pl.DataFrame({"a": [1, 2, 3]})
nw_frame = unstable_nw.from_native(pl_frame)
with pytest.raises(AssertionError):
unstable_nw.DataFrame(nw_frame, level="full")

nw_frame_early_return = unstable_nw.from_native(nw_frame)

if TYPE_CHECKING:
assert_type(pl_frame, pl.DataFrame)
assert_type(nw_frame, unstable_nw.DataFrame[pl.DataFrame])

nw_frame_depth_2 = unstable_nw.DataFrame(nw_frame, level="full") # type: ignore[var-annotated]
# NOTE: Checking that the type is `DataFrame[Unknown]`
assert_type(nw_frame_depth_2, unstable_nw.DataFrame) # type: ignore[type-arg]
assert_type(nw_frame_early_return, unstable_nw.DataFrame[pl.DataFrame])


def test_lazyframe_recursive() -> None:
pytest.importorskip("polars")
import polars as pl

pl_frame = pl.DataFrame({"a": [1, 2, 3]}).lazy()
nw_frame = unstable_nw.from_native(pl_frame)
with pytest.raises(AssertionError):
unstable_nw.LazyFrame(nw_frame, level="lazy")

nw_frame_early_return = unstable_nw.from_native(nw_frame)

if TYPE_CHECKING:
assert_type(pl_frame, pl.LazyFrame)
assert_type(nw_frame, unstable_nw.LazyFrame[pl.LazyFrame])

nw_frame_depth_2 = unstable_nw.LazyFrame(nw_frame, level="lazy") # type: ignore[var-annotated]
# NOTE: Checking that the type is `LazyFrame[Unknown]`
assert_type(nw_frame_depth_2, unstable_nw.LazyFrame) # type: ignore[type-arg]
assert_type(nw_frame_early_return, unstable_nw.LazyFrame[pl.LazyFrame])


def test_series_recursive() -> None:
"""https://github.com/narwhals-dev/narwhals/issues/2239."""
pytest.importorskip("polars")
Expand Down
Loading