Repository: pandas-dev/pandas
Pull request: TST: Test inequality w/ complex dtypes (GH28050)
- [x] closes #28050
- [x] tests added / passed
- [x] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing.html#code-standards) for how to run them
- [x] whatsnew entry

Whats new::
Add a test to `pandas/test/dtypes/test_dtypes.py`


Problem statement:
NUM: inequality with complex dtypes
TL;DR: our comparisons with complex dtypes are not internally consistent:


```
arr = np.arange(5).astype(np.complex128)
ser = pd.Series(arr)
df = ser.to_frame()

>>> df < df.astype(object)
[...]
TypeError: '<' not supported between instances of 'complex' and 'complex'

>>> df.lt(df.astype(object))
       0
0  False
1  False
2  False
3  False
4  False
```

----
Digging into this...

numpy has some surprising behavior for comparing complex dtypes:

```
arr = np.arange(5)
arr = arr + arr*1j
arr2 = arr*2 - 1

>>> arr < arr2
array([False,  True,  True,  True,  True])
```

I would expect these inequalities to be undefined, and in fact, if we cast to object we get a TypeError:

```
>>> arr < arr2.astype(object)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'complex' and 'complex'
```

That's the behavior I expected in the first place, but then trying it on just the scalars:

```
>>> arr[0] < arr2[0]
False
```

Hints from issue discussion:
Looks like there's some consistency now. Could use a test if there isn't one

```
In [28]: arr = np.arange(5).astype(np.complex128)
    ...: ser = pd.Series(arr)
    ...: df = ser.to_frame()

In [29]: df < df.astype(object)
TypeError: '<' not supported between instances of 'complex' and 'complex'

In [30]: df.lt(df.astype(object))
TypeError: '<' not supported between instances of 'complex' and 'complex'
```
take

Commit message: Add test for complex dtype comparison using '<'

Patch to review:
diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py
index abb29ce66fd34..37c3584cfa154 100644
--- a/pandas/tests/dtypes/test_dtypes.py
+++ b/pandas/tests/dtypes/test_dtypes.py
@@ -1095,3 +1095,22 @@ def test_period_dtype_compare_to_string():
     dtype = PeriodDtype(freq="M")
     assert (dtype == "period[M]") is True
     assert (dtype != "period[M]") is False
+
+
+def test_compare_complex_dtypes():
+    # GH 28050
+    # https://github.com/pandas-dev/pandas/issues/28050
+    arr = np.arange(5).astype(np.complex128)
+    df = pd.DataFrame(arr)
+
+    with pytest.raises(
+        TypeError,
+        match="'<' not supported between instances of 'complex' and 'complex'",
+    ):
+        df < df.astype(object)
+
+    with pytest.raises(
+        TypeError,
+        match="'<' not supported between instances of 'complex' and 'complex'",
+    ):
+        df.lt(df.astype(object))


Code review comments:
diff_hunk: @@ -1095,3 +1095,22 @@ def test_period_dtype_compare_to_string():
     dtype = PeriodDtype(freq="M")
     assert (dtype == "period[M]") is True
     assert (dtype != "period[M]") is False
+
+
+def test_compare_complex_dtypes():
+    # GH 28050
+    # https://github.com/pandas-dev/pandas/issues/28050
+    arr = np.arange(5).astype(np.complex128)
+    df = pd.DataFrame(arr)
+
+    with pytest.raises(
+        TypeError,
+        match="'<' not supported between instances of 'complex' and 'complex'",
path: pandas/tests/dtypes/test_dtypes.py
text: @user1:
Please define match msg in a variable to avoid duplication

diff_hunk: @@ -1095,3 +1095,22 @@ def test_period_dtype_compare_to_string():
     dtype = PeriodDtype(freq="M")
     assert (dtype == "period[M]") is True
     assert (dtype != "period[M]") is False
+
+
+def test_compare_complex_dtypes():
+    # GH 28050
+    # https://github.com/pandas-dev/pandas/issues/28050
+    arr = np.arange(5).astype(np.complex128)
+    df = pd.DataFrame(arr)
path: pandas/tests/dtypes/test_dtypes.py
text: @user1:
Could define this in one go. We don not need the https link

@user1:
Please put the arange call into the DataFrame() call, otherwise lgtm 

@author:
> Please put the arange call into the DataFrame() call, otherwise lgtm

Done - thanks for the lessons!