Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
154dc54
feat: Define `CompliantDataFrame.from_numpy`
dangotbanned Mar 23, 2025
3d533a0
feat: Add `PolarsDataFrame.from_numpy`
dangotbanned Mar 23, 2025
b333351
fix: Align `to_numpy` signatures
dangotbanned Mar 23, 2025
4805551
feat: Add `ArrowDataFrame.from_numpy`
dangotbanned Mar 23, 2025
c689161
refactor: Simplify `polars` impl
dangotbanned Mar 23, 2025
b63fa86
feat: Add `PandasLikeDataFrame.from_numpy`
dangotbanned Mar 24, 2025
d0e36f3
fix: Use `TypeVar` defaults correctly?
dangotbanned Mar 24, 2025
1591c2d
feat: Add `Implementation._to_compliant_namespace`
dangotbanned Mar 24, 2025
c5500a3
chore: Make `PolarsNamespace.concat` compliant
dangotbanned Mar 24, 2025
39382c5
chore(typing): Fill in more `__getattr__` gaps
dangotbanned Mar 24, 2025
7cd9ca7
chore: start aligning `PolarsSelectorNamespace`
dangotbanned Mar 24, 2025
aca796a
chore(typing): Pragmatic solution for `PolarsNamespace.selectors`
dangotbanned Mar 24, 2025
7101b62
feat(typing): Add `EagerNamespace._dataframe`
dangotbanned Mar 24, 2025
91bd274
feat: Add `PolarsNamespace._dataframe`
dangotbanned Mar 24, 2025
7f9fb6b
feat: Implement `EagerNamespace.from_numpy`
dangotbanned Mar 24, 2025
0c6a484
feat: Add `PolarsNamespace.from_numpy`
dangotbanned Mar 24, 2025
4f99e2d
chore: add `version` to `_from_numpy_impl`
dangotbanned Mar 24, 2025
14fe87f
feat(typing): `_to_compliant_namespace` overloads
dangotbanned Mar 24, 2025
7749bcd
feat(typing): Add `is_(eager|lazy)_allowed` guards
dangotbanned Mar 24, 2025
d52b405
refactor: Rewrite `from_numpy` using new protocols
dangotbanned Mar 24, 2025
bbc8a3d
remove duplicate overload
dangotbanned Mar 24, 2025
b3c791f
ignore `mypy` for now
dangotbanned Mar 24, 2025
2d49da4
Merge remote-tracking branch 'upstream/main' into from-numpy-2d-ns
dangotbanned Mar 24, 2025
b076950
fix: Un-confuse `mypy`
dangotbanned Mar 24, 2025
36c6b19
refactor(typing): Make aliases readable
dangotbanned Mar 24, 2025
50a39df
refactor: validate `schema` before passing to `Compliant*`
dangotbanned Mar 24, 2025
0273426
test: remove `xfail` from lazy backends
dangotbanned Mar 24, 2025
4e8591a
refactor: Add `EagerDataFrame._numpy_column_names`
dangotbanned Mar 24, 2025
694960d
refresh ci
dangotbanned Mar 24, 2025
f07cf38
ignore coverage on future stuff
dangotbanned Mar 24, 2025
31a5259
Merge remote-tracking branch 'upstream/main' into from-numpy-2d-ns
dangotbanned Mar 24, 2025
7a137b3
Merge branch 'main' into from-numpy-2d-ns
dangotbanned Mar 25, 2025
dabe5d4
Merge branch 'main' into from-numpy-2d-ns
dangotbanned Mar 25, 2025
8770d37
Merge branch 'main' into from-numpy-2d-ns
dangotbanned Mar 25, 2025
60a5469
Merge branch 'main' into from-numpy-2d-ns
dangotbanned Mar 26, 2025
fc74ba1
Merge branch 'main' into from-numpy-2d-ns
dangotbanned Mar 26, 2025
0e67a1e
fix(typing): Satisfy `pyright` in `PolarsNamespace.concat`
dangotbanned Mar 26, 2025
4f1b172
Merge remote-tracking branch 'upstream/main' into from-numpy-2d-ns
dangotbanned Mar 26, 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
25 changes: 4 additions & 21 deletions narwhals/_polars/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from narwhals._polars.dataframe import Method
from narwhals._polars.dataframe import PolarsDataFrame
from narwhals._polars.dataframe import PolarsLazyFrame
from narwhals._polars.typing import FrameT
from narwhals.schema import Schema
from narwhals.typing import Into1DArray
from narwhals.typing import TimeUnit
Expand Down Expand Up @@ -130,35 +131,17 @@ def len(self: Self) -> PolarsExpr:
pl.len(), version=self._version, backend_version=self._backend_version
)

@overload
def concat(
self: Self,
items: Iterable[PolarsDataFrame],
*,
how: Literal["vertical", "horizontal", "diagonal"],
) -> PolarsDataFrame: ...

@overload
def concat(
self: Self,
items: Iterable[PolarsLazyFrame],
*,
how: Literal["vertical", "horizontal", "diagonal"],
) -> PolarsLazyFrame: ...

def concat(
self: Self,
items: Iterable[PolarsDataFrame] | Iterable[PolarsLazyFrame],
items: Iterable[FrameT],
*,
how: Literal["vertical", "horizontal", "diagonal"],
) -> PolarsDataFrame | PolarsLazyFrame:
Copy link
Member Author

@dangotbanned dangotbanned Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolves (#2283 (comment)) via (0e67a1e)

@MarcoGorelli
I had no idea a TypeVar could be used this way πŸ€”

One rule I thought was that a TypeVar on a parameter annotation must either:

  • Be present in the class def (e.g. Generic[T] or Protocol[T])
  • Or appear in the return type

FrameT = TypeVar("FrameT", PolarsDataFrame, PolarsLazyFrame)

FrameT doesn't meet either of those rules - so I'd have expected this to get rejected.

But why work??

My best guess is there seems to be an understanding of what FrameT represents - and how that is consistent with:

def concat(
self,
items: Iterable[CompliantFrameT],
*,
how: Literal["horizontal", "vertical", "diagonal"],
) -> CompliantFrameT: ...

CompliantFrameT = TypeVar("CompliantFrameT", bound=CompliantFrameAny)

CompliantDataFrameAny: TypeAlias = "CompliantDataFrame[Any, Any, Any]"
CompliantLazyFrameAny: TypeAlias = "CompliantLazyFrame[Any, Any]"
CompliantFrameAny: TypeAlias = "CompliantDataFrameAny | CompliantLazyFrameAny"

from narwhals._polars.dataframe import PolarsDataFrame
from narwhals._polars.dataframe import PolarsLazyFrame

dfs: Iterable[Any] = (item.native for item in items)
result = pl.concat(dfs, how=how)
result = pl.concat((item.native for item in items), how=how)
if isinstance(result, pl.DataFrame):
return PolarsDataFrame(
return self._dataframe(
result, backend_version=self._backend_version, version=self._version
)
return PolarsLazyFrame(
Expand Down
4 changes: 4 additions & 0 deletions narwhals/_polars/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@

if TYPE_CHECKING:
import sys
from typing import TypeVar

if sys.version_info >= (3, 10):
from typing import TypeAlias
else:
from typing_extensions import TypeAlias

from narwhals._polars.dataframe import PolarsDataFrame
from narwhals._polars.dataframe import PolarsLazyFrame
from narwhals._polars.expr import PolarsExpr
from narwhals._polars.series import PolarsSeries

IntoPolarsExpr: TypeAlias = Union[PolarsExpr, PolarsSeries]
FrameT = TypeVar("FrameT", PolarsDataFrame, PolarsLazyFrame)