Skip to content

Commit

Permalink
feat: add AnonymousExprError (#1816)
Browse files Browse the repository at this point in the history
  • Loading branch information
EdAbati authored Jan 17, 2025
1 parent f0e82cb commit fb1d34e
Show file tree
Hide file tree
Showing 18 changed files with 106 additions and 170 deletions.
10 changes: 4 additions & 6 deletions narwhals/_arrow/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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 AnonymousExprError
from narwhals.exceptions import ColumnNotFoundError
from narwhals.typing import CompliantExpr
from narwhals.utils import Implementation
Expand Down Expand Up @@ -390,12 +391,9 @@ def clip(self: Self, lower_bound: Any | None, upper_bound: Any | None) -> Self:
def over(self: Self, keys: list[str]) -> Self:
def func(df: ArrowDataFrame) -> list[ArrowSeries]:
if self._output_names is None:
msg = (
"Anonymous expressions are not supported in over.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".over"
raise AnonymousExprError.from_expr_name(msg)

tmp = df.group_by(*keys, drop_null_keys=False).agg(self)
tmp = df.select(*keys).join(
tmp, how="left", left_on=keys, right_on=keys, suffix="_right"
Expand Down
50 changes: 14 additions & 36 deletions narwhals/_arrow/expr_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import TYPE_CHECKING
from typing import Callable

from narwhals.exceptions import AnonymousExprError

if TYPE_CHECKING:
from typing_extensions import Self

Expand All @@ -17,12 +19,8 @@ def keep(self: Self) -> ArrowExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.keep`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.keep"
raise AnonymousExprError.from_expr_name(msg)

return self._compliant_expr.__class__(
lambda df: [
Expand All @@ -42,12 +40,8 @@ def map(self: Self, function: Callable[[str], str]) -> ArrowExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.map`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.map"
raise AnonymousExprError.from_expr_name(msg)

output_names = [function(str(name)) for name in root_names]

Expand All @@ -68,12 +62,8 @@ def map(self: Self, function: Callable[[str], str]) -> ArrowExpr:
def prefix(self: Self, prefix: str) -> ArrowExpr:
root_names = self._compliant_expr._root_names
if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.prefix`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.prefix"
raise AnonymousExprError.from_expr_name(msg)

output_names = [prefix + str(name) for name in root_names]
return self._compliant_expr.__class__(
Expand All @@ -93,12 +83,8 @@ def prefix(self: Self, prefix: str) -> ArrowExpr:
def suffix(self: Self, suffix: str) -> ArrowExpr:
root_names = self._compliant_expr._root_names
if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.suffix`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.suffix"
raise AnonymousExprError.from_expr_name(msg)

output_names = [str(name) + suffix for name in root_names]

Expand All @@ -120,12 +106,8 @@ def to_lowercase(self: Self) -> ArrowExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.to_lowercase`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.to_lowercase"
raise AnonymousExprError.from_expr_name(msg)
output_names = [str(name).lower() for name in root_names]

return self._compliant_expr.__class__(
Expand All @@ -146,12 +128,8 @@ def to_uppercase(self: Self) -> ArrowExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.to_uppercase`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.to_uppercase"
raise AnonymousExprError.from_expr_name(msg)
output_names = [str(name).upper() for name in root_names]

return self._compliant_expr.__class__(
Expand Down
9 changes: 3 additions & 6 deletions narwhals/_arrow/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from narwhals._expression_parsing import is_simple_aggregation
from narwhals._expression_parsing import parse_into_exprs
from narwhals.exceptions import AnonymousExprError
from narwhals.utils import generate_temporary_column_name
from narwhals.utils import remove_prefix

Expand Down Expand Up @@ -61,12 +62,8 @@ def agg(
)
for expr in exprs:
if expr._output_names is None:
msg = (
"Anonymous expressions are not supported in group_by.agg.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = "group_by.agg"
raise AnonymousExprError.from_expr_name(msg)

return agg_arrow(
self._grouped,
Expand Down
9 changes: 3 additions & 6 deletions narwhals/_dask/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from narwhals._dask.utils import narwhals_to_native_dtype
from narwhals._expression_parsing import infer_new_root_output_names
from narwhals._pandas_like.utils import native_to_narwhals_dtype
from narwhals.exceptions import AnonymousExprError
from narwhals.exceptions import ColumnNotFoundError
from narwhals.exceptions import InvalidOperationError
from narwhals.typing import CompliantExpr
Expand Down Expand Up @@ -690,12 +691,8 @@ def gather_every(self: Self, n: int, offset: int = 0) -> NoReturn:
def over(self: Self, keys: list[str]) -> Self:
def func(df: DaskLazyFrame) -> list[Any]:
if self._output_names is None:
msg = (
"Anonymous expressions are not supported in over.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = "over"
raise AnonymousExprError.from_expr_name(msg)

if df._native_frame.npartitions == 1: # pragma: no cover
tmp = df.group_by(*keys, drop_null_keys=False).agg(self)
Expand Down
50 changes: 14 additions & 36 deletions narwhals/_dask/expr_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import TYPE_CHECKING
from typing import Callable

from narwhals.exceptions import AnonymousExprError

if TYPE_CHECKING:
from typing_extensions import Self

Expand All @@ -17,12 +19,8 @@ def keep(self: Self) -> DaskExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.keep`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.keep"
raise AnonymousExprError.from_expr_name(msg)

return self._compliant_expr.__class__(
lambda df: [
Expand All @@ -43,12 +41,8 @@ def map(self: Self, function: Callable[[str], str]) -> DaskExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.map`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.map"
raise AnonymousExprError.from_expr_name(msg)

output_names = [function(str(name)) for name in root_names]

Expand All @@ -70,12 +64,8 @@ def map(self: Self, function: Callable[[str], str]) -> DaskExpr:
def prefix(self: Self, prefix: str) -> DaskExpr:
root_names = self._compliant_expr._root_names
if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.prefix`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.prefix"
raise AnonymousExprError.from_expr_name(msg)

output_names = [prefix + str(name) for name in root_names]
return self._compliant_expr.__class__(
Expand All @@ -96,12 +86,8 @@ def prefix(self: Self, prefix: str) -> DaskExpr:
def suffix(self: Self, suffix: str) -> DaskExpr:
root_names = self._compliant_expr._root_names
if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.suffix`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.suffix"
raise AnonymousExprError.from_expr_name(msg)

output_names = [str(name) + suffix for name in root_names]

Expand All @@ -124,12 +110,8 @@ def to_lowercase(self: Self) -> DaskExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.to_lowercase`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.to_lowercase"
raise AnonymousExprError.from_expr_name(msg)
output_names = [str(name).lower() for name in root_names]

return self._compliant_expr.__class__(
Expand All @@ -151,12 +133,8 @@ def to_uppercase(self: Self) -> DaskExpr:
root_names = self._compliant_expr._root_names

if root_names is None:
msg = (
"Anonymous expressions are not supported in `.name.to_uppercase`.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = ".name.to_uppercase"
raise AnonymousExprError.from_expr_name(msg)
output_names = [str(name).upper() for name in root_names]

return self._compliant_expr.__class__(
Expand Down
9 changes: 3 additions & 6 deletions narwhals/_dask/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from narwhals._expression_parsing import is_simple_aggregation
from narwhals._expression_parsing import parse_into_exprs
from narwhals.exceptions import AnonymousExprError
from narwhals.utils import remove_prefix

if TYPE_CHECKING:
Expand Down Expand Up @@ -110,12 +111,8 @@ def agg(
output_names: list[str] = copy(self._keys)
for expr in exprs:
if expr._output_names is None:
msg = (
"Anonymous expressions are not supported in group_by.agg.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = "group_by.agg"
raise AnonymousExprError.from_expr_name(msg)

output_names.extend(expr._output_names)

Expand Down
9 changes: 3 additions & 6 deletions narwhals/_duckdb/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import TYPE_CHECKING

from narwhals._expression_parsing import parse_into_exprs
from narwhals.exceptions import AnonymousExprError

if TYPE_CHECKING:
from narwhals._duckdb.dataframe import DuckDBLazyFrame
Expand Down Expand Up @@ -33,12 +34,8 @@ def agg(
output_names: list[str] = copy(self._keys)
for expr in exprs:
if expr._output_names is None: # pragma: no cover
msg = (
"Anonymous expressions are not supported in group_by.agg.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = "group_by.agg"
raise AnonymousExprError.from_expr_name(msg)

output_names.extend(expr._output_names)

Expand Down
17 changes: 5 additions & 12 deletions narwhals/_pandas_like/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from narwhals._pandas_like.utils import rename
from narwhals.dependencies import get_numpy
from narwhals.dependencies import is_numpy_array
from narwhals.exceptions import AnonymousExprError
from narwhals.exceptions import ColumnNotFoundError
from narwhals.typing import CompliantExpr

Expand Down Expand Up @@ -399,12 +400,8 @@ def func(df: PandasLikeDataFrame) -> list[PandasLikeSeries]:
self._output_names is None or self._root_names is None
): # pragma: no cover
# Technically unreachable, but keep this for safety
msg = (
"Anonymous expressions are not supported in over.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = "over"
raise AnonymousExprError.from_expr_name(msg)

reverse = self._kwargs.get("reverse", False)
if reverse:
Expand Down Expand Up @@ -452,12 +449,8 @@ def func(df: PandasLikeDataFrame) -> list[PandasLikeSeries]:

def func(df: PandasLikeDataFrame) -> list[PandasLikeSeries]:
if self._output_names is None:
msg = (
"Anonymous expressions are not supported in over.\n"
"Instead of `nw.all()`, try using a named expression, such as "
"`nw.col('a', 'b')`\n"
)
raise ValueError(msg)
msg = "over"
raise AnonymousExprError.from_expr_name(msg)
tmp = df.group_by(*keys, drop_null_keys=False).agg(self)
tmp = df.select(*keys).join(
tmp, how="left", left_on=keys, right_on=keys, suffix="_right"
Expand Down
Loading

0 comments on commit fb1d34e

Please sign in to comment.