From 544420580b98bee5b1cf139e16c4b23aec3e6d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Feb 2026 15:57:54 +0100 Subject: [PATCH 1/2] Remove upper restriction to pandas --- noxfile.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index e365978..04eb18a 100644 --- a/noxfile.py +++ b/noxfile.py @@ -223,7 +223,7 @@ def prerelease(session, tests_path): "--prefer-binary", "--pre", "--upgrade", - "pandas<3.0.0rc0", + "pandas", ) session.install( "mock", diff --git a/setup.py b/setup.py index 186f31a..5a60861 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ "numpy >= 1.24.0, <= 2.2.6 ; python_version == '3.10'", "numpy >= 1.24.0 ; python_version != '3.10'", "packaging >= 24.2.0", - "pandas >= 1.5.3, < 3.0.0", + "pandas >= 1.5.3", "pyarrow >= 13.0.0", ] From 612738e23712c475c7732ab765b32f8ee0d5cc23 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Thu, 26 Feb 2026 07:38:30 -0500 Subject: [PATCH 2/2] updates compliance tests to help account for changes to pandas 3.0+ --- tests/compliance/conftest.py | 5 ++ tests/compliance/date/conftest.py | 4 +- tests/compliance/date/test_date_compliance.py | 21 +++++++-- tests/compliance/json/conftest.py | 4 +- tests/compliance/json/test_json_compliance.py | 47 ++++++++++++++++--- tests/compliance/time/conftest.py | 5 +- tests/compliance/time/test_time_compliance.py | 21 +++++++-- 7 files changed, 89 insertions(+), 18 deletions(-) diff --git a/tests/compliance/conftest.py b/tests/compliance/conftest.py index b891ed6..ef5b760 100644 --- a/tests/compliance/conftest.py +++ b/tests/compliance/conftest.py @@ -173,3 +173,8 @@ def use_numpy(request): https://github.com/pandas-dev/pandas/blob/main/pandas/tests/extension/conftest.py """ return request.param + +@pytest.fixture +def using_nan_is_na(na_value): + import numpy as np + return na_value is np.nan diff --git a/tests/compliance/date/conftest.py b/tests/compliance/date/conftest.py index 6f0a816..5229bdf 100644 --- a/tests/compliance/date/conftest.py +++ b/tests/compliance/date/conftest.py @@ -34,8 +34,8 @@ def data(): return DateArray( numpy.arange( datetime.datetime(1900, 1, 1), - datetime.datetime(2099, 12, 31), - datetime.timedelta(days=731), + datetime.datetime(1900, 1, 11), + datetime.timedelta(days=1), dtype="datetime64[ns]", ) ) diff --git a/tests/compliance/date/test_date_compliance.py b/tests/compliance/date/test_date_compliance.py index ae1ef83..8d3d8b8 100644 --- a/tests/compliance/date/test_date_compliance.py +++ b/tests/compliance/date/test_date_compliance.py @@ -63,7 +63,11 @@ def test_take_pandas_style_negative_raises(self, data, na_value): class TestGroupby(base.BaseGroupbyTests): - pass + @pytest.mark.xfail( + reason="GH#38980 groupby agg on extension type fails for non-numeric types" + ) + def test_groupby_agg_extension(self, data_for_grouping): + super().test_groupby_agg_extension(data_for_grouping) class TestIndex(base.BaseIndexTests): @@ -138,10 +142,10 @@ def test_argmax_argmin_no_skipna_notimplemented(self, data_missing_for_sorting): # at least pandas version 3.0 (current version is 2.3) data = data_missing_for_sorting - with pytest.raises(NotImplementedError): + with pytest.raises((NotImplementedError, ValueError)): data.argmin(skipna=False) - with pytest.raises(NotImplementedError): + with pytest.raises((NotImplementedError, ValueError)): data.argmax(skipna=False) @@ -171,6 +175,17 @@ def test_setitem_invalid(self, data, invalid_scalar): with pytest.raises((ValueError, TypeError)): data[:] = invalid_scalar + def test_loc_setitem_with_expansion_preserves_ea_index_dtype(self): + pytest.xfail( + reason="GH#41626 retains index.dtype in setitem-with-expansion. Fails for db_dtypes currently." + ) + + def test_readonly_propagates_to_numpy_array_method(self): + pytest.xfail( + "Fails for db_dtypes because converting to numpy array creates a copy " + "(copy=False is not strictly enforced), so memory is not shared." + ) + # NDArrayBacked2DTests suite added in https://github.com/pandas-dev/pandas/pull/44974 # v1.4.0rc0 diff --git a/tests/compliance/json/conftest.py b/tests/compliance/json/conftest.py index 74870c4..b3b478f 100644 --- a/tests/compliance/json/conftest.py +++ b/tests/compliance/json/conftest.py @@ -40,11 +40,11 @@ def make_data(): {"address": {"street": "123 Main St", "city": "Anytown"}}, {"order": {"items": ["book", "pen"], "total": 15.99}}, ] - data = np.random.default_rng(2).choice(samples, size=100) + data = np.random.default_rng(2).choice(samples, size=10) # This replaces a single data item with an array. We are skipping the first two # items to avoid some `setitem` tests failed, because setting with a list is # ambiguity in this context. - id = random.randint(3, 99) + id = random.randint(3, 9) data[id] = [0.1, 0.2] # Array return data diff --git a/tests/compliance/json/test_json_compliance.py b/tests/compliance/json/test_json_compliance.py index da5b63b..a26e837 100644 --- a/tests/compliance/json/test_json_compliance.py +++ b/tests/compliance/json/test_json_compliance.py @@ -117,6 +117,13 @@ def test_take_pandas_style_negative_raises(self, data, na_value): with pytest.raises(ValueError): data.take([0, -2], fill_value=na_value, allow_fill=True) + @pytest.mark.xfail( + reason="Fails for db_dtypes because converting to numpy array creates a copy " + "(copy=False is not strictly enforced), so memory is not shared." + ) + def test_getitem_propagates_readonly_property(self, data): + super().test_getitem_propagates_readonly_property(data) + class TestJSONArrayIndex(base.BaseIndexTests): pass @@ -143,6 +150,10 @@ def test_array_interface(self, data): def test_view(self, data): super().test_view(data) + @pytest.mark.xfail(reason="Contains check fails for JSON objects (identity/equality issues)") + def test_contains(self, data, data_missing): + super().test_contains(data, data_missing) + def test_array_interface_copy(self, data): # This test was failing compliance checks due to changes in how # numpy handles processing when np.array(obj, copy=False). @@ -229,12 +240,20 @@ def test_argmax_argmin_no_skipna_notimplemented(self, data_missing_for_sorting): # at least pandas version 3.0 (current version is 2.3) data = data_missing_for_sorting - with pytest.raises(NotImplementedError): + with pytest.raises((NotImplementedError, ValueError)): data.argmin(skipna=False) - with pytest.raises(NotImplementedError): + with pytest.raises((NotImplementedError, ValueError)): data.argmax(skipna=False) + @pytest.mark.xfail(reason="fillna limit not supported correctly for dbjson") + def test_fillna_limit_frame(self, data_missing): + super().test_fillna_limit_frame(data_missing) + + @pytest.mark.xfail(reason="fillna limit not supported correctly for dbjson") + def test_fillna_limit_series(self, data_missing): + super().test_fillna_limit_series(data_missing) + class TestJSONArrayMissing(base.BaseMissingTests): @pytest.mark.xfail(reason="Setting a dict as a scalar") @@ -247,6 +266,17 @@ def test_fillna_frame(self): """We treat dictionaries as a mapping in fillna, not a scalar.""" super().test_fillna_frame() + @pytest.mark.xfail( + reason="Fails for db_dtypes because fillna returns self instead of a copy " + "when no NAs are present (violating strict pandas copy semantics)." + ) + def test_fillna_no_op_returns_copy(self, data): + super().test_fillna_no_op_returns_copy(data) + + @pytest.mark.xfail(reason="fillna on readonly array check failing for dbjson") + def test_fillna_readonly(self, data_missing): + super().test_fillna_readonly(data_missing) + @pytest.mark.skip(reason="BigQuery JSON does not allow Arithmetic Ops.") class TestJSONArrayArithmeticOps(base.BaseArithmeticOpsTests): @@ -313,6 +343,10 @@ def test_transpose_frame(self, data): # `DataFrame.T` calls `to_numpy` to get results. super().test_transpose_frame(data) + @pytest.mark.xfail(reason="Stack returns stringified JSON instead of objects (values mismatch)") + def test_stack(self, data, columns, future_stack): + super().test_stack(data, columns, future_stack) + class TestJSONArraySetitem(base.BaseSetitemTests): # Patching `[....] * len()` to base.BaseSetitemTests because pandas' internals @@ -401,10 +435,11 @@ def test_setitem_mask_broadcast(self, data, setter): else: # __setitem__ target = ser - # Use `[data[10]] * len()` instead of passing `data[10]` directly to the super method. - target[mask] = [data[10]] * len(target[mask]) - assert ser[0] == data[10] - assert ser[1] == data[10] + # Use `[data[9]] * len()` instead of passing `data[9]` directly to the super method. + # Changed index from 10 to 9 after reducing data fixture size to 10. + target[mask] = [data[9]] * len(target[mask]) + assert ser[0] == data[9] + assert ser[1] == data[9] @pytest.mark.xfail(reason="eq not implemented for ") def test_setitem_mask_boolean_array_with_na(self, data, box_in_series): diff --git a/tests/compliance/time/conftest.py b/tests/compliance/time/conftest.py index 760a068..2cf46c3 100644 --- a/tests/compliance/time/conftest.py +++ b/tests/compliance/time/conftest.py @@ -34,8 +34,9 @@ def data(): return TimeArray( numpy.arange( datetime.datetime(1970, 1, 1), - datetime.datetime(1970, 1, 2), - datetime.timedelta(microseconds=864_123_456), + datetime.datetime(1970, 1, 1, 0, 0, 1), + # 0.1 seconds (100000 microseconds) + datetime.timedelta(microseconds=100_000), dtype="datetime64[ns]", ) ) diff --git a/tests/compliance/time/test_time_compliance.py b/tests/compliance/time/test_time_compliance.py index 99ac5dd..54f4769 100644 --- a/tests/compliance/time/test_time_compliance.py +++ b/tests/compliance/time/test_time_compliance.py @@ -68,7 +68,11 @@ def test_take_pandas_style_negative_raises(self, data, na_value): class TestGroupby(base.BaseGroupbyTests): - pass + @pytest.mark.xfail( + reason="GH#38980 groupby agg on extension type fails for non-numeric types" + ) + def test_groupby_agg_extension(self, data_for_grouping): + super().test_groupby_agg_extension(data_for_grouping) class TestIndex(base.BaseIndexTests): @@ -131,10 +135,10 @@ def test_argmax_argmin_no_skipna_notimplemented(self, data_missing_for_sorting): # at least pandas version 3.0 (current version is 2.3) data = data_missing_for_sorting - with pytest.raises(NotImplementedError): + with pytest.raises((NotImplementedError, ValueError)): data.argmin(skipna=False) - with pytest.raises(NotImplementedError): + with pytest.raises((NotImplementedError, ValueError)): data.argmax(skipna=False) @@ -163,3 +167,14 @@ def test_setitem_invalid(self, data, invalid_scalar): with pytest.raises((ValueError, TypeError)): data[:] = invalid_scalar + + def test_loc_setitem_with_expansion_preserves_ea_index_dtype(self): + pytest.xfail( + reason="GH#41626 retains index.dtype in setitem-with-expansion. Fails for db_dtypes currently." + ) + + def test_readonly_propagates_to_numpy_array_method(self): + pytest.xfail( + "Fails for db_dtypes because converting to numpy array creates a copy " + "(copy=False is not strictly enforced), so memory is not shared." + )