Repository: narwhals-dev/narwhals
Pull request #1797 (2025-01-11 16:22:13)

docs: remove docstring examples from narwhals/stable/v1
<!--
# Thanks for contributing a pull request! 
## Please make sure you see our contribution guidelines: https://github.com/narwhals-dev/narwhals/blob/main/CONTRIBUTING.md
-->

## What type of PR is this? (check all applicable)

- [ ] 💾 Refactor
- [ ] ✨ Feature
- [ ] 🐛 Bug Fix
- [ ] 🔧 Optimization
- [ ] 📝 Documentation
- [ ] ✅ Test
- [ ] 🐳 Other

## Related issues

- Related issue #\<issue number\>
- Closes #\<issue number\>

## Checklist

- [ ] Code follows style guide (ruff)
- [ ] Tests added
- [ ] Documented the changes

## If you have comments or can explain your changes, please do so below



Patch:
diff --git a/narwhals/_arrow/dataframe.py b/narwhals/_arrow/dataframe.py
index c36f5893..61688795 100644
--- a/narwhals/_arrow/dataframe.py
+++ b/narwhals/_arrow/dataframe.py
@@ -16,8 +16,8 @@ from narwhals._arrow.utils import select_rows
 from narwhals._arrow.utils import validate_dataframe_comparand
 from narwhals._expression_parsing import evaluate_into_exprs
 from narwhals.dependencies import is_numpy_array
-from narwhals.exceptions import ColumnNotFoundError
 from narwhals.utils import Implementation
+from narwhals.utils import check_column_exists
 from narwhals.utils import flatten
 from narwhals.utils import generate_temporary_column_name
 from narwhals.utils import is_sequence_but_not_str
@@ -642,9 +642,7 @@ class ArrowDataFrame(CompliantDataFrame, CompliantLazyFrame):
         import pyarrow.compute as pc
 
         df = self._native_frame
-        if subset is not None and any(x not in self.columns for x in subset):
-            msg = f"Column(s) {subset} not found in {self.columns}"
-            raise ColumnNotFoundError(msg)
+        check_column_exists(self.columns, subset)
         subset = subset or self.columns
 
         if keep in {"any", "first", "last"}:
diff --git a/narwhals/_dask/dataframe.py b/narwhals/_dask/dataframe.py
index 35a0d045..89e1bc48 100644
--- a/narwhals/_dask/dataframe.py
+++ b/narwhals/_dask/dataframe.py
@@ -11,9 +11,9 @@ from narwhals._dask.utils import add_row_index
 from narwhals._dask.utils import parse_exprs_and_named_exprs
 from narwhals._pandas_like.utils import native_to_narwhals_dtype
 from narwhals._pandas_like.utils import select_columns_by_name
-from narwhals.exceptions import ColumnNotFoundError
 from narwhals.typing import CompliantLazyFrame
 from narwhals.utils import Implementation
+from narwhals.utils import check_column_exists
 from narwhals.utils import flatten
 from narwhals.utils import generate_temporary_column_name
 from narwhals.utils import parse_columns_to_drop
@@ -198,9 +198,7 @@ class DaskLazyFrame(CompliantLazyFrame):
         *,
         keep: Literal["any", "none"] = "any",
     ) -> Self:
-        if subset is not None and any(x not in self.columns for x in subset):
-            msg = f"Column(s) {subset} not found in {self.columns}"
-            raise ColumnNotFoundError(msg)
+        check_column_exists(self.columns, subset)
         native_frame = self._native_frame
         if keep == "none":
             subset = subset or self.columns
diff --git a/narwhals/_duckdb/expr_dt.py b/narwhals/_duckdb/expr_dt.py
index b4957380..c3ed9710 100644
--- a/narwhals/_duckdb/expr_dt.py
+++ b/narwhals/_duckdb/expr_dt.py
@@ -123,3 +123,10 @@ class DuckDBExprDateTimeNamespace:
             "ordinal_day",
             returns_scalar=self._compliant_expr._returns_scalar,
         )
+
+    def date(self) -> DuckDBExpr:
+        return self._compliant_expr._from_call(
+            lambda _input: _input.cast("date"),
+            "date",
+            returns_scalar=self._compliant_expr._returns_scalar,
+        )
diff --git a/narwhals/_pandas_like/dataframe.py b/narwhals/_pandas_like/dataframe.py
index b8b70785..0cff4cb3 100644
--- a/narwhals/_pandas_like/dataframe.py
+++ b/narwhals/_pandas_like/dataframe.py
@@ -20,8 +20,8 @@ from narwhals._pandas_like.utils import rename
 from narwhals._pandas_like.utils import select_columns_by_name
 from narwhals._pandas_like.utils import validate_dataframe_comparand
 from narwhals.dependencies import is_numpy_array
-from narwhals.exceptions import ColumnNotFoundError
 from narwhals.utils import Implementation
+from narwhals.utils import check_column_exists
 from narwhals.utils import flatten
 from narwhals.utils import generate_temporary_column_name
 from narwhals.utils import import_dtypes_module
@@ -695,9 +695,7 @@ class PandasLikeDataFrame:
         # The param `maintain_order` is only here for compatibility with the Polars API
         # and has no effect on the output.
         mapped_keep = {"none": False, "any": "first"}.get(keep, keep)
-        if subset is not None and any(x not in self.columns for x in subset):
-            msg = f"Column(s) {subset} not found in {self.columns}"
-            raise ColumnNotFoundError(msg)
+        check_column_exists(self.columns, subset)
         return self._from_native_frame(
             self._native_frame.drop_duplicates(subset=subset, keep=mapped_keep)
         )
diff --git a/narwhals/_spark_like/dataframe.py b/narwhals/_spark_like/dataframe.py
index 101d5ad2..7e7f41dd 100644
--- a/narwhals/_spark_like/dataframe.py
+++ b/narwhals/_spark_like/dataframe.py
@@ -9,8 +9,8 @@ from typing import Sequence
 
 from narwhals._spark_like.utils import native_to_narwhals_dtype
 from narwhals._spark_like.utils import parse_exprs_and_named_exprs
-from narwhals.exceptions import ColumnNotFoundError
 from narwhals.utils import Implementation
+from narwhals.utils import check_column_exists
 from narwhals.utils import flatten
 from narwhals.utils import parse_columns_to_drop
 from narwhals.utils import parse_version
@@ -200,19 +200,14 @@ class SparkLikeLazyFrame:
 
     def unique(
         self: Self,
-        subset: str | list[str] | None = None,
+        subset: list[str] | None = None,
         *,
         keep: Literal["any", "none"],
     ) -> Self:
         if keep != "any":
             msg = "`LazyFrame.unique` with PySpark backend only supports `keep='any'`."
             raise ValueError(msg)
-
-        if subset is not None and any(x not in self.columns for x in subset):
-            msg = f"Column(s) {subset} not found in {self.columns}"
-            raise ColumnNotFoundError(msg)
-
-        subset = [subset] if isinstance(subset, str) else subset
+        check_column_exists(self.columns, subset)
         return self._from_native_frame(self._native_frame.dropDuplicates(subset=subset))
 
     def join(
diff --git a/narwhals/stable/v1/__init__.py b/narwhals/stable/v1/__init__.py
index e8fd5a92..171c5291 100644
--- a/narwhals/stable/v1/__init__.py
+++ b/narwhals/stable/v1/__init__.py
@@ -171,45 +171,6 @@ class DataFrame(NwDataFrame[IntoDataFrameT]):
 
         Returns:
             A new LazyFrame.
-
-        Examples:
-            Construct pandas, Polars and PyArrow DataFrames:
-
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoFrame
-            >>> data = {"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0], "ham": ["a", "b", "c"]}
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            We define a library agnostic function:
-
-            >>> def agnostic_lazy(df_native: IntoFrame) -> IntoFrame:
-            ...     df = nw.from_native(df_native)
-            ...     return df.lazy().to_native()
-
-            Note that then, pandas and pyarrow dataframe stay eager, but Polars DataFrame
-            becomes a Polars LazyFrame:
-
-            >>> agnostic_lazy(df_pd)
-               foo  bar ham
-            0    1  6.0   a
-            1    2  7.0   b
-            2    3  8.0   c
-            >>> agnostic_lazy(df_pl)
-            <LazyFrame ...>
-            >>> agnostic_lazy(df_pa)
-            pyarrow.Table
-            foo: int64
-            bar: double
-            ham: string
-            ----
-            foo: [[1,2,3]]
-            bar: [[6,7,8]]
-            ham: [["a","b","c"]]
         """
         return super().lazy()  # type: ignore[return-value]
 
@@ -232,40 +193,6 @@ class DataFrame(NwDataFrame[IntoDataFrameT]):
 
         Returns:
             A mapping from column name to values / Series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoDataFrame
-            >>> data = {
-            ...     "A": [1, 2, 3, 4, 5],
-            ...     "fruits": ["banana", "banana", "apple", "apple", "banana"],
-            ...     "B": [5, 4, 3, 2, 1],
-            ...     "animals": ["beetle", "fly", "beetle", "beetle", "beetle"],
-            ...     "optional": [28, 300, None, 2, -30],
-            ... }
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            We define a library agnostic function:
-
-            >>> def agnostic_to_dict(
-            ...     df_native: IntoDataFrame,
-            ... ) -> dict[str, list[int | str | float | None]]:
-            ...     df = nw.from_native(df_native)
-            ...     return df.to_dict(as_series=False)
-
-            We can then pass either pandas, Polars or PyArrow to `agnostic_to_dict`:
-
-            >>> agnostic_to_dict(df_pd)
-            {'A': [1, 2, 3, 4, 5], 'fruits': ['banana', 'banana', 'apple', 'apple', 'banana'], 'B': [5, 4, 3, 2, 1], 'animals': ['beetle', 'fly', 'beetle', 'beetle', 'beetle'], 'optional': [28.0, 300.0, nan, 2.0, -30.0]}
-            >>> agnostic_to_dict(df_pl)
-            {'A': [1, 2, 3, 4, 5], 'fruits': ['banana', 'banana', 'apple', 'apple', 'banana'], 'B': [5, 4, 3, 2, 1], 'animals': ['beetle', 'fly', 'beetle', 'beetle', 'beetle'], 'optional': [28, 300, None, 2, -30]}
-            >>> agnostic_to_dict(df_pa)
-            {'A': [1, 2, 3, 4, 5], 'fruits': ['banana', 'banana', 'apple', 'apple', 'banana'], 'B': [5, 4, 3, 2, 1], 'animals': ['beetle', 'fly', 'beetle', 'beetle', 'beetle'], 'optional': [28, 300, None, 2, -30]}
         """
         return super().to_dict(as_series=as_series)  # type: ignore[return-value]
 
@@ -274,57 +201,6 @@ class DataFrame(NwDataFrame[IntoDataFrameT]):
 
         Returns:
             A new Series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoDataFrame
-            >>> from narwhals.typing import IntoSeries
-            >>> data = {
-            ...     "a": [1, 2, 3, 1],
-            ...     "b": ["x", "y", "z", "x"],
-            ... }
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            Let's define a dataframe-agnostic function:
-
-            >>> def agnostic_is_duplicated(df_native: IntoDataFrame) -> IntoSeries:
-            ...     df = nw.from_native(df_native, eager_only=True)
-            ...     return df.is_duplicated().to_native()
-
-            We can then pass any supported library such as Pandas, Polars, or PyArrow
-            to `agnostic_is_duplicated`:
-
-            >>> agnostic_is_duplicated(df_pd)
-            0     True
-            1    False
-            2    False
-            3     True
-            dtype: bool
-
-            >>> agnostic_is_duplicated(df_pl)  # doctest: +NORMALIZE_WHITESPACE
-            shape: (4,)
-            Series: '' [bool]
-            [
-                true
-                false
-                false
-                true
-            ]
-            >>> agnostic_is_duplicated(df_pa)  # doctest: +ELLIPSIS
-            <pyarrow.lib.ChunkedArray object at ...>
-            [
-              [
-                true,
-                false,
-                false,
-                true
-              ]
-            ]
         """
         return super().is_duplicated()  # type: ignore[return-value]
 
@@ -333,57 +209,6 @@ class DataFrame(NwDataFrame[IntoDataFrameT]):
 
         Returns:
             A new Series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoDataFrame
-            >>> from narwhals.typing import IntoSeries
-            >>> data = {
-            ...     "a": [1, 2, 3, 1],
-            ...     "b": ["x", "y", "z", "x"],
-            ... }
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            Let's define a dataframe-agnostic function:
-
-            >>> def agnostic_is_unique(df_native: IntoDataFrame) -> IntoSeries:
-            ...     df = nw.from_native(df_native, eager_only=True)
-            ...     return df.is_unique().to_native()
-
-            We can then pass any supported library such as Pandas, Polars, or PyArrow
-            to `agnostic_is_unique`:
-
-            >>> agnostic_is_unique(df_pd)
-            0    False
-            1     True
-            2     True
-            3    False
-            dtype: bool
-
-            >>> agnostic_is_unique(df_pl)  # doctest: +NORMALIZE_WHITESPACE
-            shape: (4,)
-            Series: '' [bool]
-            [
-                false
-                 true
-                 true
-                false
-            ]
-            >>> agnostic_is_unique(df_pa)  # doctest: +ELLIPSIS
-            <pyarrow.lib.ChunkedArray object at ...>
-            [
-              [
-                false,
-                true,
-                true,
-                false
-              ]
-            ]
         """
         return super().is_unique()  # type: ignore[return-value]
 
@@ -418,59 +243,6 @@ class LazyFrame(NwLazyFrame[IntoFrameT]):
 
         Returns:
             DataFrame
-
-        Examples:
-            >>> import narwhals as nw
-            >>> import polars as pl
-            >>> import dask.dataframe as dd
-            >>> data = {
-            ...     "a": ["a", "b", "a", "b", "b", "c"],
-            ...     "b": [1, 2, 3, 4, 5, 6],
-            ...     "c": [6, 5, 4, 3, 2, 1],
-            ... }
-            >>> lf_pl = pl.LazyFrame(data)
-            >>> lf_dask = dd.from_dict(data, npartitions=2)
-
-            >>> lf = nw.from_native(lf_pl)
-            >>> lf  # doctest:+ELLIPSIS
-            ┌─────────────────────────────┐
-            |     Narwhals LazyFrame      |
-            |-----------------------------|
-            |<LazyFrame at ...
-            └─────────────────────────────┘
-            >>> df = lf.group_by("a").agg(nw.all().sum()).collect()
-            >>> df.to_native().sort("a")
-            shape: (3, 3)
-            ┌─────┬─────┬─────┐
-            │ a   ┆ b   ┆ c   │
-            │ --- ┆ --- ┆ --- │
-            │ str ┆ i64 ┆ i64 │
-            ╞═════╪═════╪═════╡
-            │ a   ┆ 4   ┆ 10  │
-            │ b   ┆ 11  ┆ 10  │
-            │ c   ┆ 6   ┆ 1   │
-            └─────┴─────┴─────┘
-
-            >>> lf = nw.from_native(lf_dask)
-            >>> lf
-            ┌───────────────────────────────────┐
-            |        Narwhals LazyFrame         |
-            |-----------------------------------|
-            |Dask DataFrame Structure:          |
-            |                    a      b      c|
-            |npartitions=2                      |
-            |0              string  int64  int64|
-            |3                 ...    ...    ...|
-            |5                 ...    ...    ...|
-            |Dask Name: frompandas, 1 expression|
-            |Expr=df                            |
-            └───────────────────────────────────┘
-            >>> df = lf.group_by("a").agg(nw.col("b", "c").sum()).collect()
-            >>> df.to_native()
-               a   b   c
-            0  a   4  10
-            1  b  11  10
-            2  c   6   1
         """
         return super().collect()  # type: ignore[return-value]
 
@@ -520,50 +292,6 @@ class Series(NwSeries[Any]):
 
         Returns:
             A DataFrame containing this Series as a single column.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoDataFrame
-            >>> from narwhals.typing import IntoSeries
-
-            >>> data = [1, 2]
-            >>> s_pd = pd.Series(data, name="a")
-            >>> s_pl = pl.Series("a", data)
-            >>> s_pa = pa.chunked_array([data])
-
-            We define a library agnostic function:
-
-            >>> def agnostic_to_frame(s_native: IntoSeries) -> IntoDataFrame:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.to_frame().to_native()
-
-            We can then pass any supported library such as pandas, Polars, or
-            PyArrow to `agnostic_to_frame`:
-
-            >>> agnostic_to_frame(s_pd)
-               a
-            0  1
-            1  2
-
-            >>> agnostic_to_frame(s_pl)
-            shape: (2, 1)
-            ┌─────┐
-            │ a   │
-            │ --- │
-            │ i64 │
-            ╞═════╡
-            │ 1   │
-            │ 2   │
-            └─────┘
-
-            >>> agnostic_to_frame(s_pa)
-            pyarrow.Table
-            : int64
-            ----
-            : [[1,2]]
         """
         return super().to_frame()  # type: ignore[return-value]
 
@@ -589,54 +317,6 @@ class Series(NwSeries[Any]):
             A DataFrame with two columns:
             - The original values as first column
             - Either count or proportion as second column, depending on normalize parameter.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoDataFrame
-            >>> from narwhals.typing import IntoSeries
-
-            >>> data = [1, 1, 2, 3, 2]
-            >>> s_pd = pd.Series(data, name="s")
-            >>> s_pl = pl.Series(values=data, name="s")
-            >>> s_pa = pa.chunked_array([data])
-
-            Let's define a dataframe-agnostic function:
-
-            >>> def agnostic_value_counts(s_native: IntoSeries) -> IntoDataFrame:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.value_counts(sort=True).to_native()
-
-            We can then pass any supported library such as pandas, Polars, or
-            PyArrow to `agnostic_value_counts`:
-
-            >>> agnostic_value_counts(s_pd)
-               s  count
-            0  1      2
-            1  2      2
-            2  3      1
-
-            >>> agnostic_value_counts(s_pl)  # doctest: +NORMALIZE_WHITESPACE
-            shape: (3, 2)
-            ┌─────┬───────┐
-            │ s   ┆ count │
-            │ --- ┆ ---   │
-            │ i64 ┆ u32   │
-            ╞═════╪═══════╡
-            │ 1   ┆ 2     │
-            │ 2   ┆ 2     │
-            │ 3   ┆ 1     │
-            └─────┴───────┘
-
-            >>> agnostic_value_counts(s_pa)
-            pyarrow.Table
-            : int64
-            count: int64
-            ----
-            : [[1,2,3]]
-            count: [[2,2,1]]
         """
         return super().value_counts(  # type: ignore[return-value]
             sort=sort, parallel=parallel, name=name, normalize=normalize
@@ -693,40 +373,6 @@ class Series(NwSeries[Any]):
 
         Returns:
             Series
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoSeriesT
-
-            >>> data = [1, 2, 3]
-            >>> s_pd = pd.Series(name="a", data=data)
-            >>> s_pl = pl.Series(name="a", values=data)
-
-            We define a library agnostic function:
-
-            >>> def agnostic_ewm_mean(s_native: IntoSeriesT) -> IntoSeriesT:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.ewm_mean(com=1, ignore_nulls=False).to_native()
-
-            We can then pass any supported library such as pandas or Polars
-            to `agnostic_ewm_mean`:
-
-            >>> agnostic_ewm_mean(s_pd)
-            0    1.000000
-            1    1.666667
-            2    2.428571
-            Name: a, dtype: float64
-
-            >>> agnostic_ewm_mean(s_pl)  # doctest: +NORMALIZE_WHITESPACE
-            shape: (3,)
-            Series: 'a' [f64]
-            [
-               1.0
-               1.666667
-               2.428571
-            ]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -776,55 +422,6 @@ class Series(NwSeries[Any]):
 
         Returns:
             A new series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoSeriesT
-
-            >>> data = [1.0, 2.0, 3.0, 4.0]
-            >>> s_pd = pd.Series(data)
-            >>> s_pl = pl.Series(data)
-            >>> s_pa = pa.chunked_array([data])
-
-            We define a library agnostic function:
-
-            >>> def agnostic_rolling_sum(s_native: IntoSeriesT) -> IntoSeriesT:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.rolling_sum(window_size=2).to_native()
-
-            We can then pass any supported library such as pandas, Polars, or
-            PyArrow to `agnostic_rolling_sum`:
-
-            >>> agnostic_rolling_sum(s_pd)
-            0    NaN
-            1    3.0
-            2    5.0
-            3    7.0
-            dtype: float64
-
-            >>> agnostic_rolling_sum(s_pl)  # doctest:+NORMALIZE_WHITESPACE
-            shape: (4,)
-            Series: '' [f64]
-            [
-               null
-               3.0
-               5.0
-               7.0
-            ]
-
-            >>> agnostic_rolling_sum(s_pa)  # doctest:+ELLIPSIS
-            <pyarrow.lib.ChunkedArray object at ...>
-            [
-              [
-                null,
-                3,
-                5,
-                7
-              ]
-            ]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -870,55 +467,6 @@ class Series(NwSeries[Any]):
 
         Returns:
             A new series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoSeriesT
-
-            >>> data = [1.0, 2.0, 3.0, 4.0]
-            >>> s_pd = pd.Series(data)
-            >>> s_pl = pl.Series(data)
-            >>> s_pa = pa.chunked_array([data])
-
-            We define a library agnostic function:
-
-            >>> def agnostic_rolling_mean(s_native: IntoSeriesT) -> IntoSeriesT:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.rolling_mean(window_size=2).to_native()
-
-            We can then pass any supported library such as pandas, Polars, or
-            PyArrow to `agnostic_rolling_mean`:
-
-            >>> agnostic_rolling_mean(s_pd)
-            0    NaN
-            1    1.5
-            2    2.5
-            3    3.5
-            dtype: float64
-
-            >>> agnostic_rolling_mean(s_pl)  # doctest:+NORMALIZE_WHITESPACE
-            shape: (4,)
-            Series: '' [f64]
-            [
-               null
-               1.5
-               2.5
-               3.5
-            ]
-
-            >>> agnostic_rolling_mean(s_pa)  # doctest:+ELLIPSIS
-            <pyarrow.lib.ChunkedArray object at ...>
-            [
-              [
-                null,
-                1.5,
-                2.5,
-                3.5
-              ]
-            ]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -966,55 +514,6 @@ class Series(NwSeries[Any]):
 
         Returns:
             A new series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoSeriesT
-
-            >>> data = [1.0, 3.0, 1.0, 4.0]
-            >>> s_pd = pd.Series(data)
-            >>> s_pl = pl.Series(data)
-            >>> s_pa = pa.chunked_array([data])
-
-            We define a library agnostic function:
-
-            >>> def agnostic_rolling_var(s_native: IntoSeriesT) -> IntoSeriesT:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.rolling_var(window_size=2, min_periods=1).to_native()
-
-            We can then pass any supported library such as pandas, Polars, or
-            PyArrow to `agnostic_rolling_var`:
-
-            >>> agnostic_rolling_var(s_pd)
-            0    NaN
-            1    2.0
-            2    2.0
-            3    4.5
-            dtype: float64
-
-            >>> agnostic_rolling_var(s_pl)  # doctest:+NORMALIZE_WHITESPACE
-            shape: (4,)
-            Series: '' [f64]
-            [
-               null
-               2.0
-               2.0
-               4.5
-            ]
-
-            >>> agnostic_rolling_var(s_pa)  # doctest:+ELLIPSIS
-            <pyarrow.lib.ChunkedArray object at ...>
-            [
-              [
-                nan,
-                2,
-                2,
-                4.5
-              ]
-            ]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1063,55 +562,6 @@ class Series(NwSeries[Any]):
 
         Returns:
             A new series.
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoSeriesT
-
-            >>> data = [1.0, 3.0, 1.0, 4.0]
-            >>> s_pd = pd.Series(data)
-            >>> s_pl = pl.Series(data)
-            >>> s_pa = pa.chunked_array([data])
-
-            We define a library agnostic function:
-
-            >>> def agnostic_rolling_std(s_native: IntoSeriesT) -> IntoSeriesT:
-            ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.rolling_std(window_size=2, min_periods=1).to_native()
-
-            We can then pass any supported library such as pandas, Polars, or
-            PyArrow to `agnostic_rolling_std`:
-
-            >>> agnostic_rolling_std(s_pd)
-            0         NaN
-            1    1.414214
-            2    1.414214
-            3    2.121320
-            dtype: float64
-
-            >>> agnostic_rolling_std(s_pl)  # doctest:+NORMALIZE_WHITESPACE
-            shape: (4,)
-            Series: '' [f64]
-            [
-               null
-               1.414214
-               1.414214
-               2.12132
-            ]
-
-            >>> agnostic_rolling_std(s_pa)  # doctest:+ELLIPSIS
-            <pyarrow.lib.ChunkedArray object at ...>
-            [
-              [
-                nan,
-                1.4142135623730951,
-                1.4142135623730951,
-                2.1213203435596424
-              ]
-            ]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1184,43 +634,6 @@ class Expr(NwExpr):
 
         Returns:
             Expr
-
-        Examples:
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoFrameT
-            >>> data = {"a": [1, 2, 3]}
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-
-            We define a library agnostic function:
-
-            >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
-            ...     df = nw.from_native(df_native)
-            ...     return df.select(
-            ...         nw.col("a").ewm_mean(com=1, ignore_nulls=False)
-            ...     ).to_native()
-
-            We can then pass either pandas or Polars to `func`:
-
-            >>> my_library_agnostic_function(df_pd)
-                      a
-            0  1.000000
-            1  1.666667
-            2  2.428571
-
-            >>> my_library_agnostic_function(df_pl)  # doctest: +NORMALIZE_WHITESPACE
-            shape: (3, 1)
-            ┌──────────┐
-            │ a        │
-            │ ---      │
-            │ f64      │
-            ╞══════════╡
-            │ 1.0      │
-            │ 1.666667 │
-            │ 2.428571 │
-            └──────────┘
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1270,54 +683,6 @@ class Expr(NwExpr):
 
         Returns:
             A new expression.
-
-        Examples:
-            >>> import narwhals as nw
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> data = {"a": [1.0, 2.0, None, 4.0]}
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            We define a library agnostic function:
-
-            >>> @nw.narwhalify
-            ... def agnostic_rolling_sum(df):
-            ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_sum(window_size=3, min_periods=1)
-            ...     )
-
-            We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`:
-
-            >>> agnostic_rolling_sum(df_pd)
-                 a    b
-            0  1.0  1.0
-            1  2.0  3.0
-            2  NaN  3.0
-            3  4.0  6.0
-
-            >>> agnostic_rolling_sum(df_pl)
-            shape: (4, 2)
-            ┌──────┬─────┐
-            │ a    ┆ b   │
-            │ ---  ┆ --- │
-            │ f64  ┆ f64 │
-            ╞══════╪═════╡
-            │ 1.0  ┆ 1.0 │
-            │ 2.0  ┆ 3.0 │
-            │ null ┆ 3.0 │
-            │ 4.0  ┆ 6.0 │
-            └──────┴─────┘
-
-            >>> agnostic_rolling_sum(df_pa)  #  doctest:+ELLIPSIS
-            pyarrow.Table
-            a: double
-            b: double
-            ----
-            a: [[1,2,null,4]]
-            b: [[1,3,3,6]]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1363,54 +728,6 @@ class Expr(NwExpr):
 
         Returns:
             A new expression.
-
-        Examples:
-            >>> import narwhals as nw
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> data = {"a": [1.0, 2.0, None, 4.0]}
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            We define a library agnostic function:
-
-            >>> @nw.narwhalify
-            ... def agnostic_rolling_mean(df):
-            ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_mean(window_size=3, min_periods=1)
-            ...     )
-
-            We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`:
-
-            >>> agnostic_rolling_mean(df_pd)
-                 a    b
-            0  1.0  1.0
-            1  2.0  1.5
-            2  NaN  1.5
-            3  4.0  3.0
-
-            >>> agnostic_rolling_mean(df_pl)
-            shape: (4, 2)
-            ┌──────┬─────┐
-            │ a    ┆ b   │
-            │ ---  ┆ --- │
-            │ f64  ┆ f64 │
-            ╞══════╪═════╡
-            │ 1.0  ┆ 1.0 │
-            │ 2.0  ┆ 1.5 │
-            │ null ┆ 1.5 │
-            │ 4.0  ┆ 3.0 │
-            └──────┴─────┘
-
-            >>> agnostic_rolling_mean(df_pa)  #  doctest:+ELLIPSIS
-            pyarrow.Table
-            a: double
-            b: double
-            ----
-            a: [[1,2,null,4]]
-            b: [[1,1.5,1.5,3]]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1458,55 +775,6 @@ class Expr(NwExpr):
 
         Returns:
             A new expression.
-
-        Examples:
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoFrameT
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> data = {"a": [1.0, 2.0, None, 4.0]}
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            We define a library agnostic function:
-
-            >>> def agnostic_rolling_var(df_native: IntoFrameT) -> IntoFrameT:
-            ...     df = nw.from_native(df_native)
-            ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_var(window_size=3, min_periods=1)
-            ...     ).to_native()
-
-            We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`:
-
-            >>> agnostic_rolling_var(df_pd)
-                 a    b
-            0  1.0  NaN
-            1  2.0  0.5
-            2  NaN  0.5
-            3  4.0  2.0
-
-            >>> agnostic_rolling_var(df_pl)  #  doctest:+SKIP
-            shape: (4, 2)
-            ┌──────┬──────┐
-            │ a    ┆ b    │
-            │ ---  ┆ ---  │
-            │ f64  ┆ f64  │
-            ╞══════╪══════╡
-            │ 1.0  ┆ null │
-            │ 2.0  ┆ 0.5  │
-            │ null ┆ 0.5  │
-            │ 4.0  ┆ 2.0  │
-            └──────┴──────┘
-
-            >>> agnostic_rolling_var(df_pa)  #  doctest:+ELLIPSIS
-            pyarrow.Table
-            a: double
-            b: double
-            ----
-            a: [[1,2,null,4]]
-            b: [[nan,0.5,0.5,2]]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1552,55 +820,6 @@ class Expr(NwExpr):
 
         Returns:
             A new expression.
-
-        Examples:
-            >>> import narwhals as nw
-            >>> from narwhals.typing import IntoFrameT
-            >>> import pandas as pd
-            >>> import polars as pl
-            >>> import pyarrow as pa
-            >>> data = {"a": [1.0, 2.0, None, 4.0]}
-            >>> df_pd = pd.DataFrame(data)
-            >>> df_pl = pl.DataFrame(data)
-            >>> df_pa = pa.table(data)
-
-            We define a library agnostic function:
-
-            >>> def agnostic_rolling_std(df_native: IntoFrameT) -> IntoFrameT:
-            ...     df = nw.from_native(df_native)
-            ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_std(window_size=3, min_periods=1)
-            ...     ).to_native()
-
-            We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`:
-
-            >>> agnostic_rolling_std(df_pd)
-                 a         b
-            0  1.0       NaN
-            1  2.0  0.707107
-            2  NaN  0.707107
-            3  4.0  1.414214
-
-            >>> agnostic_rolling_std(df_pl)  #  doctest:+SKIP
-            shape: (4, 2)
-            ┌──────┬──────────┐
-            │ a    ┆ b        │
-            │ ---  ┆ ---      │
-            │ f64  ┆ f64      │
-            ╞══════╪══════════╡
-            │ 1.0  ┆ null     │
-            │ 2.0  ┆ 0.707107 │
-            │ null ┆ 0.707107 │
-            │ 4.0  ┆ 1.414214 │
-            └──────┴──────────┘
-
-            >>> agnostic_rolling_std(df_pa)  #  doctest:+ELLIPSIS
-            pyarrow.Table
-            a: double
-            b: double
-            ----
-            a: [[1,2,null,4]]
-            b: [[nan,0.7071067811865476,0.7071067811865476,1.4142135623730951]]
         """
         from narwhals.exceptions import NarwhalsUnstableWarning
         from narwhals.utils import find_stacklevel
@@ -1625,28 +844,6 @@ class Schema(NwSchema):
         schema: Mapping[str, DType] | Iterable[tuple[str, DType]] | None
             The schema definition given by column names and their associated.
             *instantiated* Narwhals data type. Accepts a mapping or an iterable of tuples.
-
-    Examples:
-        Define a schema by passing *instantiated* data types.
-
-        >>> import narwhals as nw
-        >>> schema = nw.Schema({"foo": nw.Int8(), "bar": nw.String()})
-        >>> schema
-        Schema({'foo': Int8, 'bar': String})
-
-        Access the data type associated with a specific column name.
-
-        >>> schema["foo"]
-        Int8
-
-        Access various schema properties using the `names`, `dtypes`, and `len` methods.
-
-        >>> schema.names()
-        ['foo', 'bar']
-        >>> schema.dtypes()
-        [Int8, String]
-        >>> schema.len()
-        2
     """
 
 
@@ -2271,21 +1468,6 @@ def narwhalify(
 
     Returns:
         Decorated function.
-
-    Examples:
-        Instead of writing
-
-        >>> import narwhals as nw
-        >>> def agnostic_group_by_sum(df):
-        ...     df = nw.from_native(df, pass_through=True)
-        ...     df = df.group_by("a").agg(nw.col("b").sum())
-        ...     return nw.to_native(df)
-
-        you can just write
-
-        >>> @nw.narwhalify
-        ... def agnostic_group_by_sum(df):
-        ...     return df.group_by("a").agg(nw.col("b").sum())
     """
     pass_through = validate_strict_and_pass_though(
         strict, pass_through, pass_through_default=True, emit_deprecation_warning=False
@@ -2346,53 +1528,6 @@ def all() -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import polars as pl
-        >>> import pandas as pd
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]}
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        Let's define a dataframe-agnostic function:
-
-        >>> def agnostic_all(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.all() * 2).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_all`:
-
-        >>> agnostic_all(df_pd)
-           a   b
-        0  2   8
-        1  4  10
-        2  6  12
-
-        >>> agnostic_all(df_pl)
-        shape: (3, 2)
-        ┌─────┬─────┐
-        │ a   ┆ b   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 2   ┆ 8   │
-        │ 4   ┆ 10  │
-        │ 6   ┆ 12  │
-        └─────┴─────┘
-
-        >>> agnostic_all(df_pa)
-        pyarrow.Table
-        a: int64
-        b: int64
-        ----
-        a: [[2,4,6]]
-        b: [[8,10,12]]
     """
     return _stableify(nw.all())
 
@@ -2405,49 +1540,6 @@ def col(*names: str | Iterable[str]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2], "b": [3, 4]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_col(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.col("a") * nw.col("b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_col`:
-
-        >>> agnostic_col(df_pd)
-           a
-        0  3
-        1  8
-
-        >>> agnostic_col(df_pl)
-        shape: (2, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 3   │
-        │ 8   │
-        └─────┘
-
-        >>> agnostic_col(df_pa)
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[3,8]]
     """
     return _stableify(nw.col(*names))
 
@@ -2464,48 +1556,6 @@ def nth(*indices: int | Sequence[int]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2], "b": [3, 4]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_nth(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.nth(0) * 2).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_nth`:
-
-        >>> agnostic_nth(df_pd)
-           a
-        0  2
-        1  4
-
-        >>> agnostic_nth(df_pl)
-        shape: (2, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 2   │
-        │ 4   │
-        └─────┘
-
-        >>> agnostic_nth(df_pa)
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[2,4]]
     """
     return _stableify(nw.nth(*indices))
 
@@ -2515,45 +1565,6 @@ def len() -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import polars as pl
-        >>> import pandas as pd
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2], "b": [5, 10]}
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        Let's define a dataframe-agnostic function:
-
-        >>> def agnostic_len(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.len()).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_len`:
-
-        >>> agnostic_len(df_pd)
-           len
-        0    2
-        >>> agnostic_len(df_pl)
-        shape: (1, 1)
-        ┌─────┐
-        │ len │
-        │ --- │
-        │ u32 │
-        ╞═════╡
-        │ 2   │
-        └─────┘
-        >>> agnostic_len(df_pa)
-        pyarrow.Table
-        len: int64
-        ----
-        len: [[2]]
     """
     return _stableify(nw.len())
 
@@ -2568,51 +1579,6 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_lit(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.with_columns(nw.lit(3)).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_lit`:
-
-        >>> agnostic_lit(df_pd)
-           a  literal
-        0  1        3
-        1  2        3
-
-        >>> agnostic_lit(df_pl)
-        shape: (2, 2)
-        ┌─────┬─────────┐
-        │ a   ┆ literal │
-        │ --- ┆ ---     │
-        │ i64 ┆ i32     │
-        ╞═════╪═════════╡
-        │ 1   ┆ 3       │
-        │ 2   ┆ 3       │
-        └─────┴─────────┘
-
-        >>> agnostic_lit(df_pa)
-        pyarrow.Table
-        a: int64
-        literal: int64
-        ----
-        a: [[1,2]]
-        literal: [[3,3]]
     """
     return _stableify(nw.lit(value, dtype))
 
@@ -2628,47 +1594,6 @@ def min(*columns: str) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import polars as pl
-        >>> import pandas as pd
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2], "b": [5, 10]}
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        Let's define a dataframe-agnostic function:
-
-        >>> def agnostic_min(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.min("b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_min`:
-
-        >>> agnostic_min(df_pd)
-           b
-        0  5
-
-        >>> agnostic_min(df_pl)
-        shape: (1, 1)
-        ┌─────┐
-        │ b   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 5   │
-        └─────┘
-
-        >>> agnostic_min(df_pa)
-        pyarrow.Table
-        b: int64
-        ----
-        b: [[5]]
     """
     return _stableify(nw.min(*columns))
 
@@ -2684,47 +1609,6 @@ def max(*columns: str) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import polars as pl
-        >>> import pandas as pd
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2], "b": [5, 10]}
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        Let's define a dataframe-agnostic function:
-
-        >>> def agnostic_max(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.max("a")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_max`:
-
-        >>> agnostic_max(df_pd)
-           a
-        0  2
-
-        >>> agnostic_max(df_pl)
-        shape: (1, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 2   │
-        └─────┘
-
-        >>> agnostic_max(df_pa)
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[2]]
     """
     return _stableify(nw.max(*columns))
 
@@ -2740,47 +1624,6 @@ def mean(*columns: str) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 8, 3]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe agnostic function:
-
-        >>> def agnostic_mean(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.mean("a")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_mean`:
-
-        >>> agnostic_mean(df_pd)
-             a
-        0  4.0
-
-        >>> agnostic_mean(df_pl)
-        shape: (1, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ f64 │
-        ╞═════╡
-        │ 4.0 │
-        └─────┘
-
-        >>> agnostic_mean(df_pa)
-        pyarrow.Table
-        a: double
-        ----
-        a: [[4]]
     """
     return _stableify(nw.mean(*columns))
 
@@ -2798,47 +1641,6 @@ def median(*columns: str) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [4, 5, 2]}
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        Let's define a dataframe agnostic function:
-
-        >>> def agnostic_median(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.median("a")).to_native()
-
-        We can then pass any supported library such as pandas, Polars, or
-        PyArrow to `agnostic_median`:
-
-        >>> agnostic_median(df_pd)
-             a
-        0  4.0
-
-        >>> agnostic_median(df_pl)
-        shape: (1, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ f64 │
-        ╞═════╡
-        │ 4.0 │
-        └─────┘
-
-        >>> agnostic_median(df_pa)
-        pyarrow.Table
-        a: double
-        ----
-        a: [[4]]
     """
     return _stableify(nw.median(*columns))
 
@@ -2854,47 +1656,6 @@ def sum(*columns: str) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_sum(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.sum("a")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_sum`:
-
-        >>> agnostic_sum(df_pd)
-           a
-        0  3
-
-        >>> agnostic_sum(df_pl)
-        shape: (1, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 3   │
-        └─────┘
-
-        >>> agnostic_sum(df_pa)
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[3]]
     """
     return _stableify(nw.sum(*columns))
 
@@ -2911,50 +1672,6 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2, 3], "b": [5, 10, None]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_sum_horizontal(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.sum_horizontal("a", "b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_sum_horizontal`:
-
-        >>> agnostic_sum_horizontal(df_pd)
-              a
-        0   6.0
-        1  12.0
-        2   3.0
-
-        >>> agnostic_sum_horizontal(df_pl)
-        shape: (3, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 6   │
-        │ 12  │
-        │ 3   │
-        └─────┘
-
-        >>> agnostic_sum_horizontal(df_pa)
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[6,12,3]]
     """
     return _stableify(nw.sum_horizontal(*exprs))
 
@@ -2968,64 +1685,6 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {
-        ...     "a": [False, False, True, True, False, None],
-        ...     "b": [False, True, True, None, None, None],
-        ... }
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data).convert_dtypes(dtype_backend="pyarrow")
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_all_horizontal(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select("a", "b", all=nw.all_horizontal("a", "b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_all_horizontal`:
-
-        >>> agnostic_all_horizontal(df_pd)
-               a      b    all
-        0  False  False  False
-        1  False   True  False
-        2   True   True   True
-        3   True   <NA>   <NA>
-        4  False   <NA>  False
-        5   <NA>   <NA>   <NA>
-
-        >>> agnostic_all_horizontal(df_pl)
-        shape: (6, 3)
-        ┌───────┬───────┬───────┐
-        │ a     ┆ b     ┆ all   │
-        │ ---   ┆ ---   ┆ ---   │
-        │ bool  ┆ bool  ┆ bool  │
-        ╞═══════╪═══════╪═══════╡
-        │ false ┆ false ┆ false │
-        │ false ┆ true  ┆ false │
-        │ true  ┆ true  ┆ true  │
-        │ true  ┆ null  ┆ null  │
-        │ false ┆ null  ┆ false │
-        │ null  ┆ null  ┆ null  │
-        └───────┴───────┴───────┘
-
-        >>> agnostic_all_horizontal(df_pa)
-        pyarrow.Table
-        a: bool
-        b: bool
-        all: bool
-        ----
-        a: [[false,false,true,true,false,null]]
-        b: [[false,true,true,null,null,null]]
-        all: [[false,false,true,null,false,null]]
     """
     return _stableify(nw.all_horizontal(*exprs))
 
@@ -3039,64 +1698,6 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {
-        ...     "a": [False, False, True, True, False, None],
-        ...     "b": [False, True, True, None, None, None],
-        ... }
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data).convert_dtypes(dtype_backend="pyarrow")
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_any_horizontal(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select("a", "b", any=nw.any_horizontal("a", "b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_any_horizontal`:
-
-        >>> agnostic_any_horizontal(df_pd)
-               a      b    any
-        0  False  False  False
-        1  False   True   True
-        2   True   True   True
-        3   True   <NA>   True
-        4  False   <NA>   <NA>
-        5   <NA>   <NA>   <NA>
-
-        >>> agnostic_any_horizontal(df_pl)
-        shape: (6, 3)
-        ┌───────┬───────┬───────┐
-        │ a     ┆ b     ┆ any   │
-        │ ---   ┆ ---   ┆ ---   │
-        │ bool  ┆ bool  ┆ bool  │
-        ╞═══════╪═══════╪═══════╡
-        │ false ┆ false ┆ false │
-        │ false ┆ true  ┆ true  │
-        │ true  ┆ true  ┆ true  │
-        │ true  ┆ null  ┆ true  │
-        │ false ┆ null  ┆ null  │
-        │ null  ┆ null  ┆ null  │
-        └───────┴───────┴───────┘
-
-        >>> agnostic_any_horizontal(df_pa)
-        pyarrow.Table
-        a: bool
-        b: bool
-        any: bool
-        ----
-        a: [[false,false,true,true,false,null]]
-        b: [[false,true,true,null,null,null]]
-        any: [[false,true,true,true,null,null]]
     """
     return _stableify(nw.any_horizontal(*exprs))
 
@@ -3110,56 +1711,6 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {
-        ...     "a": [1, 8, 3],
-        ...     "b": [4, 5, None],
-        ...     "c": ["x", "y", "z"],
-        ... }
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function that computes the horizontal mean of "a"
-        and "b" columns:
-
-        >>> def agnostic_mean_horizontal(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.mean_horizontal("a", "b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_mean_horizontal`:
-
-        >>> agnostic_mean_horizontal(df_pd)
-             a
-        0  2.5
-        1  6.5
-        2  3.0
-
-        >>> agnostic_mean_horizontal(df_pl)
-        shape: (3, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ f64 │
-        ╞═════╡
-        │ 2.5 │
-        │ 6.5 │
-        │ 3.0 │
-        └─────┘
-
-        >>> agnostic_mean_horizontal(df_pa)
-        pyarrow.Table
-        a: double
-        ----
-        a: [[2.5,6.5,3]]
     """
     return _stableify(nw.mean_horizontal(*exprs))
 
@@ -3176,53 +1727,6 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {
-        ...     "a": [1, 8, 3],
-        ...     "b": [4, 5, None],
-        ...     "c": ["x", "y", "z"],
-        ... }
-
-        We define a dataframe-agnostic function that computes the horizontal min of "a"
-        and "b" columns:
-
-        >>> def agnostic_min_horizontal(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.min_horizontal("a", "b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_min_horizontal`:
-
-        >>> agnostic_min_horizontal(pd.DataFrame(data))
-             a
-        0  1.0
-        1  5.0
-        2  3.0
-
-        >>> agnostic_min_horizontal(pl.DataFrame(data))
-        shape: (3, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 1   │
-        │ 5   │
-        │ 3   │
-        └─────┘
-
-        >>> agnostic_min_horizontal(pa.table(data))
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[1,5,3]]
     """
     return _stableify(nw.min_horizontal(*exprs))
 
@@ -3239,53 +1743,6 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {
-        ...     "a": [1, 8, 3],
-        ...     "b": [4, 5, None],
-        ...     "c": ["x", "y", "z"],
-        ... }
-
-        We define a dataframe-agnostic function that computes the horizontal max of "a"
-        and "b" columns:
-
-        >>> def agnostic_max_horizontal(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(nw.max_horizontal("a", "b")).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_max_horizontal`:
-
-        >>> agnostic_max_horizontal(pd.DataFrame(data))
-             a
-        0  4.0
-        1  8.0
-        2  3.0
-
-        >>> agnostic_max_horizontal(pl.DataFrame(data))
-        shape: (3, 1)
-        ┌─────┐
-        │ a   │
-        │ --- │
-        │ i64 │
-        ╞═════╡
-        │ 4   │
-        │ 8   │
-        │ 3   │
-        └─────┘
-
-        >>> agnostic_max_horizontal(pa.table(data))
-        pyarrow.Table
-        a: int64
-        ----
-        a: [[4,8,3]]
     """
     return _stableify(nw.max_horizontal(*exprs))
 
@@ -3336,123 +1793,6 @@ def concat(
 
     Raises:
         TypeError: The items to concatenate should either all be eager, or all lazy
-
-    Examples:
-        Let's take an example of vertical concatenation:
-
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import narwhals as nw
-        >>> data_1 = {"a": [1, 2, 3], "b": [4, 5, 6]}
-        >>> data_2 = {"a": [5, 2], "b": [1, 4]}
-
-        >>> df_pd_1 = pd.DataFrame(data_1)
-        >>> df_pd_2 = pd.DataFrame(data_2)
-        >>> df_pl_1 = pl.DataFrame(data_1)
-        >>> df_pl_2 = pl.DataFrame(data_2)
-
-        Let's define a dataframe-agnostic function:
-
-        >>> @nw.narwhalify
-        ... def agnostic_vertical_concat(df1, df2):
-        ...     return nw.concat([df1, df2], how="vertical")
-
-        >>> agnostic_vertical_concat(df_pd_1, df_pd_2)
-           a  b
-        0  1  4
-        1  2  5
-        2  3  6
-        0  5  1
-        1  2  4
-        >>> agnostic_vertical_concat(df_pl_1, df_pl_2)
-        shape: (5, 2)
-        ┌─────┬─────┐
-        │ a   ┆ b   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 1   ┆ 4   │
-        │ 2   ┆ 5   │
-        │ 3   ┆ 6   │
-        │ 5   ┆ 1   │
-        │ 2   ┆ 4   │
-        └─────┴─────┘
-
-        Let's look at case a for horizontal concatenation:
-
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import narwhals as nw
-        >>> data_1 = {"a": [1, 2, 3], "b": [4, 5, 6]}
-        >>> data_2 = {"c": [5, 2], "d": [1, 4]}
-
-        >>> df_pd_1 = pd.DataFrame(data_1)
-        >>> df_pd_2 = pd.DataFrame(data_2)
-        >>> df_pl_1 = pl.DataFrame(data_1)
-        >>> df_pl_2 = pl.DataFrame(data_2)
-
-        Defining a dataframe-agnostic function:
-
-        >>> @nw.narwhalify
-        ... def agnostic_horizontal_concat(df1, df2):
-        ...     return nw.concat([df1, df2], how="horizontal")
-
-        >>> agnostic_horizontal_concat(df_pd_1, df_pd_2)
-           a  b    c    d
-        0  1  4  5.0  1.0
-        1  2  5  2.0  4.0
-        2  3  6  NaN  NaN
-
-        >>> agnostic_horizontal_concat(df_pl_1, df_pl_2)
-        shape: (3, 4)
-        ┌─────┬─────┬──────┬──────┐
-        │ a   ┆ b   ┆ c    ┆ d    │
-        │ --- ┆ --- ┆ ---  ┆ ---  │
-        │ i64 ┆ i64 ┆ i64  ┆ i64  │
-        ╞═════╪═════╪══════╪══════╡
-        │ 1   ┆ 4   ┆ 5    ┆ 1    │
-        │ 2   ┆ 5   ┆ 2    ┆ 4    │
-        │ 3   ┆ 6   ┆ null ┆ null │
-        └─────┴─────┴──────┴──────┘
-
-        Let's look at case a for diagonal concatenation:
-
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import narwhals as nw
-        >>> data_1 = {"a": [1, 2], "b": [3.5, 4.5]}
-        >>> data_2 = {"a": [3, 4], "z": ["x", "y"]}
-
-        >>> df_pd_1 = pd.DataFrame(data_1)
-        >>> df_pd_2 = pd.DataFrame(data_2)
-        >>> df_pl_1 = pl.DataFrame(data_1)
-        >>> df_pl_2 = pl.DataFrame(data_2)
-
-        Defining a dataframe-agnostic function:
-
-        >>> @nw.narwhalify
-        ... def agnostic_diagonal_concat(df1, df2):
-        ...     return nw.concat([df1, df2], how="diagonal")
-
-        >>> agnostic_diagonal_concat(df_pd_1, df_pd_2)
-           a    b    z
-        0  1  3.5  NaN
-        1  2  4.5  NaN
-        0  3  NaN    x
-        1  4  NaN    y
-
-        >>> agnostic_diagonal_concat(df_pl_1, df_pl_2)
-        shape: (4, 3)
-        ┌─────┬──────┬──────┐
-        │ a   ┆ b    ┆ z    │
-        │ --- ┆ ---  ┆ ---  │
-        │ i64 ┆ f64  ┆ str  │
-        ╞═════╪══════╪══════╡
-        │ 1   ┆ 3.5  ┆ null │
-        │ 2   ┆ 4.5  ┆ null │
-        │ 3   ┆ null ┆ x    │
-        │ 4   ┆ null ┆ y    │
-        └─────┴──────┴──────┘
     """
     return _stableify(nw.concat(items, how=how))
 
@@ -3478,62 +1818,6 @@ def concat_str(
 
     Returns:
         A new expression.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {
-        ...     "a": [1, 2, 3],
-        ...     "b": ["dogs", "cats", None],
-        ...     "c": ["play", "swim", "walk"],
-        ... }
-
-        We define a dataframe-agnostic function that computes the horizontal string
-        concatenation of different columns
-
-        >>> def agnostic_concat_str(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.select(
-        ...         nw.concat_str(
-        ...             [
-        ...                 nw.col("a") * 2,
-        ...                 nw.col("b"),
-        ...                 nw.col("c"),
-        ...             ],
-        ...             separator=" ",
-        ...         ).alias("full_sentence")
-        ...     ).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow
-        to `agnostic_concat_str`:
-
-        >>> agnostic_concat_str(pd.DataFrame(data))
-          full_sentence
-        0   2 dogs play
-        1   4 cats swim
-        2          None
-
-        >>> agnostic_concat_str(pl.DataFrame(data))
-        shape: (3, 1)
-        ┌───────────────┐
-        │ full_sentence │
-        │ ---           │
-        │ str           │
-        ╞═══════════════╡
-        │ 2 dogs play   │
-        │ 4 cats swim   │
-        │ null          │
-        └───────────────┘
-
-        >>> agnostic_concat_str(pa.table(data))
-        pyarrow.Table
-        full_sentence: string
-        ----
-        full_sentence: [["2 dogs play","4 cats swim",null]]
     """
     return _stableify(
         nw.concat_str(exprs, *more_exprs, separator=separator, ignore_nulls=ignore_nulls)
@@ -3578,57 +1862,6 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When:
 
     Returns:
         A "when" object, which `.then` can be called on.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>>
-        >>> data = {"a": [1, 2, 3], "b": [5, 10, 15]}
-        >>> df_pl = pl.DataFrame(data)
-        >>> df_pd = pd.DataFrame(data)
-        >>> df_pa = pa.table(data)
-
-        We define a dataframe-agnostic function:
-
-        >>> def agnostic_when_then_otherwise(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return df.with_columns(
-        ...         nw.when(nw.col("a") < 3).then(5).otherwise(6).alias("a_when")
-        ...     ).to_native()
-
-        We can pass any supported library such as Pandas, Polars, or PyArrow to
-        `agnostic_when_then_otherwise`:
-
-        >>> agnostic_when_then_otherwise(df_pd)
-           a   b  a_when
-        0  1   5       5
-        1  2  10       5
-        2  3  15       6
-
-        >>> agnostic_when_then_otherwise(df_pl)
-        shape: (3, 3)
-        ┌─────┬─────┬────────┐
-        │ a   ┆ b   ┆ a_when │
-        │ --- ┆ --- ┆ ---    │
-        │ i64 ┆ i64 ┆ i32    │
-        ╞═════╪═════╪════════╡
-        │ 1   ┆ 5   ┆ 5      │
-        │ 2   ┆ 10  ┆ 5      │
-        │ 3   ┆ 15  ┆ 6      │
-        └─────┴─────┴────────┘
-
-        >>> agnostic_when_then_otherwise(df_pa)
-        pyarrow.Table
-        a: int64
-        b: int64
-        a_when: int64
-        ----
-        a: [[1,2,3]]
-        b: [[5,10,15]]
-        a_when: [[5,5,6]]
     """
     return When.from_when(nw_when(*predicates))
 
@@ -3651,54 +1884,6 @@ def new_series(
 
     Returns:
         A new Series
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT, IntoSeriesT
-        >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]}
-
-        Let's define a dataframe-agnostic function:
-
-        >>> def agnostic_new_series(df_native: IntoFrameT) -> IntoSeriesT:
-        ...     values = [4, 1, 2, 3]
-        ...     native_namespace = nw.get_native_namespace(df_native)
-        ...     return nw.new_series(
-        ...         name="a",
-        ...         values=values,
-        ...         dtype=nw.Int32,
-        ...         native_namespace=native_namespace,
-        ...     ).to_native()
-
-        We can then pass any supported eager library, such as pandas / Polars / PyArrow:
-
-        >>> agnostic_new_series(pd.DataFrame(data))
-        0    4
-        1    1
-        2    2
-        3    3
-        Name: a, dtype: int32
-        >>> agnostic_new_series(pl.DataFrame(data))  # doctest: +NORMALIZE_WHITESPACE
-        shape: (4,)
-        Series: 'a' [i32]
-        [
-           4
-           1
-           2
-           3
-        ]
-        >>> agnostic_new_series(pa.table(data))
-        <pyarrow.lib.ChunkedArray object at ...>
-        [
-          [
-            4,
-            1,
-            2,
-            3
-          ]
-        ]
     """
     return _stableify(  # type: ignore[no-any-return]
         _new_series_impl(
@@ -3722,38 +1907,6 @@ def from_arrow(
 
     Returns:
         A new DataFrame.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]}
-
-        Let's define a dataframe-agnostic function which creates a PyArrow
-        Table.
-
-        >>> def agnostic_to_arrow(df_native: IntoFrameT) -> IntoFrameT:
-        ...     df = nw.from_native(df_native)
-        ...     return nw.from_arrow(df, native_namespace=pa).to_native()
-
-        Let's see what happens when passing pandas / Polars input:
-
-        >>> agnostic_to_arrow(pd.DataFrame(data))
-        pyarrow.Table
-        a: int64
-        b: int64
-        ----
-        a: [[1,2,3]]
-        b: [[4,5,6]]
-        >>> agnostic_to_arrow(pl.DataFrame(data))
-        pyarrow.Table
-        a: int64
-        b: int64
-        ----
-        a: [[1,2,3]]
-        b: [[4,5,6]]
     """
     return _stableify(  # type: ignore[no-any-return]
         nw_from_arrow(native_frame, native_namespace=native_namespace)
@@ -3783,45 +1936,6 @@ def from_dict(
 
     Returns:
         A new DataFrame.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrameT
-        >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]}
-
-        Let's create a new dataframe of the same class as the dataframe we started with, from a dict of new data:
-
-        >>> def agnostic_from_dict(df_native: IntoFrameT) -> IntoFrameT:
-        ...     new_data = {"c": [5, 2], "d": [1, 4]}
-        ...     native_namespace = nw.get_native_namespace(df_native)
-        ...     return nw.from_dict(new_data, native_namespace=native_namespace).to_native()
-
-        Let's see what happens when passing pandas, Polars or PyArrow input:
-
-        >>> agnostic_from_dict(pd.DataFrame(data))
-           c  d
-        0  5  1
-        1  2  4
-        >>> agnostic_from_dict(pl.DataFrame(data))
-        shape: (2, 2)
-        ┌─────┬─────┐
-        │ c   ┆ d   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 5   ┆ 1   │
-        │ 2   ┆ 4   │
-        └─────┴─────┘
-        >>> agnostic_from_dict(pa.table(data))
-        pyarrow.Table
-        c: int64
-        d: int64
-        ----
-        c: [[5,2]]
-        d: [[1,4]]
     """
     return _stableify(  # type: ignore[no-any-return]
         _from_dict_impl(
@@ -3854,123 +1968,6 @@ def from_numpy(
 
     Returns:
         A new DataFrame.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> import numpy as np
-        >>> from narwhals.typing import IntoFrameT
-        >>> data = {"a": [1, 2], "b": [3, 4]}
-
-        Let's create a new dataframe of the same class as the dataframe we started with, from a NumPy ndarray of new data:
-
-        >>> def agnostic_from_numpy(df_native: IntoFrameT) -> IntoFrameT:
-        ...     new_data = np.array([[5, 2, 1], [1, 4, 3]])
-        ...     df = nw.from_native(df_native)
-        ...     native_namespace = nw.get_native_namespace(df)
-        ...     return nw.from_numpy(new_data, native_namespace=native_namespace).to_native()
-
-        Let's see what happens when passing pandas, Polars or PyArrow input:
-
-        >>> agnostic_from_numpy(pd.DataFrame(data))
-           column_0  column_1  column_2
-        0         5         2         1
-        1         1         4         3
-        >>> agnostic_from_numpy(pl.DataFrame(data))
-        shape: (2, 3)
-        ┌──────────┬──────────┬──────────┐
-        │ column_0 ┆ column_1 ┆ column_2 │
-        │ ---      ┆ ---      ┆ ---      │
-        │ i64      ┆ i64      ┆ i64      │
-        ╞══════════╪══════════╪══════════╡
-        │ 5        ┆ 2        ┆ 1        │
-        │ 1        ┆ 4        ┆ 3        │
-        └──────────┴──────────┴──────────┘
-        >>> agnostic_from_numpy(pa.table(data))
-        pyarrow.Table
-        column_0: int64
-        column_1: int64
-        column_2: int64
-        ----
-        column_0: [[5,1]]
-        column_1: [[2,4]]
-        column_2: [[1,3]]
-
-        Let's specify the column names:
-
-        >>> def agnostic_from_numpy(df_native: IntoFrameT) -> IntoFrameT:
-        ...     new_data = np.array([[5, 2, 1], [1, 4, 3]])
-        ...     schema = ["c", "d", "e"]
-        ...     df = nw.from_native(df_native)
-        ...     native_namespace = nw.get_native_namespace(df)
-        ...     return nw.from_numpy(
-        ...         new_data, native_namespace=native_namespace, schema=schema
-        ...     ).to_native()
-
-        Let's see the modified outputs:
-
-        >>> agnostic_from_numpy(pd.DataFrame(data))
-           c  d  e
-        0  5  2  1
-        1  1  4  3
-        >>> agnostic_from_numpy(pl.DataFrame(data))
-        shape: (2, 3)
-        ┌─────┬─────┬─────┐
-        │ c   ┆ d   ┆ e   │
-        │ --- ┆ --- ┆ --- │
-        │ i64 ┆ i64 ┆ i64 │
-        ╞═════╪═════╪═════╡
-        │ 5   ┆ 2   ┆ 1   │
-        │ 1   ┆ 4   ┆ 3   │
-        └─────┴─────┴─────┘
-        >>> agnostic_from_numpy(pa.table(data))
-        pyarrow.Table
-        c: int64
-        d: int64
-        e: int64
-        ----
-        c: [[5,1]]
-        d: [[2,4]]
-        e: [[1,3]]
-
-        Let's modify the function so that it specifies the schema:
-
-        >>> def agnostic_from_numpy(df_native: IntoFrameT) -> IntoFrameT:
-        ...     new_data = np.array([[5, 2, 1], [1, 4, 3]])
-        ...     schema = {"c": nw.Int16(), "d": nw.Float32(), "e": nw.Int8()}
-        ...     df = nw.from_native(df_native)
-        ...     native_namespace = nw.get_native_namespace(df)
-        ...     return nw.from_numpy(
-        ...         new_data, native_namespace=native_namespace, schema=schema
-        ...     ).to_native()
-
-        Let's see the outputs:
-
-        >>> agnostic_from_numpy(pd.DataFrame(data))
-           c    d  e
-        0  5  2.0  1
-        1  1  4.0  3
-        >>> agnostic_from_numpy(pl.DataFrame(data))
-        shape: (2, 3)
-        ┌─────┬─────┬─────┐
-        │ c   ┆ d   ┆ e   │
-        │ --- ┆ --- ┆ --- │
-        │ i16 ┆ f32 ┆ i8  │
-        ╞═════╪═════╪═════╡
-        │ 5   ┆ 2.0 ┆ 1   │
-        │ 1   ┆ 4.0 ┆ 3   │
-        └─────┴─────┴─────┘
-        >>> agnostic_from_numpy(pa.table(data))
-        pyarrow.Table
-        c: int16
-        d: float
-        e: int8
-        ----
-        c: [[5,1]]
-        d: [[2,4]]
-        e: [[1,3]]
     """
     return _stableify(  # type: ignore[no-any-return]
         _from_numpy_impl(
@@ -3996,45 +1993,6 @@ def read_csv(
 
     Returns:
         DataFrame.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoDataFrame
-        >>> from types import ModuleType
-
-        Let's create an agnostic function that reads a csv file with a specified native namespace:
-
-        >>> def agnostic_read_csv(native_namespace: ModuleType) -> IntoDataFrame:
-        ...     return nw.read_csv("file.csv", native_namespace=native_namespace).to_native()
-
-        Then we can read the file by passing pandas, Polars or PyArrow namespaces:
-
-        >>> agnostic_read_csv(native_namespace=pd)  # doctest:+SKIP
-           a  b
-        0  1  4
-        1  2  5
-        2  3  6
-        >>> agnostic_read_csv(native_namespace=pl)  # doctest:+SKIP
-        shape: (3, 2)
-        ┌─────┬─────┐
-        │ a   ┆ b   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 1   ┆ 4   │
-        │ 2   ┆ 5   │
-        │ 3   ┆ 6   │
-        └─────┴─────┘
-        >>> agnostic_read_csv(native_namespace=pa)  # doctest:+SKIP
-        pyarrow.Table
-        a: int64
-        b: int64
-        ----
-        a: [[1,2,3]]
-        b: [[4,5,6]]
     """
     return _stableify(  # type: ignore[no-any-return]
         _read_csv_impl(source, native_namespace=native_namespace, **kwargs)
@@ -4058,38 +2016,6 @@ def scan_csv(
 
     Returns:
         LazyFrame.
-
-    Examples:
-        >>> import dask.dataframe as dd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrame
-        >>> from types import ModuleType
-
-        Let's create an agnostic function that lazily reads a csv file with a specified native namespace:
-
-        >>> def agnostic_scan_csv(native_namespace: ModuleType) -> IntoFrame:
-        ...     return nw.scan_csv("file.csv", native_namespace=native_namespace).to_native()
-
-        Then we can read the file by passing, for example, Polars or Dask namespaces:
-
-        >>> agnostic_scan_csv(native_namespace=pl).collect()  # doctest:+SKIP
-        shape: (3, 2)
-        ┌─────┬─────┐
-        │ a   ┆ b   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 1   ┆ 4   │
-        │ 2   ┆ 5   │
-        │ 3   ┆ 6   │
-        └─────┴─────┘
-        >>> agnostic_scan_csv(native_namespace=dd).compute()  # doctest:+SKIP
-           a  b
-        0  1  4
-        1  2  5
-        2  3  6
     """
     return _stableify(  # type: ignore[no-any-return]
         _scan_csv_impl(source, native_namespace=native_namespace, **kwargs)
@@ -4110,47 +2036,6 @@ def read_parquet(
 
     Returns:
         DataFrame.
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoDataFrame
-        >>> from types import ModuleType
-
-        Let's create an agnostic function that reads a parquet file with a specified native namespace:
-
-        >>> def agnostic_read_parquet(native_namespace: ModuleType) -> IntoDataFrame:
-        ...     return nw.read_parquet(
-        ...         "file.parquet", native_namespace=native_namespace
-        ...     ).to_native()
-
-        Then we can read the file by passing pandas, Polars or PyArrow namespaces:
-
-        >>> agnostic_read_parquet(native_namespace=pd)  # doctest:+SKIP
-           a  b
-        0  1  4
-        1  2  5
-        2  3  6
-        >>> agnostic_read_parquet(native_namespace=pl)  # doctest:+SKIP
-        shape: (3, 2)
-        ┌─────┬─────┐
-        │ a   ┆ b   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 1   ┆ 4   │
-        │ 2   ┆ 5   │
-        │ 3   ┆ 6   │
-        └─────┴─────┘
-        >>> agnostic_read_parquet(native_namespace=pa)  # doctest:+SKIP
-        pyarrow.Table
-        a: int64
-        b: int64
-        ----
-        a: [[1,2,3]]
-        b: [[4,5,6]]
     """
     return _stableify(  # type: ignore[no-any-return]
         _read_parquet_impl(source, native_namespace=native_namespace, **kwargs)
@@ -4174,40 +2059,6 @@ def scan_parquet(
 
     Returns:
         LazyFrame.
-
-    Examples:
-        >>> import dask.dataframe as dd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from narwhals.typing import IntoFrame
-        >>> from types import ModuleType
-
-        Let's create an agnostic function that lazily reads a parquet file with a specified native namespace:
-
-        >>> def agnostic_scan_parquet(native_namespace: ModuleType) -> IntoFrame:
-        ...     return nw.scan_parquet(
-        ...         "file.parquet", native_namespace=native_namespace
-        ...     ).to_native()
-
-        Then we can read the file by passing, for example, Polars or Dask namespaces:
-
-        >>> agnostic_scan_parquet(native_namespace=pl).collect()  # doctest:+SKIP
-        shape: (3, 2)
-        ┌─────┬─────┐
-        │ a   ┆ b   │
-        │ --- ┆ --- │
-        │ i64 ┆ i64 │
-        ╞═════╪═════╡
-        │ 1   ┆ 4   │
-        │ 2   ┆ 5   │
-        │ 3   ┆ 6   │
-        └─────┴─────┘
-        >>> agnostic_scan_parquet(native_namespace=dd).compute()  # doctest:+SKIP
-           a  b
-        0  1  4
-        1  2  5
-        2  3  6
     """
     return _stableify(  # type: ignore[no-any-return]
         _scan_parquet_impl(source, native_namespace=native_namespace, **kwargs)
diff --git a/narwhals/stable/v1/_dtypes.py b/narwhals/stable/v1/_dtypes.py
index 00fe0614..df5728d4 100644
--- a/narwhals/stable/v1/_dtypes.py
+++ b/narwhals/stable/v1/_dtypes.py
@@ -40,33 +40,6 @@ class Datetime(NwDatetime):
 
     Notes:
         Adapted from [Polars implementation](https://github.com/pola-rs/polars/blob/py-1.7.1/py-polars/polars/datatypes/classes.py#L398-L457)
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import pyarrow.compute as pc
-        >>> import narwhals as nw
-        >>> from datetime import datetime, timedelta
-        >>> data = [datetime(2024, 12, 9) + timedelta(days=n) for n in range(5)]
-        >>> ser_pd = (
-        ...     pd.Series(data)
-        ...     .dt.tz_localize("Africa/Accra")
-        ...     .astype("datetime64[ms, Africa/Accra]")
-        ... )
-        >>> ser_pl = (
-        ...     pl.Series(data).cast(pl.Datetime("ms")).dt.replace_time_zone("Africa/Accra")
-        ... )
-        >>> ser_pa = pc.assume_timezone(
-        ...     pa.chunked_array([data], type=pa.timestamp("ms")), "Africa/Accra"
-        ... )
-
-        >>> nw.from_native(ser_pd, series_only=True).dtype
-        Datetime(time_unit='ms', time_zone='Africa/Accra')
-        >>> nw.from_native(ser_pl, series_only=True).dtype
-        Datetime(time_unit='ms', time_zone='Africa/Accra')
-        >>> nw.from_native(ser_pa, series_only=True).dtype
-        Datetime(time_unit='ms', time_zone='Africa/Accra')
     """
 
     def __hash__(self) -> int:
@@ -81,24 +54,6 @@ class Duration(NwDuration):
 
     Notes:
         Adapted from [Polars implementation](https://github.com/pola-rs/polars/blob/py-1.7.1/py-polars/polars/datatypes/classes.py#L460-L502)
-
-    Examples:
-        >>> import pandas as pd
-        >>> import polars as pl
-        >>> import pyarrow as pa
-        >>> import narwhals as nw
-        >>> from datetime import timedelta
-        >>> data = [timedelta(seconds=d) for d in range(1, 4)]
-        >>> ser_pd = pd.Series(data).astype("timedelta64[ms]")
-        >>> ser_pl = pl.Series(data).cast(pl.Duration("ms"))
-        >>> ser_pa = pa.chunked_array([data], type=pa.duration("ms"))
-
-        >>> nw.from_native(ser_pd, series_only=True).dtype
-        Duration(time_unit='ms')
-        >>> nw.from_native(ser_pl, series_only=True).dtype
-        Duration(time_unit='ms')
-        >>> nw.from_native(ser_pa, series_only=True).dtype
-        Duration(time_unit='ms')
     """
 
     def __hash__(self) -> int:
diff --git a/narwhals/translate.py b/narwhals/translate.py
index 9ad86801..6ed82326 100644
--- a/narwhals/translate.py
+++ b/narwhals/translate.py
@@ -2,6 +2,7 @@ from __future__ import annotations
 
 from datetime import datetime
 from datetime import timedelta
+from decimal import Decimal
 from functools import wraps
 from typing import TYPE_CHECKING
 from typing import Any
@@ -59,6 +60,7 @@ NON_TEMPORAL_SCALAR_TYPES = (
     int,
     float,
     complex,
+    Decimal,
 )
 
 
diff --git a/narwhals/utils.py b/narwhals/utils.py
index 509a0e36..73f0e20a 100644
--- a/narwhals/utils.py
+++ b/narwhals/utils.py
@@ -1059,3 +1059,9 @@ def generate_repr(header: str, native_repr: str) -> str:
         "| Use `.to_native` to see native output |\n└"
         f"{'─' * 39}┘"
     )
+
+
+def check_column_exists(columns: list[str], subset: list[str] | None) -> None:
+    if subset is not None and (missing := set(subset).difference(columns)):
+        msg = f"Column(s) {sorted(missing)} not found in {columns}"
+        raise ColumnNotFoundError(msg)


Test patch:
diff --git a/tests/expr_and_series/dt/datetime_attributes_test.py b/tests/expr_and_series/dt/datetime_attributes_test.py
index 6ff2e87b..b1d09406 100644
--- a/tests/expr_and_series/dt/datetime_attributes_test.py
+++ b/tests/expr_and_series/dt/datetime_attributes_test.py
@@ -49,8 +49,6 @@ def test_datetime_attributes(
         request.applymarker(pytest.mark.xfail)
     if attribute == "date" and "cudf" in str(constructor):
         request.applymarker(pytest.mark.xfail)
-    if "duckdb" in str(constructor) and attribute in ("date"):
-        request.applymarker(pytest.mark.xfail)
     if "pyspark" in str(constructor):
         request.applymarker(pytest.mark.xfail)
 
@@ -122,7 +120,6 @@ def test_to_date(request: pytest.FixtureRequest, constructor: Constructor) -> No
             "pandas_nullable_constructor",
             "cudf",
             "modin_constructor",
-            "duckdb",
             "pyspark",
         )
     ):
diff --git a/tests/stable_api_test.py b/tests/stable_api_test.py
index 862c5966..6872dddc 100644
--- a/tests/stable_api_test.py
+++ b/tests/stable_api_test.py
@@ -13,6 +13,12 @@ from tests.utils import Constructor
 from tests.utils import assert_equal_data
 
 
+def remove_docstring_examples(doc: str) -> str:
+    if "Examples:" in doc:
+        return doc[: doc.find("Examples:")].rstrip()
+    return doc.rstrip()
+
+
 def test_renamed_taxicab_norm(
     constructor: Constructor, request: pytest.FixtureRequest
 ) -> None:
@@ -98,8 +104,8 @@ def test_stable_api_docstrings() -> None:
     for item in main_namespace_api:
         if getattr(nw, item).__doc__ is None:
             continue
-        v1_doc = getattr(nw_v1, item).__doc__
-        nw_doc = getattr(nw, item).__doc__
+        v1_doc = remove_docstring_examples(getattr(nw_v1, item).__doc__)
+        nw_doc = remove_docstring_examples(getattr(nw, item).__doc__)
         assert v1_doc == nw_doc, item
 
 
@@ -108,12 +114,11 @@ def test_dataframe_docstrings() -> None:
     df = nw.from_native(pl.DataFrame())
     api = [i for i in df.__dir__() if not i.startswith("_")]
     for item in api:
-        assert (
+        assert remove_docstring_examples(
             getattr(stable_df, item).__doc__.replace(
                 "import narwhals.stable.v1 as nw", "import narwhals as nw"
             )
-            == getattr(df, item).__doc__
-        ), item
+        ) == remove_docstring_examples(getattr(df, item).__doc__), item
 
 
 def test_lazyframe_docstrings() -> None:
@@ -124,12 +129,11 @@ def test_lazyframe_docstrings() -> None:
         if item in ("schema", "columns"):
             # to avoid performance warning
             continue
-        assert (
+        assert remove_docstring_examples(
             getattr(stable_df, item).__doc__.replace(
                 "import narwhals.stable.v1 as nw", "import narwhals as nw"
             )
-            == getattr(df, item).__doc__
-        )
+        ) == remove_docstring_examples(getattr(df, item).__doc__)
 
 
 def test_series_docstrings() -> None:
@@ -139,12 +143,11 @@ def test_series_docstrings() -> None:
     for item in api:
         if getattr(df, item).__doc__ is None:
             continue
-        assert (
+        assert remove_docstring_examples(
             getattr(stable_df, item).__doc__.replace(
                 "import narwhals.stable.v1 as nw", "import narwhals as nw"
             )
-            == getattr(df, item).__doc__
-        ), item
+        ) == remove_docstring_examples(getattr(df, item).__doc__), item
 
 
 def test_dtypes(request: pytest.FixtureRequest, constructor: Constructor) -> None:
diff --git a/tests/translate/to_py_scalar_test.py b/tests/translate/to_py_scalar_test.py
index ace5db7a..b8598350 100644
--- a/tests/translate/to_py_scalar_test.py
+++ b/tests/translate/to_py_scalar_test.py
@@ -2,6 +2,7 @@ from __future__ import annotations
 
 from datetime import datetime
 from datetime import timedelta
+from decimal import Decimal
 from typing import Any
 
 import numpy as np
@@ -20,6 +21,7 @@ from tests.utils import PANDAS_VERSION
         (1, 1),
         (pa.scalar(1), 1),
         (np.int64(1), 1),
+        (Decimal("1.1"), Decimal("1.1")),
         (1.0, 1.0),
         (None, None),
         ("a", "a"),
diff --git a/tests/utils_test.py b/tests/utils_test.py
index e999696d..9748a954 100644
--- a/tests/utils_test.py
+++ b/tests/utils_test.py
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import re
 import string
 from typing import TYPE_CHECKING
 
@@ -13,6 +14,8 @@ from pandas.testing import assert_index_equal
 from pandas.testing import assert_series_equal
 
 import narwhals.stable.v1 as nw
+from narwhals.exceptions import ColumnNotFoundError
+from narwhals.utils import check_column_exists
 from narwhals.utils import parse_version
 from tests.utils import PANDAS_VERSION
 from tests.utils import get_module_version_as_tuple
@@ -284,3 +287,13 @@ def test_generate_temporary_column_name_raise() -> None:
 )
 def test_parse_version(version: str, expected: tuple[int, ...]) -> None:
     assert parse_version(version) == expected
+
+
+def test_check_column_exists() -> None:
+    columns = ["a", "b", "c"]
+    subset = ["d", "f"]
+    with pytest.raises(
+        ColumnNotFoundError,
+        match=re.escape("Column(s) ['d', 'f'] not found in ['a', 'b', 'c']"),
+    ):
+        check_column_exists(columns, subset)