Repository: narwhals-dev/narwhals
Pull request #1321 (2024-11-04 19:59:14)

ci: trigger slow downstream libraries tests suites before release
## What type of PR is this? (check all applicable)

- [ ] 💾 Refactor
- [ ] ✨ Feature
- [ ] 🐛 Bug Fix
- [ ] 🔧 Optimization
- [ ] 📝 Documentation
- [ ] ✅ Test
- [x] 🐳 Other

## Related issues 

- Related PR #1228 

## Checklist

- [ ] Code follows style guide (ruff)
- [ ] Tests added 
- [ ] Documented the changes

## If you have comments or can explain your changes, please do so below.

EDIT: I changed my mind 😄 I think the "slow tests" and the "publish" workflows should all run in the bump-version PR. So we can see if everything went well before merging.

The flow would be:
1. bump version
2. PR with new tag
3. Publish workflow starts along side all other workflows
4. The publish workflow triggers the "slow tests" workflow and wait for completion
5. Library published
6. merge release PR to main and celebration


~The slow tests are triggered when a tag is pushed to a branch that is _not_ `main`. Since "Bump version" creates a tag on a `bump-version` branch, this should also trigger the slow tests when the bump version PR is made. 
I also changed the "Publish Python" workflow to be triggered on tag pushes on `main`.~

~The flow would be:~
~1. bump version~
~2. PR with new tag~
~3. slow tests running along side all tests~
~4. merge PR to main~
~5. Publish workflow is triggered~
~6. Library published and celebrations~

~Currently the "publish" workflow is triggered in the "bump version" PR though. And you can see the results of the workflow before merging to `main`. Is this something that we need to keep?~


Patch:
diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml
index 88f5daae..17986a7d 100644
--- a/.github/workflows/publish_to_pypi.yml
+++ b/.github/workflows/publish_to_pypi.yml
@@ -1,11 +1,18 @@
 name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
 
-on: push
+on: 
+  push:
+    tags:
+      - "v[0-9]+.[0-9]+.[0-9]+*"
 
 
 jobs:
+  slow-downstream-tests:
+    uses: ./.github/workflows/downstream_tests_slow.yml
+
   build:
     name: Build distribution 📦
+    needs: slow-downstream-tests
     runs-on: ubuntu-latest
 
     steps:
@@ -29,9 +36,7 @@ jobs:
         path: dist/
 
   publish-to-pypi:
-    name: >-
-      Publish Python 🐍 distribution 📦 to PyPI
-    if: startsWith(github.ref, 'refs/tags/v')  # only publish to PyPI on tag pushes
+    name: Publish Python 🐍 distribution 📦 to PyPI
     needs:
     - build
     runs-on: ubuntu-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 141e9d3c..4eca8ac2 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,7 +3,7 @@ ci:
 repos:
 - repo: https://github.com/astral-sh/ruff-pre-commit
   # Ruff version.
-  rev: 'v0.7.1'
+  rev: 'v0.7.2'
   hooks:
     # Run the formatter.
     - id: ruff-format
@@ -38,7 +38,7 @@ repos:
       files: ^narwhals/
       exclude: ^narwhals/dependencies\.py
 - repo: https://github.com/kynan/nbstripout
-  rev: 0.7.1
+  rev: 0.8.0
   hooks:
     - id: nbstripout
 - repo: https://github.com/adamchainz/blacken-docs
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/docs/installation.md b/docs/installation.md
index b42198a7..b6e6c84d 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -29,7 +29,7 @@ To verify the installation, start the Python REPL and execute:
 ```python
 >>> import narwhals
 >>> narwhals.__version__
-'1.13.1'
+'1.13.2'
 ```
 If you see the version number, then the installation was successful!
 
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/__init__.py b/narwhals/__init__.py
index 2c98c943..bbb39479 100644
--- a/narwhals/__init__.py
+++ b/narwhals/__init__.py
@@ -67,7 +67,7 @@ from narwhals.utils import maybe_get_index
 from narwhals.utils import maybe_reset_index
 from narwhals.utils import maybe_set_index
 
-__version__ = "1.13.1"
+__version__ = "1.13.2"
 
 __all__ = [
     "dependencies",
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 796386fa..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:
@@ -395,15 +395,13 @@ class PandasLikeDataFrame:
         if not new_columns and len(self) == 0:
             return self
 
-        # If the inputs are all Expressions which return full columns
-        # (as opposed to scalars), we can use a fast path (concat, instead of assign).
+        # If the inputs are all Expressions
+        # (as opposed to Series), we can use a fast path (concat, instead of assign).
         # We can't use the fastpath if any input is not an expression (e.g.
         # if it's a Series) because then we might be changing its flags.
         # See `test_memmap` for an example of where this is necessary.
-        fast_path = (
-            all(len(s) > 1 for s in new_columns)
-            and all(isinstance(x, PandasLikeExpr) for x in exprs)
-            and all(isinstance(x, PandasLikeExpr) for (_, x) in named_exprs.items())
+        fast_path = all(isinstance(x, PandasLikeExpr) for x in exprs) and all(
+            isinstance(x, PandasLikeExpr) for (_, x) in named_exprs.items()
         )
 
         if fast_path:
@@ -658,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/_pandas_like/utils.py b/narwhals/_pandas_like/utils.py
index 8ab2cfad..87ed2c94 100644
--- a/narwhals/_pandas_like/utils.py
+++ b/narwhals/_pandas_like/utils.py
@@ -129,7 +129,7 @@ def validate_dataframe_comparand(index: Any, other: Any) -> Any:
         if other.len() == 1:
             # broadcast
             s = other._native_series
-            return s.__class__(s.iloc[0], index=index, dtype=s.dtype)
+            return s.__class__(s.iloc[0], index=index, dtype=s.dtype, name=s.name)
         if other._native_series.index is not index:
             return set_axis(
                 other._native_series,
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
diff --git a/pyproject.toml b/pyproject.toml
index 885e84dd..014a2876 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
 
 [project]
 name = "narwhals"
-version = "1.13.1"
+version = "1.13.2"
 authors = [
   { name="Marco Gorelli", email="33491632+MarcoGorelli@users.noreply.github.com" },
 ]


Test patch:
diff --git a/.github/workflows/downstream_tests.yml b/.github/workflows/downstream_tests.yml
index 95b4d14e..d585a7e2 100644
--- a/.github/workflows/downstream_tests.yml
+++ b/.github/workflows/downstream_tests.yml
@@ -1,4 +1,4 @@
-name: Test Downstream Libraries
+name: Test Downstream Libraries - Fast
 
 on: 
   pull_request:
@@ -230,60 +230,3 @@ jobs:
         run: |
             cd tubular
             pytest tests --config-file=pyproject.toml
-  
-  # vegafusion:
-  #    env:
-  #      UV_SYSTEM_PYTHON: true
-
-  #    strategy:
-  #      matrix:
-  #        python-version: ["3.11"]
-  #        os: [ubuntu-latest]
-
-  #    runs-on: ${{ matrix.os }}
-  #    steps:
-  #       - uses: actions/checkout@v4
-  #       - uses: actions/setup-python@v5
-  #         with:
-  #           python-version: ${{ matrix.python-version }}
-  #       - name: Install uv
-  #         uses: astral-sh/setup-uv@v3
-  #         with:
-  #           enable-cache: "true"
-  #           cache-suffix: ${{ matrix.python-version }}
-  #           cache-dependency-glob: "**requirements*.txt"
-  #       - name: clone-vegafusion
-  #         run: |
-  #             git clone --single-branch -b v2 https://github.com/vega/vegafusion.git
-  #             cd vegafusion
-  #             git log
-  #       - name: Cache rust dependencies
-  #         uses: Swatinem/rust-cache@v2
-  #         with:
-  #           workspaces: vegafusion
-  #       - name: Build wheels
-  #         uses: PyO3/maturin-action@v1
-  #         with:
-  #           command: build
-  #           manylinux: 2014
-  #           rust-toolchain: stable
-  #           args: --release -m vegafusion/vegafusion-python/Cargo.toml --features=protobuf-src --strip
-  #       - name: Install wheels
-  #         working-directory: vegafusion/target/wheels/
-  #         run: |
-  #           ls -la
-  #           python -m pip install vegafusion-*manylinux*.whl
-
-  #           # Optional dependencies
-  #           python -m pip install pyarrow pandas polars-lts-cpu "duckdb>=1.0" "vl-convert-python>=1.0.1rc1" scikit-image "pandas>=2.2" jupytext voila anywidget ipywidgets chromedriver-binary-auto
-
-  #           # Test dependencies
-  #           python -m pip install pytest altair vega-datasets scikit-image jupytext voila ipykernel anywidget ipywidgets selenium flaky tenacity chromedriver-binary-auto 
-  #       - name: Test lazy imports
-  #         working-directory: vegafusion/vegafusion-python/
-  #         run: python checks/check_lazy_imports.py
-  #       - name: Test vegafusion
-  #         working-directory: vegafusion/vegafusion-python/
-  #         env:
-  #           VEGAFUSION_TEST_HEADLESS: 1
-  #         run: pytest
diff --git a/.github/workflows/downstream_tests_slow.yml b/.github/workflows/downstream_tests_slow.yml
new file mode 100644
index 00000000..f24d963b
--- /dev/null
+++ b/.github/workflows/downstream_tests_slow.yml
@@ -0,0 +1,63 @@
+name: Test Downstream Libraries - Slow
+
+on: 
+  workflow_call:
+  workflow_dispatch:
+
+jobs:
+  vegafusion:
+     env:
+       UV_SYSTEM_PYTHON: true
+
+     strategy:
+       matrix:
+         python-version: ["3.11"]
+         os: [ubuntu-latest]
+
+     runs-on: ${{ matrix.os }}
+     steps:
+        - uses: actions/checkout@v4
+        - uses: actions/setup-python@v5
+          with:
+            python-version: ${{ matrix.python-version }}
+        - name: Install uv
+          uses: astral-sh/setup-uv@v3
+          with:
+            enable-cache: "true"
+            cache-suffix: ${{ matrix.python-version }}
+            cache-dependency-glob: "**requirements*.txt"
+        - name: clone-vegafusion
+          run: |
+              git clone --single-branch -b v2 https://github.com/vega/vegafusion.git
+              cd vegafusion
+              git log
+        - name: Cache rust dependencies
+          uses: Swatinem/rust-cache@v2
+          with:
+            workspaces: vegafusion
+        - name: Build wheels
+          uses: PyO3/maturin-action@v1
+          with:
+            command: build
+            manylinux: 2014
+            rust-toolchain: stable
+            args: --release -m vegafusion/vegafusion-python/Cargo.toml --features=protobuf-src --strip
+        - name: Install wheels
+          working-directory: vegafusion/target/wheels/
+          run: |
+            ls -la
+            python -m pip install vegafusion-*manylinux*.whl
+
+            # Optional dependencies
+            python -m pip install pyarrow pandas polars-lts-cpu "duckdb>=1.0" "vl-convert-python>=1.0.1rc1" scikit-image "pandas>=2.2" jupytext voila anywidget ipywidgets chromedriver-binary-auto
+
+            # Test dependencies
+            python -m pip install pytest altair vega-datasets scikit-image jupytext voila ipykernel anywidget ipywidgets selenium flaky tenacity chromedriver-binary-auto 
+        - name: Test lazy imports
+          working-directory: vegafusion/vegafusion-python/
+          run: python checks/check_lazy_imports.py
+        - name: Test vegafusion
+          working-directory: vegafusion/vegafusion-python/
+          env:
+            VEGAFUSION_TEST_HEADLESS: 1
+          run: pytest
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)