Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
931d7ea
refactor: Add `_compliant` sub-package
dangotbanned Mar 5, 2025
cef630e
refactor: migrate imports, delete `_selectors`
dangotbanned Mar 5, 2025
ca2ca24
refactor: Export `Eval(Names|Series)`
dangotbanned Mar 5, 2025
9cc3ce8
feat(DRAFT): Add placeholder `(Eager|Lazy)Expr` protocols
dangotbanned Mar 5, 2025
53413ae
ci: ignore coverage
dangotbanned Mar 5, 2025
9efd3c6
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 6, 2025
2bf05fb
refactor: avoid adding `typing.IntoCompliantExpr`
dangotbanned Mar 6, 2025
7fb4914
refactor: avoid adding `typing.CompliantFrameT`
dangotbanned Mar 6, 2025
51820a1
refactor: avoid adding `typing.CompliantSeriesT_co`
dangotbanned Mar 6, 2025
8f1c5ca
refactor: avoid adding `typing.CompliantNamespace`
dangotbanned Mar 6, 2025
5bf2bdb
refactor: avoid adding `typing.CompliantExpr`
dangotbanned Mar 6, 2025
075228b
fix(typing): Resolve `NativeExpr`-related issues
dangotbanned Mar 6, 2025
a0fe52a
refactor(typing): spec out and reuse `LazyExpr`
dangotbanned Mar 6, 2025
23fdf8f
be quiet `mypy`!
dangotbanned Mar 6, 2025
d58e2c9
feat(DRAFT): `EagerExpr` from `_expression_parsing.py`
dangotbanned Mar 6, 2025
6cb725c
feat: Generic dunders
dangotbanned Mar 6, 2025
bc93782
chore(typing): fix variance issues
dangotbanned Mar 6, 2025
7d48726
feat(DRAFT): add a couple more methods
dangotbanned Mar 6, 2025
75b33c4
feat: Spec-out all generic parts of `EagerExpr`
dangotbanned Mar 6, 2025
b38b25b
Merge branch 'main' into compliant-package
dangotbanned Mar 7, 2025
5d766c2
revert: remove unused `_series` property
dangotbanned Mar 7, 2025
a066213
feat: add `EagerExpr.from_column_(names|indices)`
dangotbanned Mar 7, 2025
57ab13b
chore: add some notes on `Eager(Namespace|Series)`
dangotbanned Mar 7, 2025
e16e942
update import/exports
dangotbanned Mar 7, 2025
364d2ee
fix(typing): Use `Self`
dangotbanned Mar 7, 2025
484c997
refactor(DRAFT): start implementing `Arrow*`
dangotbanned Mar 7, 2025
77b599a
fix: typo and add missing `count`
dangotbanned Mar 7, 2025
7a1a653
refactor(DRAFT): mostly ready `ArrowExpr`
dangotbanned Mar 7, 2025
afddd4c
refactor(DRAFT): Possibly all `ArrowExpr`?
dangotbanned Mar 7, 2025
f87a629
refactor: migrate to `ArrowExpr._reuse_series_namespace_implementation`
dangotbanned Mar 7, 2025
d509fc9
fix: fix typo lol
dangotbanned Mar 7, 2025
2535f35
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 7, 2025
9d55d2a
chore: remove `ArrowExpr` parts from `_expression_parsing`
dangotbanned Mar 7, 2025
f16ece2
ci: get coverage for properties
dangotbanned Mar 7, 2025
388f715
refactor(DRAFT): start migrating `PandasLike*`
dangotbanned Mar 7, 2025
4bc483f
refactor(DRAFT): big progress on `Pandas*`
dangotbanned Mar 7, 2025
9d7fc16
refactor: migrate expr namespaces
dangotbanned Mar 7, 2025
bf18326
fix: dont `__bool__` a `pd.Series`
dangotbanned Mar 7, 2025
73656f1
fix(DRAFT): extend `is_eager_namespace`
dangotbanned Mar 7, 2025
c606ea0
refactor: drop all unused `_expression_parsing`
dangotbanned Mar 7, 2025
6ce86c3
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 7, 2025
00a3442
refactor: remove `implementation` from method names
dangotbanned Mar 7, 2025
7cd3e2d
refactor: rename `attr` -> `method_name`, add annotation
dangotbanned Mar 7, 2025
035976b
feat: Define `CompliantSeries._to_expr`
dangotbanned Mar 8, 2025
874bf6d
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 8, 2025
ba14a82
refactor: get coverage and simplify `_polars.namespace`
dangotbanned Mar 8, 2025
e64626a
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 8, 2025
612df69
refactor: avoid reimplementing `ArrowSeries._from_iterable`
dangotbanned Mar 8, 2025
5a13b63
feat: Super reusable namespaces 🀯
dangotbanned Mar 8, 2025
c662d85
maybe `3.8` compat?
dangotbanned Mar 8, 2025
d53ce01
chore(typing): add some safety for `.name`
dangotbanned Mar 8, 2025
2777822
feat: adds `EagerExprNameNamespace`
dangotbanned Mar 8, 2025
b05f132
Merge branch 'main' into compliant-package
dangotbanned Mar 8, 2025
067252b
refactor: Simplify `EagerExprNameNamespace`
dangotbanned Mar 8, 2025
0d57240
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 9, 2025
309f910
chore: resolve more conflicts from (#2168)
dangotbanned Mar 9, 2025
3a434c2
Merge branch 'main' into compliant-package
dangotbanned Mar 9, 2025
8ec9cd9
docs: add module-level doc
dangotbanned Mar 9, 2025
c368a60
docs(typing): Explain `is_eager_expr`
dangotbanned Mar 9, 2025
7d3addc
docs: `NativeExpr`
dangotbanned Mar 9, 2025
66ecf84
chore: remove outdated comments
dangotbanned Mar 9, 2025
d1dd6ce
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 9, 2025
b3bdb3b
fix(typing): `EagerNamespace.all_horizontal`
dangotbanned Mar 9, 2025
0f6f803
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 10, 2025
40d718f
refactor: Add `EagerExprStructNamespace`
dangotbanned Mar 10, 2025
1338d34
Merge remote-tracking branch 'upstream/main' into compliant-package
dangotbanned Mar 10, 2025
c7ba9f9
Merge branch 'main' into compliant-package
dangotbanned Mar 10, 2025
7119ad2
Merge branch 'main' into compliant-package
dangotbanned Mar 10, 2025
42dd2c4
refactor: add `EagerDataFrame._evaluate_into_expr(s)`
dangotbanned Mar 10, 2025
12da35b
chore: remove `expr.py` notes
dangotbanned Mar 11, 2025
79c7c8d
chore: remove `namespace.py` notes
dangotbanned Mar 11, 2025
34dd94a
docs: Use more helpful deprecation message
dangotbanned Mar 11, 2025
617ebc3
Merge branch 'main' into compliant-package
dangotbanned Mar 11, 2025
9b93ef8
Merge branch 'main' into compliant-package
dangotbanned Mar 11, 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
2 changes: 1 addition & 1 deletion narwhals/_arrow/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
from narwhals._arrow.expr_name import ArrowExprNameNamespace
from narwhals._arrow.expr_str import ArrowExprStringNamespace
from narwhals._arrow.series import ArrowSeries
from narwhals._compliant import CompliantExpr
from narwhals._expression_parsing import ExprKind
from narwhals._expression_parsing import evaluate_output_names_and_aliases
from narwhals._expression_parsing import is_scalar_like
from narwhals._expression_parsing import reuse_series_implementation
from narwhals.dependencies import get_numpy
from narwhals.dependencies import is_numpy_array
from narwhals.exceptions import ColumnNotFoundError
from narwhals.typing import CompliantExpr
from narwhals.utils import Implementation
from narwhals.utils import not_implemented

Expand Down
2 changes: 1 addition & 1 deletion narwhals/_arrow/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
from narwhals._arrow.utils import horizontal_concat
from narwhals._arrow.utils import nulls_like
from narwhals._arrow.utils import vertical_concat
from narwhals._compliant import CompliantNamespace
from narwhals._expression_parsing import combine_alias_output_names
from narwhals._expression_parsing import combine_evaluate_output_names
from narwhals.typing import CompliantNamespace
from narwhals.utils import Implementation
from narwhals.utils import exclude_column_names
from narwhals.utils import get_column_names
Expand Down
8 changes: 4 additions & 4 deletions narwhals/_arrow/selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
from typing import TYPE_CHECKING

from narwhals._arrow.expr import ArrowExpr
from narwhals._selectors import CompliantSelector
from narwhals._selectors import EagerSelectorNamespace
from narwhals._compliant import CompliantSelector
from narwhals._compliant import EagerSelectorNamespace

if TYPE_CHECKING:
from typing_extensions import Self

from narwhals._arrow.dataframe import ArrowDataFrame
from narwhals._arrow.series import ArrowSeries
from narwhals._selectors import EvalNames
from narwhals._selectors import EvalSeries
from narwhals._compliant import EvalNames
from narwhals._compliant import EvalSeries
from narwhals.utils import _FullContext


Expand Down
37 changes: 37 additions & 0 deletions narwhals/_compliant/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from __future__ import annotations

from narwhals._compliant.dataframe import CompliantDataFrame
from narwhals._compliant.dataframe import CompliantLazyFrame
from narwhals._compliant.expr import CompliantExpr
from narwhals._compliant.expr import LazyExpr
from narwhals._compliant.namespace import CompliantNamespace
from narwhals._compliant.selectors import CompliantSelector
from narwhals._compliant.selectors import CompliantSelectorNamespace
from narwhals._compliant.selectors import EagerSelectorNamespace
from narwhals._compliant.selectors import EvalNames
from narwhals._compliant.selectors import EvalSeries
from narwhals._compliant.selectors import LazySelectorNamespace
from narwhals._compliant.series import CompliantSeries
from narwhals._compliant.typing import CompliantFrameT
from narwhals._compliant.typing import CompliantSeriesOrNativeExprT_co
from narwhals._compliant.typing import CompliantSeriesT_co
from narwhals._compliant.typing import IntoCompliantExpr

__all__ = [
"CompliantDataFrame",
"CompliantExpr",
"CompliantFrameT",
"CompliantLazyFrame",
"CompliantNamespace",
"CompliantSelector",
"CompliantSelectorNamespace",
"CompliantSeries",
"CompliantSeriesOrNativeExprT_co",
"CompliantSeriesT_co",
"EagerSelectorNamespace",
"EvalNames",
"EvalSeries",
"IntoCompliantExpr",
"LazyExpr",
"LazySelectorNamespace",
]
82 changes: 82 additions & 0 deletions narwhals/_compliant/dataframe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import Any
from typing import Iterator
from typing import Mapping
from typing import Protocol
from typing import Sequence
from typing import TypeVar

from narwhals._compliant.typing import CompliantSeriesT_co
from narwhals._compliant.typing import EagerSeriesT
from narwhals._compliant.typing import EagerSeriesT_co

if TYPE_CHECKING:
from typing_extensions import Self
from typing_extensions import TypeIs

from narwhals._compliant.expr import EagerExpr
from narwhals.dtypes import DType

__all__ = ["CompliantDataFrame", "CompliantLazyFrame"]

T = TypeVar("T")


class CompliantDataFrame(Protocol[CompliantSeriesT_co]):
def __narwhals_dataframe__(self) -> Self: ...
def __narwhals_namespace__(self) -> Any: ...
def simple_select(
self, *column_names: str
) -> Self: ... # `select` where all args are column names.
def aggregate(self, *exprs: Any) -> Self: # pragma: no cover
... # `select` where all args are aggregations or literals
# (so, no broadcasting is necessary).

@property
def columns(self) -> Sequence[str]: ...
@property
def schema(self) -> Mapping[str, DType]: ...
def get_column(self, name: str) -> CompliantSeriesT_co: ...
def iter_columns(self) -> Iterator[CompliantSeriesT_co]: ...


class CompliantLazyFrame(Protocol):
def __narwhals_lazyframe__(self) -> Self: ...
def __narwhals_namespace__(self) -> Any: ...
def simple_select(
self, *column_names: str
) -> Self: ... # `select` where all args are column names.
def aggregate(self, *exprs: Any) -> Self: # pragma: no cover
... # `select` where all args are aggregations or literals
# (so, no broadcasting is necessary).

@property
def columns(self) -> Sequence[str]: ...
@property
def schema(self) -> Mapping[str, DType]: ...
def _iter_columns(self) -> Iterator[Any]: ...


class EagerDataFrame(CompliantDataFrame[EagerSeriesT_co], Protocol[EagerSeriesT_co]):
def _maybe_evaluate_expr(
self, expr: EagerExpr[EagerDataFrame[EagerSeriesT_co], EagerSeriesT_co] | T, /
) -> EagerSeriesT_co | T:
if is_eager_expr(expr):
result: Sequence[EagerSeriesT_co] = expr(self)
if len(result) > 1:
msg = (
"Multi-output expressions (e.g. `nw.all()` or `nw.col('a', 'b')`) "
"are not supported in this context"
)
raise ValueError(msg)
return result[0]
return expr


# NOTE: DON'T CHANGE THIS EITHER
def is_eager_expr(
obj: EagerExpr[Any, EagerSeriesT] | Any,
) -> TypeIs[EagerExpr[Any, EagerSeriesT]]:
return hasattr(obj, "__narwhals_expr__")
Loading
Loading