diff --git a/python/cudf/cudf/core/column/datetime.py b/python/cudf/cudf/core/column/datetime.py index 291fe275f1ae..02e26766a0d8 100644 --- a/python/cudf/cudf/core/column/datetime.py +++ b/python/cudf/cudf/core/column/datetime.py @@ -44,6 +44,7 @@ dtype_from_pylibcudf_column, dtype_to_pylibcudf_type, get_dtype_of_same_kind, + is_pandas_nullable_extension_dtype, ) from cudf.utils.scalar import pa_scalar_to_plc_scalar from cudf.utils.temporal import ( @@ -918,7 +919,11 @@ def _preserve_tz(result_dtype: np.dtype) -> DtypeObj: result_col = binaryop.binaryop(lhs_binop, rhs_binop, op, out_dtype) if out_dtype.kind != "b" and op == "__add__": return result_col - elif out_dtype.kind == "b" and op in _EQUALITY_OPS: + elif ( + out_dtype.kind == "b" + and op in _EQUALITY_OPS + and not is_pandas_nullable_extension_dtype(out_dtype) + ): return result_col.fillna(op == "__ne__") else: return result_col diff --git a/python/cudf/cudf/pandas/scripts/pandas-testing-plugin.py b/python/cudf/cudf/pandas/scripts/pandas-testing-plugin.py index dbbb83bdbeff..c79be1db8375 100644 --- a/python/cudf/cudf/pandas/scripts/pandas-testing-plugin.py +++ b/python/cudf/cudf/pandas/scripts/pandas-testing-plugin.py @@ -770,27 +770,6 @@ def pytest_unconfigure(config): "tests/extension/test_arrow.py::TestArrowArray::test_accumulate_series[bool-cummax-True]": "TODO: Add a reason for failure", "tests/extension/test_arrow.py::TestArrowArray::test_accumulate_series[bool-cummin-True]": "TODO: Add a reason for failure", "tests/extension/test_arrow.py::TestArrowArray::test_accumulate_series[bool-cumprod-True]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ms]-ge]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ms]-gt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ms]-le]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ms]-lt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ms]-ne]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-eq]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-ge]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-gt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-le]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-lt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-ne]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[s]-ge]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[s]-gt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[s]-le]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[s]-lt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[s]-ne]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[us]-ge]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[us]-gt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[us]-le]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[us]-lt]": "TODO: Add a reason for failure", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[us]-ne]": "TODO: Add a reason for failure", "tests/extension/test_arrow.py::TestArrowArray::test_concat_mixed_dtypes[decimal128(7, 3)]": "TODO: Add a reason for failure", "tests/extension/test_arrow.py::TestArrowArray::test_groupby_agg_extension[decimal128(7, 3)]": "TODO: Add a reason for failure", "tests/extension/test_arrow.py::TestArrowArray::test_reduce_frame[decimal128(7, 3)-mean-False]": "TODO: Add a reason for failure", @@ -3979,9 +3958,6 @@ def pytest_unconfigure(config): "tests/extension/test_arrow.py::TestArrowArray::test_arith_series_with_scalar[uint32-__rpow__]": "pandas xfails (reason: GH#29997: 1**pandas.NA == 1 while 1**pyarrow.NA == NULL for uint32), but xpasses with cudf.pandas", "tests/extension/test_arrow.py::TestArrowArray::test_arith_series_with_scalar[uint64-__rpow__]": "pandas xfails (reason: GH#29997: 1**pandas.NA == 1 while 1**pyarrow.NA == NULL for uint64), but xpasses with cudf.pandas", "tests/extension/test_arrow.py::TestArrowArray::test_arith_series_with_scalar[uint8-__rpow__]": "pandas xfails (reason: GH#29997: 1**pandas.NA == 1 while 1**pyarrow.NA == NULL for uint8), but xpasses with cudf.pandas", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ms]-eq]": "Flaky/order-dependent", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[s]-eq]": "Flaky/order-dependent", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[us]-eq]": "Flaky/order-dependent", "tests/extension/test_arrow.py::TestArrowArray::test_concat_mixed_dtypes[decimal128(7, 3)]": "pandas xfails, but xpasses with cudf.pandas", "tests/extension/test_arrow.py::TestArrowArray::test_getitem_series_integer_with_missing_raises[binary-integer-array]": "pandas xfails, but xpasses with cudf.pandas", "tests/extension/test_arrow.py::TestArrowArray::test_getitem_series_integer_with_missing_raises[bool-integer-array]": "pandas xfails, but xpasses with cudf.pandas", @@ -5306,7 +5282,6 @@ def pytest_unconfigure(config): "tests/strings/test_extract.py::test_extract_dataframe_capture_groups_index[uint8-string=object]": "Flaky under test sharding: cudf.pandas behavior is test-order-dependent (see #22992)", "tests/strings/test_find_replace.py::test_pyarrow_ambiguous_group_references[pyarrow_string_dtype0-(\\\\w+) (\\\\w+) (\\\\w+)-\\\\20]": "Flaky under test sharding: cudf.pandas behavior is test-order-dependent (see #22992)", "tests/strings/test_find_replace.py::test_pyarrow_backend_group_replacement[\\\\[(\\\\d+)\\\\]-(\\\\1)-expected_list1]": "Flaky under test sharding: cudf.pandas behavior is test-order-dependent (see #22992)", - "tests/extension/test_arrow.py::TestArrowArray::test_compare_array[timestamp[ns]-eq]": "Skipped: failing in pandas-tests sharded CI (PR #22992, run 28204832469)", "tests/frame/test_stack_unstack.py::TestStackUnstackMultiLevel::test_stack_names_and_numbers[False]": "Skipped: failing in pandas-tests sharded CI (PR #22992, run 28204832469)", "tests/frame/test_stack_unstack.py::TestStackUnstackMultiLevel::test_stack_names_and_numbers[True]": "Skipped: failing in pandas-tests sharded CI (PR #22992, run 28204832469)", "tests/groupby/methods/test_value_counts.py::test_against_frame_and_seriesgroupby[False-False-False-None-True-proportion-function]": "Skipped: failing in pandas-tests sharded CI (PR #22992, run 28204832469)", diff --git a/python/cudf/cudf/tests/series/test_binops.py b/python/cudf/cudf/tests/series/test_binops.py index f7c07337993f..543d1aa98ef8 100644 --- a/python/cudf/cudf/tests/series/test_binops.py +++ b/python/cudf/cudf/tests/series/test_binops.py @@ -3243,17 +3243,28 @@ def test_binops_comparisons_datatime_with_scalars(scalars, comparison_op): assert_eq(expect, got) -def test_timedelta_arrow_backed_comparisions_pandas_compat(): +@pytest.mark.parametrize("pa_type", [pa.timestamp, pa.duration]) +@pytest.mark.parametrize("unit", ["s", "ms", "us", "ns"]) +@pytest.mark.parametrize("other_kind", ["series", "scalar"]) +def test_datetimelike_arrow_backed_comparisons_pandas_compat( + pa_type, unit, other_kind, comparison_op +): + dtype = pa_type(unit) s = pd.Series( - pd.arrays.ArrowExtensionArray( - pa.array([1, None, 3], type=pa.duration("ns")) - ) + pd.arrays.ArrowExtensionArray(pa.array([1, None, 3], type=dtype)) + ) + other = pd.Series( + pd.arrays.ArrowExtensionArray(pa.array([None, 2, 3], type=dtype)) ) with cudf.option_context("mode.pandas_compatible", True): gs = cudf.from_pandas(s) - assert_eq(s == s, gs == gs) - assert_eq(s != s, gs != gs) + if other_kind == "scalar": + other = other.iloc[-1] + gother = other + else: + gother = cudf.from_pandas(other) + assert_eq(comparison_op(s, other), comparison_op(gs, gother)) def test_decimal_arrow_backed_comparisons_pandas_compat(comparison_op):