From ffa2abba05142751cc55e8323bfe91d180a18eba Mon Sep 17 00:00:00 2001 From: Marco Edward Gorelli Date: Tue, 3 Dec 2024 13:10:46 +0000 Subject: [PATCH] feat: raise informative error message for DataFrame.__eq__/__neq__ (#1494) * feat: raise informative error message for DataFrame.__eq__/__neq__ * type --- narwhals/dataframe.py | 22 ++++++++++++++++++++++ tests/frame/eq_test.py | 17 +++++++++++++++++ tests/translate/from_native_test.py | 6 +++--- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 tests/frame/eq_test.py diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index a90df93b7..5ff74b593 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -311,6 +311,28 @@ def unpivot( ) ) + def __neq__(self, other: Any) -> NoReturn: + msg = ( + "DataFrame.__neq__ and LazyFrame.__neq__ are not implemented, please " + "use expressions instead.\n\n" + "Hint: instead of\n" + " df != 0\n" + "you may want to use\n" + " df.select(nw.all() != 0)" + ) + raise NotImplementedError(msg) + + def __eq__(self, other: object) -> NoReturn: + msg = ( + "DataFrame.__eq__ and LazyFrame.__eq__ are not implemented, please " + "use expressions instead.\n\n" + "Hint: instead of\n" + " df == 0\n" + "you may want to use\n" + " df.select(nw.all() == 0)" + ) + raise NotImplementedError(msg) + class DataFrame(BaseFrame[DataFrameT]): """Narwhals DataFrame, backed by a native dataframe. diff --git a/tests/frame/eq_test.py b/tests/frame/eq_test.py new file mode 100644 index 000000000..c10046945 --- /dev/null +++ b/tests/frame/eq_test.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +import narwhals as nw + +if TYPE_CHECKING: + from tests.utils import Constructor + + +def test_eq_neq_raise(constructor: Constructor) -> None: + with pytest.raises(NotImplementedError, match="please use expressions"): + nw.from_native(constructor({"a": [1, 2, 3]})) == 0 # noqa: B015 + with pytest.raises(NotImplementedError, match="please use expressions"): + nw.from_native(constructor({"a": [1, 2, 3]})) != 0 # noqa: B015 diff --git a/tests/translate/from_native_test.py b/tests/translate/from_native_test.py index 7092ca7cd..a95674456 100644 --- a/tests/translate/from_native_test.py +++ b/tests/translate/from_native_test.py @@ -185,7 +185,7 @@ def test_pandas_like_validate() -> None: def test_init_already_narwhals() -> None: df = nw.from_native(pl.DataFrame({"a": [1, 2, 3]})) result = nw.from_native(df) - assert result is df # type: ignore[comparison-overlap] + assert result is df s = df["a"] result_s = nw.from_native(s, allow_series=True) assert result_s is s @@ -194,7 +194,7 @@ def test_init_already_narwhals() -> None: def test_init_already_narwhals_unstable() -> None: df = unstable_nw.from_native(pl.DataFrame({"a": [1, 2, 3]})) result = unstable_nw.from_native(df) - assert result is df # type: ignore[comparison-overlap] + assert result is df s = df["a"] result_s = unstable_nw.from_native(s, allow_series=True) assert result_s is s @@ -257,4 +257,4 @@ def __dataframe__(self) -> None: # pragma: no cover mockdf = MockDf() result = nw.from_native(mockdf, eager_only=True, strict=False) - assert result is mockdf # type: ignore[comparison-overlap] + assert result is mockdf