|
7 | 7 | import numpy as np
|
8 | 8 | import pytest
|
9 | 9 |
|
| 10 | +from pandas.compat import np_version_under1p19 |
| 11 | + |
10 | 12 | from pandas.core.dtypes.common import is_scalar
|
11 | 13 |
|
12 | 14 | import pandas as pd
|
@@ -810,6 +812,68 @@ def test_where_columns_casting():
|
810 | 812 | tm.assert_frame_equal(expected, result)
|
811 | 813 |
|
812 | 814 |
|
| 815 | +@pytest.mark.parametrize("as_cat", [True, False]) |
| 816 | +def test_where_period_invalid_na(frame_or_series, as_cat, request): |
| 817 | + # GH#44697 |
| 818 | + idx = pd.period_range("2016-01-01", periods=3, freq="D") |
| 819 | + if as_cat: |
| 820 | + idx = idx.astype("category") |
| 821 | + obj = frame_or_series(idx) |
| 822 | + |
| 823 | + # NA value that we should *not* cast to Period dtype |
| 824 | + tdnat = pd.NaT.to_numpy("m8[ns]") |
| 825 | + |
| 826 | + mask = np.array([True, True, False], ndmin=obj.ndim).T |
| 827 | + |
| 828 | + if as_cat: |
| 829 | + msg = ( |
| 830 | + r"Cannot setitem on a Categorical with a new category \(NaT\), " |
| 831 | + "set the categories first" |
| 832 | + ) |
| 833 | + if np_version_under1p19: |
| 834 | + mark = pytest.mark.xfail( |
| 835 | + reason="When evaluating the f-string to generate the exception " |
| 836 | + "message, numpy somehow ends up trying to cast None to int, so " |
| 837 | + "ends up raising TypeError but with an unrelated message." |
| 838 | + ) |
| 839 | + request.node.add_marker(mark) |
| 840 | + else: |
| 841 | + msg = "value should be a 'Period'" |
| 842 | + |
| 843 | + with pytest.raises(TypeError, match=msg): |
| 844 | + obj.where(mask, tdnat) |
| 845 | + |
| 846 | + with pytest.raises(TypeError, match=msg): |
| 847 | + obj.mask(mask, tdnat) |
| 848 | + |
| 849 | + |
| 850 | +def test_where_nullable_invalid_na(frame_or_series, any_numeric_ea_dtype): |
| 851 | + # GH#44697 |
| 852 | + arr = pd.array([1, 2, 3], dtype=any_numeric_ea_dtype) |
| 853 | + obj = frame_or_series(arr) |
| 854 | + |
| 855 | + mask = np.array([True, True, False], ndmin=obj.ndim).T |
| 856 | + |
| 857 | + msg = "|".join( |
| 858 | + [ |
| 859 | + r"datetime64\[.{1,2}\] cannot be converted to an? (Integer|Floating)Dtype", |
| 860 | + r"timedelta64\[.{1,2}\] cannot be converted to an? (Integer|Floating)Dtype", |
| 861 | + r"int\(\) argument must be a string, a bytes-like object or a number, " |
| 862 | + "not 'NaTType'", |
| 863 | + "object cannot be converted to a FloatingDtype", |
| 864 | + "'values' contains non-numeric NA", |
| 865 | + ] |
| 866 | + ) |
| 867 | + |
| 868 | + for null in tm.NP_NAT_OBJECTS + [pd.NaT]: |
| 869 | + # NaT is an NA value that we should *not* cast to pd.NA dtype |
| 870 | + with pytest.raises(TypeError, match=msg): |
| 871 | + obj.where(mask, null) |
| 872 | + |
| 873 | + with pytest.raises(TypeError, match=msg): |
| 874 | + obj.mask(mask, null) |
| 875 | + |
| 876 | + |
813 | 877 | @given(
|
814 | 878 | data=st.one_of(
|
815 | 879 | OPTIONAL_DICTS, OPTIONAL_FLOATS, OPTIONAL_INTS, OPTIONAL_LISTS, OPTIONAL_TEXT
|
|
0 commit comments