|
""" |
|
Assertion helpers for arithmetic tests. |
|
""" |
|
import numpy as np |
|
import pytest |
|
|
|
from pandas import ( |
|
DataFrame, |
|
Index, |
|
Series, |
|
array, |
|
) |
|
import pandas._testing as tm |
|
from pandas.core.arrays import ( |
|
BooleanArray, |
|
NumpyExtensionArray, |
|
) |
|
|
|
|
|
def assert_cannot_add(left, right, msg="cannot add"): |
|
""" |
|
Helper to assert that left and right cannot be added. |
|
|
|
Parameters |
|
---------- |
|
left : object |
|
right : object |
|
msg : str, default "cannot add" |
|
""" |
|
with pytest.raises(TypeError, match=msg): |
|
left + right |
|
with pytest.raises(TypeError, match=msg): |
|
right + left |
|
|
|
|
|
def assert_invalid_addsub_type(left, right, msg=None): |
|
""" |
|
Helper to assert that left and right can be neither added nor subtracted. |
|
|
|
Parameters |
|
---------- |
|
left : object |
|
right : object |
|
msg : str or None, default None |
|
""" |
|
with pytest.raises(TypeError, match=msg): |
|
left + right |
|
with pytest.raises(TypeError, match=msg): |
|
right + left |
|
with pytest.raises(TypeError, match=msg): |
|
left - right |
|
with pytest.raises(TypeError, match=msg): |
|
right - left |
|
|
|
|
|
def get_upcast_box(left, right, is_cmp: bool = False): |
|
""" |
|
Get the box to use for 'expected' in an arithmetic or comparison operation. |
|
|
|
Parameters |
|
left : Any |
|
right : Any |
|
is_cmp : bool, default False |
|
Whether the operation is a comparison method. |
|
""" |
|
|
|
if isinstance(left, DataFrame) or isinstance(right, DataFrame): |
|
return DataFrame |
|
if isinstance(left, Series) or isinstance(right, Series): |
|
if is_cmp and isinstance(left, Index): |
|
|
|
return np.array |
|
return Series |
|
if isinstance(left, Index) or isinstance(right, Index): |
|
if is_cmp: |
|
return np.array |
|
return Index |
|
return tm.to_array |
|
|
|
|
|
def assert_invalid_comparison(left, right, box): |
|
""" |
|
Assert that comparison operations with mismatched types behave correctly. |
|
|
|
Parameters |
|
---------- |
|
left : np.ndarray, ExtensionArray, Index, or Series |
|
right : object |
|
box : {pd.DataFrame, pd.Series, pd.Index, pd.array, tm.to_array} |
|
""" |
|
|
|
|
|
|
|
xbox = box if box not in [Index, array] else np.array |
|
|
|
def xbox2(x): |
|
|
|
|
|
if isinstance(x, NumpyExtensionArray): |
|
return x._ndarray |
|
if isinstance(x, BooleanArray): |
|
|
|
return x.astype(bool) |
|
return x |
|
|
|
|
|
rev_box = xbox |
|
if isinstance(right, Index) and isinstance(left, Series): |
|
rev_box = np.array |
|
|
|
result = xbox2(left == right) |
|
expected = xbox(np.zeros(result.shape, dtype=np.bool_)) |
|
|
|
tm.assert_equal(result, expected) |
|
|
|
result = xbox2(right == left) |
|
tm.assert_equal(result, rev_box(expected)) |
|
|
|
result = xbox2(left != right) |
|
tm.assert_equal(result, ~expected) |
|
|
|
result = xbox2(right != left) |
|
tm.assert_equal(result, rev_box(~expected)) |
|
|
|
msg = "|".join( |
|
[ |
|
"Invalid comparison between", |
|
"Cannot compare type", |
|
"not supported between", |
|
"invalid type promotion", |
|
( |
|
|
|
r"The DTypes <class 'numpy.dtype\[datetime64\]'> and " |
|
r"<class 'numpy.dtype\[int64\]'> do not have a common DType. " |
|
"For example they cannot be stored in a single array unless the " |
|
"dtype is `object`." |
|
), |
|
] |
|
) |
|
with pytest.raises(TypeError, match=msg): |
|
left < right |
|
with pytest.raises(TypeError, match=msg): |
|
left <= right |
|
with pytest.raises(TypeError, match=msg): |
|
left > right |
|
with pytest.raises(TypeError, match=msg): |
|
left >= right |
|
with pytest.raises(TypeError, match=msg): |
|
right < left |
|
with pytest.raises(TypeError, match=msg): |
|
right <= left |
|
with pytest.raises(TypeError, match=msg): |
|
right > left |
|
with pytest.raises(TypeError, match=msg): |
|
right >= left |
|
|