Skip to content

Commit fc266a8

Browse files
authored
TST: fix xfailed tests for IntegerArray, FloatingArray (#39350)
1 parent 64cfcf4 commit fc266a8

File tree

7 files changed

+65
-20
lines changed

7 files changed

+65
-20
lines changed

pandas/_testing/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
assert_timedelta_array_equal,
8989
raise_assert_detail,
9090
)
91+
from pandas._testing.compat import get_dtype # noqa:F401
9192
from pandas._testing.contexts import ( # noqa:F401
9293
RNGContext,
9394
decompress_file,

pandas/_testing/compat.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
Helpers for sharing tests between DataFrame/Series
3+
"""
4+
5+
from pandas import DataFrame
6+
7+
8+
def get_dtype(obj):
9+
if isinstance(obj, DataFrame):
10+
# Note: we are assuming only one column
11+
return obj.dtypes.iat[0]
12+
else:
13+
return obj.dtype

pandas/tests/extension/base/ops.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,21 @@ def check_opname(self, s, op_name, other, exc=Exception):
1818

1919
self._check_op(s, op, other, op_name, exc)
2020

21+
def _combine(self, obj, other, op):
22+
if isinstance(obj, pd.DataFrame):
23+
if len(obj.columns) != 1:
24+
raise NotImplementedError
25+
expected = obj.iloc[:, 0].combine(other, op).to_frame()
26+
else:
27+
expected = obj.combine(other, op)
28+
return expected
29+
2130
def _check_op(self, s, op, other, op_name, exc=NotImplementedError):
2231
if exc is None:
2332
result = op(s, other)
24-
if isinstance(s, pd.DataFrame):
25-
if len(s.columns) != 1:
26-
raise NotImplementedError
27-
expected = s.iloc[:, 0].combine(other, op).to_frame()
28-
self.assert_frame_equal(result, expected)
29-
else:
30-
expected = s.combine(other, op)
31-
self.assert_series_equal(result, expected)
33+
expected = self._combine(s, other, op)
34+
assert isinstance(result, type(s))
35+
self.assert_equal(result, expected)
3236
else:
3337
with pytest.raises(exc):
3438
op(s, other)
@@ -72,7 +76,6 @@ def test_arith_series_with_scalar(self, data, all_arithmetic_operators):
7276
s = pd.Series(data)
7377
self.check_opname(s, op_name, s.iloc[0], exc=self.series_scalar_exc)
7478

75-
@pytest.mark.xfail(run=False, reason="_reduce needs implementation")
7679
def test_arith_frame_with_scalar(self, data, all_arithmetic_operators):
7780
# frame & scalar
7881
op_name = all_arithmetic_operators

pandas/tests/extension/json/test_json.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ class TestArithmeticOps(BaseJSON, base.BaseArithmeticOpsTests):
322322
def test_error(self, data, all_arithmetic_operators):
323323
pass
324324

325+
def test_arith_frame_with_scalar(self, data, all_arithmetic_operators, request):
326+
if len(data[0]) != 1:
327+
mark = pytest.mark.xfail(reason="raises in coercing to Series")
328+
request.node.add_marker(mark)
329+
super().test_arith_frame_with_scalar(data, all_arithmetic_operators)
330+
325331
def test_add_series_with_extension_array(self, data):
326332
ser = pd.Series(data)
327333
with pytest.raises(TypeError, match="unsupported"):

pandas/tests/extension/test_floating.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,23 @@ def check_opname(self, s, op_name, other, exc=None):
9999

100100
def _check_op(self, s, op, other, op_name, exc=NotImplementedError):
101101
if exc is None:
102+
sdtype = tm.get_dtype(s)
102103
if (
103104
hasattr(other, "dtype")
104105
and not is_extension_array_dtype(other.dtype)
105106
and is_float_dtype(other.dtype)
106107
):
107108
# other is np.float64 and would therefore always result in
108109
# upcasting, so keeping other as same numpy_dtype
109-
other = other.astype(s.dtype.numpy_dtype)
110+
other = other.astype(sdtype.numpy_dtype)
110111

111112
result = op(s, other)
112-
expected = s.combine(other, op)
113+
expected = self._combine(s, other, op)
113114

114115
# combine method result in 'biggest' (float64) dtype
115-
expected = expected.astype(s.dtype)
116+
expected = expected.astype(sdtype)
116117

117-
self.assert_series_equal(result, expected)
118+
self.assert_equal(result, expected)
118119
else:
119120
with pytest.raises(exc):
120121
op(s, other)

pandas/tests/extension/test_integer.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ def check_opname(self, s, op_name, other, exc=None):
111111

112112
def _check_op(self, s, op, other, op_name, exc=NotImplementedError):
113113
if exc is None:
114-
if s.dtype.is_unsigned_integer and (op_name == "__rsub__"):
114+
sdtype = tm.get_dtype(s)
115+
if sdtype.is_unsigned_integer and (op_name == "__rsub__"):
115116
# TODO see https://github.com/pandas-dev/pandas/issues/22023
116117
pytest.skip("unsigned subtraction gives negative values")
117118

@@ -122,29 +123,29 @@ def _check_op(self, s, op, other, op_name, exc=NotImplementedError):
122123
):
123124
# other is np.int64 and would therefore always result in
124125
# upcasting, so keeping other as same numpy_dtype
125-
other = other.astype(s.dtype.numpy_dtype)
126+
other = other.astype(sdtype.numpy_dtype)
126127

127128
result = op(s, other)
128-
expected = s.combine(other, op)
129+
expected = self._combine(s, other, op)
129130

130131
if op_name in ("__rtruediv__", "__truediv__", "__div__"):
131132
expected = expected.fillna(np.nan).astype("Float64")
132133
elif op_name.startswith("__r"):
133134
# TODO reverse operators result in object dtype
134135
# see https://github.com/pandas-dev/pandas/issues/22024
135-
expected = expected.astype(s.dtype)
136-
result = result.astype(s.dtype)
136+
expected = expected.astype(sdtype)
137+
result = result.astype(sdtype)
137138
else:
138139
# combine method result in 'biggest' (int64) dtype
139-
expected = expected.astype(s.dtype)
140+
expected = expected.astype(sdtype)
140141
pass
141142

142143
if (op_name == "__rpow__") and isinstance(other, pd.Series):
143144
# TODO pow on Int arrays gives different result with NA
144145
# see https://github.com/pandas-dev/pandas/issues/22022
145146
result = result.fillna(1)
146147

147-
self.assert_series_equal(result, expected)
148+
self.assert_equal(result, expected)
148149
else:
149150
with pytest.raises(exc):
150151
op(s, other)

pandas/tests/extension/test_sparse.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import numpy as np
1717
import pytest
1818

19+
from pandas.compat import IS64, is_platform_windows
1920
from pandas.errors import PerformanceWarning
2021

2122
from pandas.core.dtypes.common import is_object_dtype
@@ -403,6 +404,25 @@ def test_arith_series_with_array(self, data, all_arithmetic_operators):
403404
self._skip_if_different_combine(data)
404405
super().test_arith_series_with_array(data, all_arithmetic_operators)
405406

407+
def test_arith_frame_with_scalar(self, data, all_arithmetic_operators, request):
408+
if data.dtype.fill_value != 0:
409+
pass
410+
elif all_arithmetic_operators.strip("_") not in [
411+
"mul",
412+
"rmul",
413+
"floordiv",
414+
"rfloordiv",
415+
"pow",
416+
"mod",
417+
"rmod",
418+
]:
419+
mark = pytest.mark.xfail(reason="result dtype.fill_value mismatch")
420+
request.node.add_marker(mark)
421+
elif is_platform_windows() or not IS64:
422+
mark = pytest.mark.xfail(reason="results are int32, expected int64")
423+
request.node.add_marker(mark)
424+
super().test_arith_frame_with_scalar(data, all_arithmetic_operators)
425+
406426

407427
class TestComparisonOps(BaseSparseTests, base.BaseComparisonOpsTests):
408428
def _compare_other(self, s, data, op_name, other):

0 commit comments

Comments
 (0)