Skip to content

Commit f76311d

Browse files
authored
refactor: Move/remove private Compliant*Frame methods (#2934)
1 parent 79c00c0 commit f76311d

File tree

7 files changed

+42
-38
lines changed

7 files changed

+42
-38
lines changed

narwhals/_compliant/dataframe.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,6 @@ def write_csv(self, file: str | Path | BytesIO) -> None: ...
258258
def write_csv(self, file: str | Path | BytesIO | None) -> str | None: ...
259259
def write_parquet(self, file: str | Path | BytesIO) -> None: ...
260260

261-
def _evaluate_aliases(self, *exprs: CompliantExprT_contra) -> list[str]:
262-
it = (expr._evaluate_aliases(self) for expr in exprs)
263-
return list(chain.from_iterable(it))
264-
265-
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
266-
return check_columns_exist(subset, available=self.columns)
267-
268261

269262
class CompliantLazyFrame(
270263
_StoresNative[NativeFrameT],
@@ -357,17 +350,6 @@ def unpivot(
357350
) -> Self: ...
358351
def with_columns(self, *exprs: CompliantExprT_contra) -> Self: ...
359352
def with_row_index(self, name: str, order_by: Sequence[str]) -> Self: ...
360-
def _evaluate_expr(self, expr: CompliantExprT_contra, /) -> Any:
361-
result = expr(self)
362-
assert len(result) == 1 # debug assertion # noqa: S101
363-
return result[0]
364-
365-
def _evaluate_aliases(self, *exprs: CompliantExprT_contra) -> list[str]:
366-
it = (expr._evaluate_aliases(self) for expr in exprs)
367-
return list(chain.from_iterable(it))
368-
369-
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
370-
return check_columns_exist(subset, available=self.columns)
371353

372354

373355
class EagerDataFrame(
@@ -391,6 +373,9 @@ def _with_native(
391373
self, df: NativeFrameT, *, validate_column_names: bool = True
392374
) -> Self: ...
393375

376+
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
377+
return check_columns_exist(subset, available=self.columns)
378+
394379
def _evaluate_expr(self, expr: EagerExprT, /) -> EagerSeriesT:
395380
"""Evaluate `expr` and ensure it has a **single** output."""
396381
result: Sequence[EagerSeriesT] = expr(self)

narwhals/_compliant/group_by.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from __future__ import annotations
22

33
import re
4+
from itertools import chain
45
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Protocol, TypeVar
56

67
from narwhals._compliant.typing import (
78
CompliantDataFrameAny,
89
CompliantDataFrameT_co,
910
CompliantExprT_contra,
11+
CompliantFrameT,
1012
CompliantFrameT_co,
1113
CompliantLazyFrameAny,
1214
DepthTrackingExprAny,
@@ -17,7 +19,9 @@
1719
from narwhals._utils import is_sequence_of
1820

1921
if TYPE_CHECKING:
20-
from collections.abc import Iterator, Mapping, Sequence
22+
from collections.abc import Iterable, Iterator, Mapping, Sequence
23+
24+
from narwhals._compliant.expr import CompliantExpr
2125

2226
_SameFrameT = TypeVar("_SameFrameT", CompliantDataFrameAny, CompliantLazyFrameAny)
2327

@@ -32,6 +36,13 @@
3236
_RE_LEAF_NAME: re.Pattern[str] = re.compile(r"(\w+->)")
3337

3438

39+
def _evaluate_aliases(
40+
frame: CompliantFrameT, exprs: Iterable[CompliantExpr[CompliantFrameT, Any]], /
41+
) -> list[str]:
42+
it = (expr._evaluate_aliases(frame) for expr in exprs)
43+
return list(chain.from_iterable(it))
44+
45+
3546
class CompliantGroupBy(Protocol[CompliantFrameT_co, CompliantExprT_contra]):
3647
_compliant_frame: Any
3748

@@ -98,7 +109,7 @@ def _temporary_name(key: str) -> str:
98109
key_str = str(key) # pandas allows non-string column names :sob:
99110
return f"_{key_str}_tmp{'_' * (tmp_name_length - len(key_str) - 5)}"
100111

101-
output_names = compliant_frame._evaluate_aliases(*keys)
112+
output_names = _evaluate_aliases(compliant_frame, keys)
102113

103114
safe_keys = [
104115
# multi-output expression cannot have duplicate names, hence it's safe to suffix
@@ -110,7 +121,7 @@ def _temporary_name(key: str) -> str:
110121
]
111122
return (
112123
compliant_frame.with_columns(*safe_keys),
113-
compliant_frame._evaluate_aliases(*safe_keys),
124+
_evaluate_aliases(compliant_frame, safe_keys),
114125
output_names,
115126
)
116127

narwhals/_dask/dataframe.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
ValidateBackendVersion,
1414
_remap_full_join_keys,
1515
check_column_names_are_unique,
16+
check_columns_exist,
1617
generate_temporary_column_name,
1718
not_implemented,
1819
parse_columns_to_drop,
@@ -35,6 +36,7 @@
3536
from narwhals._utils import Version, _LimitedContext
3637
from narwhals.dataframe import LazyFrame
3738
from narwhals.dtypes import DType
39+
from narwhals.exceptions import ColumnNotFoundError
3840
from narwhals.typing import AsofJoinStrategy, JoinStrategy, LazyUniqueKeepStrategy
3941

4042
Incomplete: TypeAlias = "Any"
@@ -97,6 +99,9 @@ def _with_version(self, version: Version) -> Self:
9799
def _with_native(self, df: Any) -> Self:
98100
return self.__class__(df, version=self._version)
99101

102+
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
103+
return check_columns_exist(subset, available=self.columns)
104+
100105
def _iter_columns(self) -> Iterator[dx.Series]:
101106
for _col, ser in self.native.items(): # noqa: PERF102
102107
yield ser

narwhals/_ibis/dataframe.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import ibis.expr.types as ir
99

1010
from narwhals._ibis.utils import evaluate_exprs, native_to_narwhals_dtype
11+
from narwhals._sql.dataframe import SQLLazyFrame
1112
from narwhals._utils import (
1213
Implementation,
1314
ValidateBackendVersion,
@@ -16,7 +17,6 @@
1617
parse_columns_to_drop,
1718
)
1819
from narwhals.exceptions import ColumnNotFoundError, InvalidOperationError
19-
from narwhals.typing import CompliantLazyFrame
2020

2121
if TYPE_CHECKING:
2222
from collections.abc import Iterable, Iterator, Mapping, Sequence
@@ -43,9 +43,7 @@
4343

4444

4545
class IbisLazyFrame(
46-
CompliantLazyFrame[
47-
"IbisExpr", "ir.Table", "LazyFrame[ir.Table] | DataFrameV1[ir.Table]"
48-
],
46+
SQLLazyFrame["IbisExpr", "ir.Table", "LazyFrame[ir.Table] | DataFrameV1[ir.Table]"],
4947
ValidateBackendVersion,
5048
):
5149
_implementation = Implementation.IBIS

narwhals/_polars/dataframe.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from narwhals._utils import (
1616
Implementation,
1717
_into_arrow_table,
18-
check_columns_exist,
1918
convert_str_slice_to_int_slice,
2019
is_compliant_series,
2120
is_index_selector,
@@ -165,11 +164,6 @@ def _with_version(self, version: Version) -> Self:
165164
def from_native(cls, data: NativePolarsFrame, /, *, context: _LimitedContext) -> Self:
166165
return cls(data, version=context._version)
167166

168-
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
169-
return check_columns_exist( # pragma: no cover
170-
subset, available=self.columns
171-
)
172-
173167
def simple_select(self, *column_names: str) -> Self:
174168
return self._with_native(self.native.select(*column_names))
175169

@@ -263,9 +257,6 @@ class PolarsDataFrame(PolarsBaseFrame[pl.DataFrame]):
263257
write_csv: Method[Any]
264258
write_parquet: Method[None]
265259

266-
# CompliantDataFrame
267-
_evaluate_aliases: Any
268-
269260
@classmethod
270261
def from_arrow(cls, data: IntoArrowTable, /, *, context: _LimitedContext) -> Self:
271262
if context._implementation._backend_version() >= (1, 3):
@@ -558,10 +549,7 @@ def join(
558549

559550

560551
class PolarsLazyFrame(PolarsBaseFrame[pl.LazyFrame]):
561-
# CompliantLazyFrame
562552
sink_parquet: Method[None]
563-
_evaluate_expr: Any
564-
_evaluate_aliases: Any
565553

566554
@staticmethod
567555
def _is_native(obj: pl.LazyFrame | Any) -> TypeIs[pl.LazyFrame]:

narwhals/_sql/dataframe.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
from narwhals._compliant.dataframe import CompliantLazyFrame
66
from narwhals._compliant.typing import CompliantExprT_contra, NativeExprT, NativeFrameT
77
from narwhals._translate import ToNarwhalsT_co
8+
from narwhals._utils import check_columns_exist
89

910
if TYPE_CHECKING:
11+
from collections.abc import Sequence
12+
1013
from typing_extensions import Self, TypeAlias
1114

1215
from narwhals._compliant.window import WindowInputs
1316
from narwhals._sql.expr import SQLExpr
17+
from narwhals.exceptions import ColumnNotFoundError
1418

1519
Incomplete: TypeAlias = Any
1620

@@ -28,3 +32,11 @@ def _evaluate_window_expr(
2832
result = expr.window_function(self, window_inputs)
2933
assert len(result) == 1 # debug assertion # noqa: S101
3034
return result[0]
35+
36+
def _evaluate_expr(self, expr: CompliantExprT_contra, /) -> Any:
37+
result = expr(self)
38+
assert len(result) == 1 # debug assertion # noqa: S101
39+
return result[0]
40+
41+
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
42+
return check_columns_exist(subset, available=self.columns)

narwhals/dataframe.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from narwhals._utils import (
2525
Implementation,
2626
Version,
27+
check_columns_exist,
2728
flatten,
2829
generate_repr,
2930
is_compliant_dataframe,
@@ -42,6 +43,7 @@
4243
is_pyarrow_table,
4344
)
4445
from narwhals.exceptions import (
46+
ColumnNotFoundError,
4547
InvalidIntoExprError,
4648
InvalidOperationError,
4749
PerformanceWarning,
@@ -130,6 +132,9 @@ def _flatten_and_extract(
130132
def _extract_compliant(self, arg: Any) -> Any:
131133
raise NotImplementedError
132134

135+
def _check_columns_exist(self, subset: Sequence[str]) -> ColumnNotFoundError | None:
136+
return check_columns_exist(subset, available=self.columns)
137+
133138
@property
134139
def schema(self) -> Schema:
135140
return Schema(self._compliant_frame.schema.items())
@@ -177,7 +182,7 @@ def select(
177182
)
178183
except Exception as e:
179184
# Column not found is the only thing that can realistically be raised here.
180-
if error := self._compliant_frame._check_columns_exist(flat_exprs):
185+
if error := self._check_columns_exist(flat_exprs):
181186
raise error from e
182187
raise
183188
compliant_exprs, kinds = self._flatten_and_extract(*flat_exprs, **named_exprs)

0 commit comments

Comments
 (0)