diff --git a/docs/api-reference/exceptions.md b/docs/api-reference/exceptions.md new file mode 100644 index 000000000..b6841597c --- /dev/null +++ b/docs/api-reference/exceptions.md @@ -0,0 +1,11 @@ +# `narwhals.exceptions` + +::: narwhals.exceptions + handler: python + options: + members: + - ColumnNotFoundError + - InvalidIntoExprError + - InvalidOperationError + show_source: false + show_bases: false diff --git a/docs/api-reference/index.md b/docs/api-reference/index.md index b4cbc78fc..8a8195fae 100644 --- a/docs/api-reference/index.md +++ b/docs/api-reference/index.md @@ -16,5 +16,6 @@ - [narwhals.Series.str](series_str.md) - [narwhals.dependencies](dependencies.md) - [narwhals.dtypes](dtypes.md) +- [narwhals.exceptions](exceptions.md) - [narwhals.selectors](selectors.md) - [narwhals.typing](typing.md) diff --git a/mkdocs.yml b/mkdocs.yml index a4f4fe1ea..4c3369655 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -44,6 +44,7 @@ nav: - api-reference/series_str.md - api-reference/dependencies.md - api-reference/dtypes.md + - api-reference/exceptions.md - api-reference/selectors.md - api-reference/typing.md - This: this.md diff --git a/narwhals/__init__.py b/narwhals/__init__.py index e69db9dae..c990f01fd 100644 --- a/narwhals/__init__.py +++ b/narwhals/__init__.py @@ -1,6 +1,7 @@ from __future__ import annotations from narwhals import dependencies +from narwhals import exceptions from narwhals import selectors from narwhals import stable from narwhals.dataframe import DataFrame @@ -71,72 +72,73 @@ __version__ = "1.13.5" __all__ = [ - "dependencies", - "selectors", + "Array", + "Boolean", + "Categorical", + "DataFrame", + "Date", + "Datetime", + "Duration", + "Enum", + "Expr", + "Field", + "Float32", + "Float64", + "Int16", + "Int32", + "Int64", + "Int8", + "LazyFrame", + "List", + "Object", + "Schema", + "Series", + "String", + "Struct", + "UInt16", + "UInt32", + "UInt64", + "UInt8", + "Unknown", + "all", + "all_horizontal", + "any_horizontal", + "col", "concat", - "from_dict", + "concat_str", + "dependencies", + "exceptions", "from_arrow", + "from_dict", + "from_dict", + "from_native", "generate_temporary_column_name", "get_level", - "new_series", - "to_native", - "from_native", + "get_native_namespace", "is_ordered_categorical", + "len", + "lit", + "max", + "max_horizontal", "maybe_align_index", "maybe_convert_dtypes", "maybe_get_index", "maybe_reset_index", "maybe_set_index", - "get_native_namespace", - "to_py_scalar", - "all", - "all_horizontal", - "any_horizontal", - "col", - "concat_str", - "len", - "lit", - "max", - "max_horizontal", "mean", "mean_horizontal", "median", "min", "min_horizontal", + "narwhalify", + "new_series", "nth", + "selectors", + "show_versions", + "stable", "sum", "sum_horizontal", + "to_native", + "to_py_scalar", "when", - "DataFrame", - "LazyFrame", - "Series", - "Expr", - "Int64", - "Int32", - "Int16", - "Int8", - "UInt64", - "UInt32", - "UInt16", - "UInt8", - "Float64", - "Float32", - "Boolean", - "Object", - "Unknown", - "Categorical", - "Enum", - "String", - "Datetime", - "Duration", - "Field", - "Struct", - "Array", - "List", - "Date", - "narwhalify", - "show_versions", - "stable", - "Schema", - "from_dict", ] diff --git a/narwhals/_arrow/expr.py b/narwhals/_arrow/expr.py index 6d5adc6aa..772505ee6 100644 --- a/narwhals/_arrow/expr.py +++ b/narwhals/_arrow/expr.py @@ -6,11 +6,11 @@ from typing import Literal from typing import Sequence -from narwhals._exceptions import ColumnNotFoundError from narwhals._expression_parsing import reuse_series_implementation from narwhals._expression_parsing import reuse_series_namespace_implementation from narwhals.dependencies import get_numpy from narwhals.dependencies import is_numpy_array +from narwhals.exceptions import ColumnNotFoundError from narwhals.utils import Implementation if TYPE_CHECKING: diff --git a/narwhals/_arrow/series.py b/narwhals/_arrow/series.py index 19c424a79..75a3cabde 100644 --- a/narwhals/_arrow/series.py +++ b/narwhals/_arrow/series.py @@ -264,7 +264,7 @@ def mean(self) -> int: def median(self) -> int: import pyarrow.compute as pc # ignore-banned-import() - from narwhals._exceptions import InvalidOperationError + from narwhals.exceptions import InvalidOperationError if not self.dtype.is_numeric(): msg = "`median` operation not supported for non-numeric input type." diff --git a/narwhals/_dask/expr.py b/narwhals/_dask/expr.py index 2b50a962e..142349a8c 100644 --- a/narwhals/_dask/expr.py +++ b/narwhals/_dask/expr.py @@ -11,10 +11,10 @@ from narwhals._dask.utils import add_row_index from narwhals._dask.utils import maybe_evaluate from narwhals._dask.utils import narwhals_to_native_dtype -from narwhals._exceptions import ColumnNotFoundError from narwhals._pandas_like.utils import calculate_timestamp_date from narwhals._pandas_like.utils import calculate_timestamp_datetime from narwhals._pandas_like.utils import native_to_narwhals_dtype +from narwhals.exceptions import ColumnNotFoundError from narwhals.utils import Implementation from narwhals.utils import generate_temporary_column_name @@ -400,15 +400,14 @@ def mean(self) -> Self: ) def median(self) -> Self: - from dask_expr._shuffle import _is_numeric_cast_type + from narwhals.exceptions import InvalidOperationError - from narwhals._exceptions import InvalidOperationError - - def func(_input: dask_expr.Series) -> dask_expr.Series: - if not _is_numeric_cast_type(_input.dtype): + def func(s: dask_expr.Series) -> dask_expr.Series: + dtype = native_to_narwhals_dtype(s, self._dtypes, Implementation.DASK) + if not dtype.is_numeric(): msg = "`median` operation not supported for non-numeric input type." raise InvalidOperationError(msg) - return _input.median_approximate() + return s.median_approximate() return self._from_call(func, "median", returns_scalar=True) diff --git a/narwhals/_dask/utils.py b/narwhals/_dask/utils.py index f822245bc..ef9e7439d 100644 --- a/narwhals/_dask/utils.py +++ b/narwhals/_dask/utils.py @@ -3,10 +3,10 @@ from typing import TYPE_CHECKING from typing import Any -from narwhals._exceptions import InvalidIntoExprError from narwhals.dependencies import get_pandas from narwhals.dependencies import get_polars from narwhals.dependencies import get_pyarrow +from narwhals.exceptions import InvalidIntoExprError from narwhals.utils import isinstance_or_issubclass from narwhals.utils import parse_version diff --git a/narwhals/_expression_parsing.py b/narwhals/_expression_parsing.py index 8c2914eac..050563763 100644 --- a/narwhals/_expression_parsing.py +++ b/narwhals/_expression_parsing.py @@ -12,8 +12,8 @@ from typing import cast from typing import overload -from narwhals._exceptions import InvalidIntoExprError from narwhals.dependencies import is_numpy_array +from narwhals.exceptions import InvalidIntoExprError if TYPE_CHECKING: from narwhals._arrow.dataframe import ArrowDataFrame diff --git a/narwhals/_pandas_like/expr.py b/narwhals/_pandas_like/expr.py index 323517db4..80facd572 100644 --- a/narwhals/_pandas_like/expr.py +++ b/narwhals/_pandas_like/expr.py @@ -6,12 +6,12 @@ from typing import Literal from typing import Sequence -from narwhals._exceptions import ColumnNotFoundError from narwhals._expression_parsing import reuse_series_implementation from narwhals._expression_parsing import reuse_series_namespace_implementation from narwhals._pandas_like.series import PandasLikeSeries from narwhals.dependencies import get_numpy from narwhals.dependencies import is_numpy_array +from narwhals.exceptions import ColumnNotFoundError if TYPE_CHECKING: from typing_extensions import Self diff --git a/narwhals/_pandas_like/series.py b/narwhals/_pandas_like/series.py index 91fd4361c..98caf9213 100644 --- a/narwhals/_pandas_like/series.py +++ b/narwhals/_pandas_like/series.py @@ -427,7 +427,7 @@ def mean(self) -> Any: return ser.mean() def median(self) -> Any: - from narwhals._exceptions import InvalidOperationError + from narwhals.exceptions import InvalidOperationError if not self.dtype.is_numeric(): msg = "`median` operation not supported for non-numeric input type." diff --git a/narwhals/_pandas_like/utils.py b/narwhals/_pandas_like/utils.py index c718850c0..ba5eece46 100644 --- a/narwhals/_pandas_like/utils.py +++ b/narwhals/_pandas_like/utils.py @@ -11,8 +11,8 @@ from narwhals._arrow.utils import ( native_to_narwhals_dtype as arrow_native_to_narwhals_dtype, ) -from narwhals._exceptions import ColumnNotFoundError from narwhals.dependencies import get_polars +from narwhals.exceptions import ColumnNotFoundError from narwhals.utils import Implementation from narwhals.utils import isinstance_or_issubclass diff --git a/narwhals/_polars/dataframe.py b/narwhals/_polars/dataframe.py index 9e76dc99c..453ada3c8 100644 --- a/narwhals/_polars/dataframe.py +++ b/narwhals/_polars/dataframe.py @@ -5,12 +5,12 @@ from typing import Literal from typing import Sequence -from narwhals._exceptions import ColumnNotFoundError -from narwhals._exceptions import InvalidIntoExprError from narwhals._polars.namespace import PolarsNamespace from narwhals._polars.utils import convert_str_slice_to_int_slice from narwhals._polars.utils import extract_args_kwargs from narwhals._polars.utils import native_to_narwhals_dtype +from narwhals.exceptions import ColumnNotFoundError +from narwhals.exceptions import InvalidIntoExprError from narwhals.utils import Implementation from narwhals.utils import is_sequence_but_not_str from narwhals.utils import parse_columns_to_drop diff --git a/narwhals/_polars/series.py b/narwhals/_polars/series.py index 5f6a940c6..9013d6ab4 100644 --- a/narwhals/_polars/series.py +++ b/narwhals/_polars/series.py @@ -193,7 +193,7 @@ def __invert__(self) -> Self: return self._from_native_series(self._native_series.__invert__()) def median(self) -> Any: - from narwhals._exceptions import InvalidOperationError + from narwhals.exceptions import InvalidOperationError if not self.dtype.is_numeric(): msg = "`median` operation not supported for non-numeric input type." diff --git a/narwhals/_exceptions.py b/narwhals/exceptions.py similarity index 88% rename from narwhals/_exceptions.py rename to narwhals/exceptions.py index 529389773..6991ea75c 100644 --- a/narwhals/_exceptions.py +++ b/narwhals/exceptions.py @@ -18,6 +18,8 @@ def __str__(self) -> str: class ColumnNotFoundError(FormattedKeyError): + """Exception raised when column name isn't present.""" + def __init__(self, message: str) -> None: self.message = message super().__init__(self.message) @@ -33,10 +35,13 @@ def from_missing_and_available_column_names( return ColumnNotFoundError(message) -class InvalidOperationError(Exception): ... +class InvalidOperationError(Exception): + """Exception raised during invalid operations.""" class InvalidIntoExprError(TypeError): + """Exception raised when object can't be converted to expression.""" + def __init__(self, message: str) -> None: self.message = message super().__init__(self.message) diff --git a/narwhals/stable/v1/__init__.py b/narwhals/stable/v1/__init__.py index e53eb2f92..874337cfe 100644 --- a/narwhals/stable/v1/__init__.py +++ b/narwhals/stable/v1/__init__.py @@ -12,6 +12,7 @@ import narwhals as nw from narwhals import dependencies +from narwhals import exceptions from narwhals import selectors from narwhals.dataframe import DataFrame as NwDataFrame from narwhals.dataframe import LazyFrame as NwLazyFrame @@ -2536,70 +2537,71 @@ def from_dict( __all__ = [ - "selectors", - "concat", - "dependencies", - "to_native", - "from_native", - "to_py_scalar", - "is_ordered_categorical", - "maybe_align_index", - "maybe_convert_dtypes", - "maybe_get_index", - "maybe_reset_index", - "maybe_set_index", - "generate_temporary_column_name", - "get_native_namespace", - "get_level", + "Array", + "Boolean", + "Categorical", + "DataFrame", + "Date", + "Datetime", + "Duration", + "Enum", + "Expr", + "Field", + "Float32", + "Float64", + "Int16", + "Int32", + "Int64", + "Int8", + "LazyFrame", + "List", + "Object", + "Schema", + "Series", + "String", + "Struct", + "UInt16", + "UInt32", + "UInt64", + "UInt8", + "Unknown", "all", "all_horizontal", "any_horizontal", "col", + "concat", "concat_str", - "nth", + "dependencies", + "exceptions", + "from_arrow", + "from_dict", + "from_native", + "generate_temporary_column_name", + "get_level", + "get_native_namespace", + "is_ordered_categorical", "len", "lit", "max", "max_horizontal", + "maybe_align_index", + "maybe_convert_dtypes", + "maybe_get_index", + "maybe_reset_index", + "maybe_set_index", "mean", "mean_horizontal", "median", "min", "min_horizontal", + "narwhalify", + "new_series", + "nth", + "selectors", + "show_versions", "sum", "sum_horizontal", + "to_native", + "to_py_scalar", "when", - "DataFrame", - "LazyFrame", - "Series", - "Expr", - "Int64", - "Int32", - "Int16", - "Int8", - "UInt64", - "UInt32", - "UInt16", - "UInt8", - "Float64", - "Float32", - "Boolean", - "Object", - "Unknown", - "Categorical", - "Enum", - "String", - "Datetime", - "Duration", - "Field", - "Struct", - "Array", - "List", - "Date", - "narwhalify", - "show_versions", - "Schema", - "from_dict", - "from_arrow", - "new_series", ] diff --git a/narwhals/utils.py b/narwhals/utils.py index b3127b7d0..7cc41f78a 100644 --- a/narwhals/utils.py +++ b/narwhals/utils.py @@ -13,7 +13,6 @@ from typing import cast from warnings import warn -from narwhals._exceptions import ColumnNotFoundError from narwhals.dependencies import get_cudf from narwhals.dependencies import get_dask_dataframe from narwhals.dependencies import get_modin @@ -28,6 +27,7 @@ from narwhals.dependencies import is_pandas_series from narwhals.dependencies import is_polars_series from narwhals.dependencies import is_pyarrow_chunked_array +from narwhals.exceptions import ColumnNotFoundError from narwhals.translate import to_native if TYPE_CHECKING: diff --git a/tests/expr_and_series/median_test.py b/tests/expr_and_series/median_test.py index e46a01637..7c50988dc 100644 --- a/tests/expr_and_series/median_test.py +++ b/tests/expr_and_series/median_test.py @@ -3,7 +3,7 @@ import pytest import narwhals.stable.v1 as nw -from narwhals._exceptions import InvalidOperationError +from narwhals.exceptions import InvalidOperationError from tests.utils import Constructor from tests.utils import ConstructorEager from tests.utils import assert_equal_data diff --git a/tests/frame/drop_test.py b/tests/frame/drop_test.py index f9da91cbb..2d6115c15 100644 --- a/tests/frame/drop_test.py +++ b/tests/frame/drop_test.py @@ -8,7 +8,7 @@ from polars.exceptions import ColumnNotFoundError as PlColumnNotFoundError import narwhals.stable.v1 as nw -from narwhals._exceptions import ColumnNotFoundError +from narwhals.exceptions import ColumnNotFoundError from tests.utils import POLARS_VERSION if TYPE_CHECKING: diff --git a/tests/frame/select_test.py b/tests/frame/select_test.py index 7c9398cba..b2897d839 100644 --- a/tests/frame/select_test.py +++ b/tests/frame/select_test.py @@ -7,8 +7,8 @@ import pytest import narwhals.stable.v1 as nw -from narwhals._exceptions import ColumnNotFoundError -from narwhals._exceptions import InvalidIntoExprError +from narwhals.exceptions import ColumnNotFoundError +from narwhals.exceptions import InvalidIntoExprError from tests.utils import PANDAS_VERSION from tests.utils import POLARS_VERSION from tests.utils import Constructor