Repository: narwhals-dev/narwhals

Issue:
[Enh]: allow passing index object directly to `maybe_set_index`
### We would like to learn about your use case. For example, if this feature is needed  to adopt Narwhals in an open source project, could you please enter the link to it below?


_No response_

### Please describe the purpose of the new feature or describe the problem to solve.

`maybe_set_index` does not allow to pass the index directly, which could be useful for Series objects

### Suggest a solution if possible.

_No response_

### If you have tried alternatives, please describe them below.

_No response_

### Additional information that may help us understand your needs.

_No response_
[Doc]: Generating an Inventory file for Intersphinx support
### What type of report is this?

Improvement

### Please describe the issue.

Hello, thanks for making `narwhals`. It's been pretty cool to use so far and has made one of my pain points with working with [AnnData](https://anndata.readthedocs.io/en/latest/) much easier. Currently I use sphinx for documentation and I am unable to get references for objects such as `IntoExpr`.


<details>

<summary>Sample Docstring generated by Sphinx</summary>

<article class="bd-article">
    <section id="annsel-tl-annselaccessor-filter">
        <h1>annsel.tl.AnnselAccessor.filter<a class="headerlink" href="#annsel-tl-annselaccessor-filter" title="Link to this heading">#</a></h1>
        <dl class="py method">
            <dt class="sig sig-object py" id="annsel.tl.AnnselAccessor.filter">
                <span class="sig-prename descclassname"><span class="pre">tl.AnnselAccessor.</span></span><span class="sig-name descname"><span class="pre">filter</span></span><span class="sig-paren">(</span>
                <em class="sig-param">
                    <span class="n"><span class="pre">self</span></span>
                </em>
                ,
                <em class="sig-param">
                    <span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">predicates</span></span>
                </em>
                ,
                <em class="sig-param">
                    <span class="n"><span class="pre">copy</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span>
                </em>
                <span class="sig-paren">)</span>
                <a class="reference external" href="https://github.com/srivarra/annsel/tree/main/annsel/tl/basic.py#L25-L68">
                    <span class="viewcode-link"><span class="pre">[source]</span></span>
                </a>
                <a class="headerlink" href="#annsel.tl.AnnselAccessor.filter" title="Link to this definition">#</a>
            </dt>
            <dd>
                <p>Filters the AnnData object by the given predicates.</p>
                <dl class="field-list simple">
                    <dt class="field-odd">Parameters<span class="colon">:</span></dt>
                    <dd class="field-odd">
                        <dl class="simple">
                            <dt>
                                <strong>predicates</strong>
                                <span class="classifier">
                                    <span class="sphinx_autodoc_typehints-type">
                                        <a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Union" title="(in Python v3.13)">
                                            <code class="xref py py-data docutils literal notranslate"><span class="pre">Union</span></code>
                                        </a>
                                        [Expr,
                                        <a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.13)">
                                            <code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code>
                                        </a>
                                        , Series,
                                        <a class="reference external" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable" title="(in Python v3.13)">
                                            <code class="xref py py-class docutils literal notranslate"><span class="pre">Iterable</span></code>
                                        </a>
                                        [
                                        <a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Union" title="(in Python v3.13)">
                                            <code class="xref py py-data docutils literal notranslate"><span class="pre">Union</span></code>
                                        </a>
                                        [Expr,
                                        <a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.13)">
                                            <code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code>
                                        </a>
                                        , Series]]]
                                    </span>
                                </span>
                            </dt>
                            <dd><p>The predicates to filter the AnnData object by.</p></dd>
                        </dl>
                    </dd>
                    <dt class="field-even">Return type<span class="colon">:</span></dt>
                    <dd class="field-even">
                        <p>
                            <span class="sphinx_autodoc_typehints-type">
                                <a class="reference external" href="https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.html#anndata.AnnData" title="(in anndata v0.1.dev50+gf48f515)">
                                    <code class="xref py py-class docutils literal notranslate"><span class="pre">AnnData</span></code>
                                </a>
                            </span>
                        </p>
                    </dd>
                    <dt class="field-odd">Returns<span class="colon">:</span></dt>
                    <dd class="field-odd"><p>_description_</p></dd>
                </dl>
            </dd>
        </dl>
    </section>
</article>

</details>


### If you have a suggestion on how it should be, add it below.

 I looked at the documentation for `mkdocstrings` and it looks like an [objects.inv file](https://mkdocstrings.github.io/usage/#cross-references-to-other-projects-inventories) can be generated which would be great for anyone using sphinx as their documentation tool of choice. I believe `enable_inventory` just needs to be `true`. I'd like to open a PR for this as well. tyty

```yaml
plugins:
- mkdocstrings:
    enable_inventory: true

```

Discussion:

Patch:
diff --git a/README.md b/README.md
index 0f1f904f..9308af7c 100644
--- a/README.md
+++ b/README.md
@@ -121,6 +121,9 @@ to this list!
 
 Narwhals has been featured in several talks, podcasts, and blog posts:
 
+- [The Real Python Podcast](https://www.youtube.com/watch?v=w5DFZbFYzCM)
+  Narwhals: Expanding DataFrame Compatibility Between Libraries
+
 - [Talk Python to me Podcast](https://youtu.be/FSH7BZ0tuE0)
   Ahoy, Narwhals are bridging the data science APIs
 
diff --git a/mkdocs.yml b/mkdocs.yml
index 46cb5335..6d337f7e 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -91,6 +91,8 @@ plugins:
           show_signature_annotations: true
         options:
           members_order: alphabetical
+    enable_inventory: true
+
 
 hooks:
 - utils/generate_backend_completeness.py
diff --git a/narwhals/_arrow/dataframe.py b/narwhals/_arrow/dataframe.py
index ac845853..a357bdeb 100644
--- a/narwhals/_arrow/dataframe.py
+++ b/narwhals/_arrow/dataframe.py
@@ -621,7 +621,7 @@ class ArrowDataFrame:
     ) -> Self:
         """
         NOTE:
-            The param `maintain_order` is only here for compatibility with the polars API
+            The param `maintain_order` is only here for compatibility with the Polars API
             and has no effect on the output.
         """
         import numpy as np  # ignore-banned-import
diff --git a/narwhals/_arrow/expr.py b/narwhals/_arrow/expr.py
index 35e936d7..7b2af578 100644
--- a/narwhals/_arrow/expr.py
+++ b/narwhals/_arrow/expr.py
@@ -317,8 +317,8 @@ class ArrowExpr:
     def is_last_distinct(self: Self) -> Self:
         return reuse_series_implementation(self, "is_last_distinct")
 
-    def unique(self: Self) -> Self:
-        return reuse_series_implementation(self, "unique")
+    def unique(self: Self, *, maintain_order: bool = False) -> Self:
+        return reuse_series_implementation(self, "unique", maintain_order=maintain_order)
 
     def sort(self: Self, *, descending: bool = False, nulls_last: bool = False) -> Self:
         return reuse_series_implementation(
diff --git a/narwhals/_arrow/series.py b/narwhals/_arrow/series.py
index 70009df4..d63a92aa 100644
--- a/narwhals/_arrow/series.py
+++ b/narwhals/_arrow/series.py
@@ -645,7 +645,12 @@ class ArrowSeries:
         else:
             return pc.all(pc.less_equal(ser[:-1], ser[1:]))  # type: ignore[no-any-return]
 
-    def unique(self: Self) -> ArrowSeries:
+    def unique(self: Self, *, maintain_order: bool = False) -> ArrowSeries:
+        """
+        NOTE:
+            The param `maintain_order` is only here for compatibility with the Polars API
+            and has no effect on the output.
+        """
         import pyarrow.compute as pc  # ignore-banned-import()
 
         return self._from_native_series(pc.unique(self._native_series))
diff --git a/narwhals/_dask/dataframe.py b/narwhals/_dask/dataframe.py
index 150b0177..cf5c8eae 100644
--- a/narwhals/_dask/dataframe.py
+++ b/narwhals/_dask/dataframe.py
@@ -187,7 +187,7 @@ class DaskLazyFrame:
     ) -> Self:
         """
         NOTE:
-            The param `maintain_order` is only here for compatibility with the polars API
+            The param `maintain_order` is only here for compatibility with the Polars API
             and has no effect on the output.
         """
         subset = flatten(subset) if subset else None
diff --git a/narwhals/_pandas_like/dataframe.py b/narwhals/_pandas_like/dataframe.py
index 5eab8b08..df298ffc 100644
--- a/narwhals/_pandas_like/dataframe.py
+++ b/narwhals/_pandas_like/dataframe.py
@@ -296,7 +296,7 @@ class PandasLikeDataFrame:
     ) -> Iterator[list[tuple[Any, ...]]] | Iterator[list[dict[str, Any]]]:
         """
         NOTE:
-            The param ``buffer_size`` is only here for compatibility with the polars API
+            The param ``buffer_size`` is only here for compatibility with the Polars API
             and has no effect on the output.
         """
         if not named:
@@ -656,7 +656,7 @@ class PandasLikeDataFrame:
     ) -> Self:
         """
         NOTE:
-            The param `maintain_order` is only here for compatibility with the polars API
+            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)
diff --git a/narwhals/_pandas_like/expr.py b/narwhals/_pandas_like/expr.py
index a58597ee..fb9e577b 100644
--- a/narwhals/_pandas_like/expr.py
+++ b/narwhals/_pandas_like/expr.py
@@ -282,8 +282,8 @@ class PandasLikeExpr:
     def cum_sum(self) -> Self:
         return reuse_series_implementation(self, "cum_sum")
 
-    def unique(self) -> Self:
-        return reuse_series_implementation(self, "unique")
+    def unique(self, *, maintain_order: bool = False) -> Self:
+        return reuse_series_implementation(self, "unique", maintain_order=maintain_order)
 
     def diff(self) -> Self:
         return reuse_series_implementation(self, "diff")
diff --git a/narwhals/_pandas_like/series.py b/narwhals/_pandas_like/series.py
index 078e857b..7bc916b5 100644
--- a/narwhals/_pandas_like/series.py
+++ b/narwhals/_pandas_like/series.py
@@ -471,7 +471,12 @@ class PandasLikeSeries:
     def cum_sum(self) -> PandasLikeSeries:
         return self._from_native_series(self._native_series.cumsum())
 
-    def unique(self) -> PandasLikeSeries:
+    def unique(self, *, maintain_order: bool = False) -> PandasLikeSeries:
+        """
+        NOTE:
+            The param `maintain_order` is only here for compatibility with the Polars API
+            and has no effect on the output.
+        """
         return self._from_native_series(
             self._native_series.__class__(
                 self._native_series.unique(), name=self._native_series.name
diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py
index bf8bb5c9..bb163b28 100644
--- a/narwhals/dataframe.py
+++ b/narwhals/dataframe.py
@@ -1722,9 +1722,9 @@ class DataFrame(BaseFrame[DataFrameT]):
                 * 'none': Don't keep duplicate rows.
                 * 'first': Keep first unique row.
                 * 'last': Keep last unique row.
-            maintain_order: Keep the same order as the original DataFrame. This is more
+            maintain_order: Keep the same order as the original DataFrame. This may be more
                 expensive to compute. Settings this to `True` blocks the possibility
-                to run on the streaming engine for polars.
+                to run on the streaming engine for Polars.
 
         Examples:
             >>> import pandas as pd
@@ -3568,9 +3568,9 @@ class LazyFrame(BaseFrame[FrameT]):
                 * 'none': Don't keep duplicate rows.
                 * 'first': Keep first unique row.
                 * 'last': Keep last unique row.
-            maintain_order: Keep the same order as the original DataFrame. This is more
+            maintain_order: Keep the same order as the original DataFrame. This may be more
                 expensive to compute. Settings this to `True` blocks the possibility
-                to run on the streaming engine for polars.
+                to run on the streaming engine for Polars.
 
         Returns:
             LazyFrame: LazyFrame with unique rows.
diff --git a/narwhals/expr.py b/narwhals/expr.py
index 2f986760..f1d9a193 100644
--- a/narwhals/expr.py
+++ b/narwhals/expr.py
@@ -707,9 +707,14 @@ class Expr:
         """
         return self.__class__(lambda plx: self._call(plx).n_unique())
 
-    def unique(self) -> Self:
+    def unique(self, *, maintain_order: bool = False) -> Self:
         """
-        Return unique values
+        Return unique values of this expression.
+
+        Arguments:
+            maintain_order: Keep the same order as the original expression. This may be more
+                expensive to compute. Settings this to `True` blocks the possibility
+                to run on the streaming engine for Polars.
 
         Examples:
             >>> import polars as pl
@@ -724,7 +729,7 @@ class Expr:
 
             >>> @nw.narwhalify
             ... def func(df):
-            ...     return df.select(nw.col("a", "b").unique())
+            ...     return df.select(nw.col("a", "b").unique(maintain_order=True))
 
             We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`:
 
@@ -752,7 +757,9 @@ class Expr:
             a: [[1,3,5]]
             b: [[2,4,6]]
         """
-        return self.__class__(lambda plx: self._call(plx).unique())
+        return self.__class__(
+            lambda plx: self._call(plx).unique(maintain_order=maintain_order)
+        )
 
     def abs(self) -> Self:
         """
diff --git a/narwhals/functions.py b/narwhals/functions.py
index 20efa7b4..3fd2025a 100644
--- a/narwhals/functions.py
+++ b/narwhals/functions.py
@@ -173,6 +173,9 @@ def new_series(
             may auto-infer it from `values`.
         native_namespace: The native library to use for DataFrame creation.
 
+    Returns:
+        A new Series
+
     Examples:
         >>> import pandas as pd
         >>> import polars as pl
@@ -291,6 +294,9 @@ def from_dict(
         native_namespace: The native library to use for DataFrame creation. Only
             necessary if inputs are not Narwhals Series.
 
+    Returns:
+        A new DataFrame
+
     Examples:
         >>> import pandas as pd
         >>> import polars as pl
@@ -431,6 +437,9 @@ def from_arrow(
         native_frame: Object which implements `__arrow_c_stream__`.
         native_namespace: The native library to use for DataFrame creation.
 
+    Returns:
+        A new DataFrame
+
     Examples:
         >>> import pandas as pd
         >>> import polars as pl
diff --git a/narwhals/series.py b/narwhals/series.py
index dac5c6d7..424c82b4 100644
--- a/narwhals/series.py
+++ b/narwhals/series.py
@@ -1005,9 +1005,14 @@ class Series:
         """
         return self._from_compliant_series(self._compliant_series.cum_sum())
 
-    def unique(self) -> Self:
+    def unique(self, *, maintain_order: bool = False) -> Self:
         """
-        Returns unique values
+        Returns unique values of the series.
+
+        Arguments:
+            maintain_order: Keep the same order as the original series. This may be more
+                expensive to compute. Settings this to `True` blocks the possibility
+                to run on the streaming engine for Polars.
 
         Examples:
             >>> import pandas as pd
@@ -1021,7 +1026,7 @@ class Series:
 
             >>> @nw.narwhalify
             ... def func(s):
-            ...     return s.unique()
+            ...     return s.unique(maintain_order=True)
 
             We can then pass either pandas or Polars to `func`:
 
@@ -1039,7 +1044,9 @@ class Series:
                6
             ]
         """
-        return self._from_compliant_series(self._compliant_series.unique())
+        return self._from_compliant_series(
+            self._compliant_series.unique(maintain_order=maintain_order)
+        )
 
     def diff(self) -> Self:
         """
diff --git a/narwhals/stable/v1/__init__.py b/narwhals/stable/v1/__init__.py
index e11cc687..8e217f08 100644
--- a/narwhals/stable/v1/__init__.py
+++ b/narwhals/stable/v1/__init__.py
@@ -2323,6 +2323,9 @@ def new_series(
             may auto-infer it from `values`.
         native_namespace: The native library to use for DataFrame creation.
 
+    Returns:
+        A new Series
+
     Examples:
         >>> import pandas as pd
         >>> import polars as pl
@@ -2376,6 +2379,9 @@ def from_arrow(
         native_frame: Object which implements `__arrow_c_stream__`.
         native_namespace: The native library to use for DataFrame creation.
 
+    Returns:
+        A new DataFrame
+
     Examples:
         >>> import pandas as pd
         >>> import polars as pl
@@ -2431,6 +2437,9 @@ def from_dict(
         native_namespace: The native library to use for DataFrame creation. Only
             necessary if inputs are not Narwhals Series.
 
+    Returns:
+        A new DataFrame
+
     Examples:
         >>> import pandas as pd
         >>> import polars as pl


Test patch:
diff --git a/tests/expr_and_series/unique_test.py b/tests/expr_and_series/unique_test.py
index acef3f60..62d2e63a 100644
--- a/tests/expr_and_series/unique_test.py
+++ b/tests/expr_and_series/unique_test.py
@@ -8,6 +8,7 @@ from tests.utils import ConstructorEager
 from tests.utils import assert_equal_data
 
 data = {"a": [1, 1, 2]}
+data_str = {"a": ["x", "x", "y"]}
 
 
 def test_unique_expr(constructor: Constructor, request: pytest.FixtureRequest) -> None:
@@ -20,7 +21,7 @@ def test_unique_expr(constructor: Constructor, request: pytest.FixtureRequest) -
 
 
 def test_unique_series(constructor_eager: ConstructorEager) -> None:
-    series = nw.from_native(constructor_eager(data), eager_only=True)["a"]
-    result = series.unique()
-    expected = {"a": [1, 2]}
+    series = nw.from_native(constructor_eager(data_str), eager_only=True)["a"]
+    result = series.unique(maintain_order=True)
+    expected = {"a": ["x", "y"]}
     assert_equal_data({"a": result}, expected)