Compare commits

..

No commits in common. "factory" and "devel" have entirely different histories.

15 changed files with 372 additions and 769 deletions

@ -2,5 +2,4 @@
<package>test-py310</package>
<package>test-py311</package>
<package>test-py312</package>
<package>test-py313</package>
</multibuild>

@ -2,7 +2,7 @@
<service name="tar_scm" mode="disabled">
<param name="url">https://github.com/pandas-dev/pandas.git</param>
<param name="scm">git</param>
<param name="revision">v2.2.3</param>
<param name="revision">v2.2.2</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">v(.*)</param>
<param name="filename">pandas</param>

@ -1,316 +0,0 @@
From 1e899afbd9ca20f4ce9d6f93e1f62c072be0ed23 Mon Sep 17 00:00:00 2001
From: Gen Sato <52241300+halogen22@users.noreply.github.com>
Date: Tue, 18 Mar 2025 01:33:40 +0900
Subject: [PATCH] BUG: .mode(dropna=False) doesn't work with nullable integers
(#61132)
* Fix dropna bug when mode
* Fix test cases
* Fix data type incompatible
---
doc/source/whatsnew/v3.0.0.rst | 1 +
pandas/_libs/hashtable_func_helper.pxi.in | 2 +-
pandas/core/algorithms.py | 12 +++---
pandas/core/arrays/base.py | 5 ++-
pandas/core/arrays/categorical.py | 2 +-
pandas/core/arrays/datetimelike.py | 2 +-
pandas/core/arrays/masked.py | 8 +---
pandas/core/series.py | 2 +-
pandas/tests/series/test_reductions.py | 23 +++++++++++
pandas/tests/test_algos.py | 47 +++++++++++++++--------
10 files changed, 71 insertions(+), 33 deletions(-)
Index: pandas-2.2.3/pandas/_libs/hashtable_func_helper.pxi.in
===================================================================
--- pandas-2.2.3.orig/pandas/_libs/hashtable_func_helper.pxi.in
+++ pandas-2.2.3/pandas/_libs/hashtable_func_helper.pxi.in
@@ -443,7 +443,7 @@ def mode(ndarray[htfunc_t] values, bint
if na_counter > 0:
res_mask = np.zeros(j+1, dtype=np.bool_)
- res_mask[j] = True
+ res_mask[j] = (na_counter == max_count)
return modes[:j + 1], res_mask
Index: pandas-2.2.3/pandas/core/algorithms.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/algorithms.py
+++ pandas-2.2.3/pandas/core/algorithms.py
@@ -1022,7 +1022,7 @@ def duplicated(
def mode(
values: ArrayLike, dropna: bool = True, mask: npt.NDArray[np.bool_] | None = None
-) -> ArrayLike:
+) -> tuple[np.ndarray, npt.NDArray[np.bool_]] | ExtensionArray:
"""
Returns the mode(s) of an array.
@@ -1035,7 +1035,7 @@ def mode(
Returns
-------
- np.ndarray or ExtensionArray
+ Union[Tuple[np.ndarray, npt.NDArray[np.bool_]], ExtensionArray]
"""
values = _ensure_arraylike(values, func_name="mode")
original = values
@@ -1049,8 +1049,10 @@ def mode(
values = _ensure_data(values)
npresult, res_mask = htable.mode(values, dropna=dropna, mask=mask)
- if res_mask is not None:
- return npresult, res_mask # type: ignore[return-value]
+ if res_mask is None:
+ res_mask = np.zeros(npresult.shape, dtype=np.bool_)
+ else:
+ return npresult, res_mask
try:
npresult = np.sort(npresult)
@@ -1061,7 +1063,7 @@ def mode(
)
result = _reconstruct_data(npresult, original.dtype, original)
- return result
+ return result, res_mask
def rank(
Index: pandas-2.2.3/pandas/core/arrays/base.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/arrays/base.py
+++ pandas-2.2.3/pandas/core/arrays/base.py
@@ -2270,8 +2270,9 @@ class ExtensionArray:
Sorted, if possible.
"""
# error: Incompatible return value type (got "Union[ExtensionArray,
- # ndarray[Any, Any]]", expected "Self")
- return mode(self, dropna=dropna) # type: ignore[return-value]
+ # Tuple[np.ndarray, npt.NDArray[np.bool_]]", expected "Self")
+ result, _ = mode(self, dropna=dropna)
+ return result # type: ignore[return-value]
def __array_ufunc__(self, ufunc: np.ufunc, method: str, *inputs, **kwargs):
if any(
Index: pandas-2.2.3/pandas/core/arrays/categorical.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/arrays/categorical.py
+++ pandas-2.2.3/pandas/core/arrays/categorical.py
@@ -2435,7 +2435,7 @@ class Categorical(NDArrayBackedExtension
if dropna:
mask = self.isna()
- res_codes = algorithms.mode(codes, mask=mask)
+ res_codes, _ = algorithms.mode(codes, mask=mask)
res_codes = cast(np.ndarray, res_codes)
assert res_codes.dtype == codes.dtype
res = self._from_backing_data(res_codes)
Index: pandas-2.2.3/pandas/core/arrays/datetimelike.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/arrays/datetimelike.py
+++ pandas-2.2.3/pandas/core/arrays/datetimelike.py
@@ -1646,7 +1646,7 @@ class DatetimeLikeArrayMixin( # type: i
if dropna:
mask = self.isna()
- i8modes = algorithms.mode(self.view("i8"), mask=mask)
+ i8modes, _ = algorithms.mode(self.view("i8"), mask=mask)
npmodes = i8modes.view(self._ndarray.dtype)
npmodes = cast(np.ndarray, npmodes)
return self._from_backing_data(npmodes)
Index: pandas-2.2.3/pandas/core/arrays/masked.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/arrays/masked.py
+++ pandas-2.2.3/pandas/core/arrays/masked.py
@@ -1105,12 +1105,8 @@ class BaseMaskedArray(OpsMixin, Extensio
return Series(arr, index=index, name="count", copy=False)
def _mode(self, dropna: bool = True) -> Self:
- if dropna:
- result = mode(self._data, dropna=dropna, mask=self._mask)
- res_mask = np.zeros(result.shape, dtype=np.bool_)
- else:
- result, res_mask = mode(self._data, dropna=dropna, mask=self._mask)
- result = type(self)(result, res_mask) # type: ignore[arg-type]
+ result, res_mask = mode(self._data, dropna=dropna, mask=self._mask)
+ result = type(self)(result, res_mask)
return result[result.argsort()]
@doc(ExtensionArray.equals)
Index: pandas-2.2.3/pandas/core/series.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/series.py
+++ pandas-2.2.3/pandas/core/series.py
@@ -2328,7 +2328,7 @@ class Series(base.IndexOpsMixin, NDFrame
# TODO: Add option for bins like value_counts()
values = self._values
if isinstance(values, np.ndarray):
- res_values = algorithms.mode(values, dropna=dropna)
+ res_values, _ = algorithms.mode(values, dropna=dropna)
else:
res_values = values._mode(dropna=dropna)
Index: pandas-2.2.3/pandas/tests/series/test_reductions.py
===================================================================
--- pandas-2.2.3.orig/pandas/tests/series/test_reductions.py
+++ pandas-2.2.3/pandas/tests/series/test_reductions.py
@@ -51,6 +51,29 @@ def test_mode_nullable_dtype(any_numeric
tm.assert_series_equal(result, expected)
+def test_mode_nullable_dtype_edge_case(any_numeric_ea_dtype):
+ # GH##58926
+ ser = Series([1, 2, 3, 1], dtype=any_numeric_ea_dtype)
+ result = ser.mode(dropna=False)
+ expected = Series([1], dtype=any_numeric_ea_dtype)
+ tm.assert_series_equal(result, expected)
+
+ ser2 = Series([1, 1, 2, 3, pd.NA], dtype=any_numeric_ea_dtype)
+ result = ser2.mode(dropna=False)
+ expected = Series([1], dtype=any_numeric_ea_dtype)
+ tm.assert_series_equal(result, expected)
+
+ ser3 = Series([1, pd.NA, pd.NA], dtype=any_numeric_ea_dtype)
+ result = ser3.mode(dropna=False)
+ expected = Series([pd.NA], dtype=any_numeric_ea_dtype)
+ tm.assert_series_equal(result, expected)
+
+ ser4 = Series([1, 1, pd.NA, pd.NA], dtype=any_numeric_ea_dtype)
+ result = ser4.mode(dropna=False)
+ expected = Series([1, pd.NA], dtype=any_numeric_ea_dtype)
+ tm.assert_series_equal(result, expected)
+
+
def test_mode_infer_string():
# GH#56183
pytest.importorskip("pyarrow")
Index: pandas-2.2.3/pandas/tests/test_algos.py
===================================================================
--- pandas-2.2.3.orig/pandas/tests/test_algos.py
+++ pandas-2.2.3/pandas/tests/test_algos.py
@@ -1840,7 +1840,8 @@ class TestRank:
class TestMode:
def test_no_mode(self):
exp = Series([], dtype=np.float64, index=Index([], dtype=int))
- tm.assert_numpy_array_equal(algos.mode(np.array([])), exp.values)
+ result, _ = algos.mode(np.array([]))
+ tm.assert_numpy_array_equal(result, exp.values)
@pytest.mark.parametrize("dt", np.typecodes["AllInteger"] + np.typecodes["Float"])
def test_mode_single(self, dt):
@@ -1853,20 +1854,24 @@ class TestMode:
ser = Series(data_single, dtype=dt)
exp = Series(exp_single, dtype=dt)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
ser = Series(data_multi, dtype=dt)
exp = Series(exp_multi, dtype=dt)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
def test_mode_obj_int(self):
exp = Series([1], dtype=int)
- tm.assert_numpy_array_equal(algos.mode(exp.values), exp.values)
+ result, _ = algos.mode(exp.values)
+ tm.assert_numpy_array_equal(result, exp.values)
exp = Series(["a", "b", "c"], dtype=object)
- tm.assert_numpy_array_equal(algos.mode(exp.values), exp.values)
+ result, _ = algos.mode(exp.values)
+ tm.assert_numpy_array_equal(result, exp.values)
@pytest.mark.parametrize("dt", np.typecodes["AllInteger"] + np.typecodes["Float"])
def test_number_mode(self, dt):
@@ -1878,12 +1883,14 @@ class TestMode:
ser = Series(data_single, dtype=dt)
exp = Series(exp_single, dtype=dt)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
ser = Series(data_multi, dtype=dt)
exp = Series(exp_multi, dtype=dt)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
def test_strobj_mode(self):
@@ -1892,7 +1899,8 @@ class TestMode:
ser = Series(data, dtype="c")
exp = Series(exp, dtype="c")
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
@pytest.mark.parametrize("dt", [str, object])
@@ -1902,7 +1910,8 @@ class TestMode:
ser = Series(data, dtype=dt)
exp = Series(exp, dtype=dt)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
def test_datelike_mode(self):
@@ -1936,18 +1945,21 @@ class TestMode:
def test_mixed_dtype(self):
exp = Series(["foo"], dtype=object)
ser = Series([1, "foo", "foo"])
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
def test_uint64_overflow(self):
exp = Series([2**63], dtype=np.uint64)
ser = Series([1, 2**63, 2**63], dtype=np.uint64)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
exp = Series([1, 2**63], dtype=np.uint64)
ser = Series([1, 2**63], dtype=np.uint64)
- tm.assert_numpy_array_equal(algos.mode(ser.values), exp.values)
+ result, _ = algos.mode(ser.values)
+ tm.assert_numpy_array_equal(result, exp.values)
tm.assert_series_equal(ser.mode(), exp)
def test_categorical(self):
@@ -1969,15 +1981,18 @@ class TestMode:
def test_index(self):
idx = Index([1, 2, 3])
exp = Series([1, 2, 3], dtype=np.int64)
- tm.assert_numpy_array_equal(algos.mode(idx), exp.values)
+ result, _ = algos.mode(idx)
+ tm.assert_numpy_array_equal(result, exp.values)
idx = Index([1, "a", "a"])
exp = Series(["a"], dtype=object)
- tm.assert_numpy_array_equal(algos.mode(idx), exp.values)
+ result, _ = algos.mode(idx)
+ tm.assert_numpy_array_equal(result, exp.values)
idx = Index([1, 1, 2, 3, 3])
exp = Series([1, 3], dtype=np.int64)
- tm.assert_numpy_array_equal(algos.mode(idx), exp.values)
+ result, _ = algos.mode(idx)
+ tm.assert_numpy_array_equal(result, exp.values)
idx = Index(
["1 day", "1 day", "-1 day", "-1 day 2 min", "2 min", "2 min"],

3
pandas-2.2.2.tar.gz Normal file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8f044538e419c7d5c03434c96b1439cbd88701dcd02d6a79b08947fbb656c2f4
size 50782448

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:be944b80189d9bbcbd269aa5f43cfe9d607149a19473121aed8d51f5d56c4ff0
size 52331559

@ -0,0 +1,40 @@
From 1828b62ee913da44ec4402642ef7baaafeb65677 Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Mon, 15 Apr 2024 09:47:31 -1000
Subject: [PATCH] Backport PR #58268: CI/TST: Unxfail
test_slice_locs_negative_step Pyarrow test
---
pandas/tests/indexes/object/test_indexing.py | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/pandas/tests/indexes/object/test_indexing.py b/pandas/tests/indexes/object/test_indexing.py
index 443cacf94d239..ebf9dac715f8d 100644
--- a/pandas/tests/indexes/object/test_indexing.py
+++ b/pandas/tests/indexes/object/test_indexing.py
@@ -7,7 +7,6 @@
NA,
is_matching_na,
)
-from pandas.compat import pa_version_under16p0
import pandas.util._test_decorators as td
import pandas as pd
@@ -201,16 +200,7 @@ class TestSliceLocs:
(pd.IndexSlice["m":"m":-1], ""), # type: ignore[misc]
],
)
- def test_slice_locs_negative_step(self, in_slice, expected, dtype, request):
- if (
- not pa_version_under16p0
- and dtype == "string[pyarrow_numpy]"
- and in_slice == slice("a", "a", -1)
- ):
- request.applymarker(
- pytest.mark.xfail(reason="https://github.com/apache/arrow/issues/40642")
- )
-
+ def test_slice_locs_negative_step(self, in_slice, expected, dtype):
index = Index(list("bcdxy"), dtype=dtype)
s_start, s_stop = index.slice_locs(in_slice.start, in_slice.stop, in_slice.step)

@ -0,0 +1,71 @@
From 0cab756077f5291f8d6a7fcfacaf374f62b866a0 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Mon, 29 Apr 2024 23:11:21 -0400
Subject: [PATCH 1/2] Remove deprecated plot_date calls
These were deprecated in Matplotlib 3.9.
---
pandas/tests/plotting/test_datetimelike.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py
index 6b709522bab70..b91bde41bf4c4 100644
--- a/pandas/tests/plotting/test_datetimelike.py
+++ b/pandas/tests/plotting/test_datetimelike.py
@@ -1432,13 +1432,11 @@ def test_mpl_nopandas(self):
values1 = np.arange(10.0, 11.0, 0.5)
values2 = np.arange(11.0, 12.0, 0.5)
- kw = {"fmt": "-", "lw": 4}
-
_, ax = mpl.pyplot.subplots()
- ax.plot_date([x.toordinal() for x in dates], values1, **kw)
- ax.plot_date([x.toordinal() for x in dates], values2, **kw)
-
- line1, line2 = ax.get_lines()
+ line1, line2, = ax.plot(
+ [x.toordinal() for x in dates], values1, "-",
+ [x.toordinal() for x in dates], values2, "-",
+ linewidth=4)
exp = np.array([x.toordinal() for x in dates], dtype=np.float64)
tm.assert_numpy_array_equal(line1.get_xydata()[:, 0], exp)
From 6d6574c4e71e3bab91503f85c8aa80c927785865 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Tue, 30 Apr 2024 16:47:26 +0000
Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
pandas/tests/plotting/test_datetimelike.py | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py
index b91bde41bf4c4..4b4eeada58366 100644
--- a/pandas/tests/plotting/test_datetimelike.py
+++ b/pandas/tests/plotting/test_datetimelike.py
@@ -1433,10 +1433,18 @@ def test_mpl_nopandas(self):
values2 = np.arange(11.0, 12.0, 0.5)
_, ax = mpl.pyplot.subplots()
- line1, line2, = ax.plot(
- [x.toordinal() for x in dates], values1, "-",
- [x.toordinal() for x in dates], values2, "-",
- linewidth=4)
+ (
+ line1,
+ line2,
+ ) = ax.plot(
+ [x.toordinal() for x in dates],
+ values1,
+ "-",
+ [x.toordinal() for x in dates],
+ values2,
+ "-",
+ linewidth=4,
+ )
exp = np.array([x.toordinal() for x in dates], dtype=np.float64)
tm.assert_numpy_array_equal(line1.get_xydata()[:, 0], exp)

@ -0,0 +1,41 @@
From d36f6dac81b577504386b53357270d9f05a9bc89 Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Tue, 14 May 2024 09:04:20 -1000
Subject: [PATCH] Backport PR #58719: CI: xfail test_to_xarray_index_types due
to new 2024.5 release
---
pandas/tests/generic/test_to_xarray.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/pandas/tests/generic/test_to_xarray.py b/pandas/tests/generic/test_to_xarray.py
index d8401a8b2ae3f..491f621783a76 100644
--- a/pandas/tests/generic/test_to_xarray.py
+++ b/pandas/tests/generic/test_to_xarray.py
@@ -9,6 +9,7 @@
date_range,
)
import pandas._testing as tm
+from pandas.util.version import Version
pytest.importorskip("xarray")
@@ -29,11 +30,17 @@ def df(self):
}
)
- def test_to_xarray_index_types(self, index_flat, df, using_infer_string):
+ def test_to_xarray_index_types(self, index_flat, df, using_infer_string, request):
index = index_flat
# MultiIndex is tested in test_to_xarray_with_multiindex
if len(index) == 0:
pytest.skip("Test doesn't make sense for empty index")
+ import xarray
+
+ if Version(xarray.__version__) >= Version("2024.5"):
+ request.applymarker(
+ pytest.mark.xfail(reason="https://github.com/pydata/xarray/issues/9026")
+ )
from xarray import Dataset

@ -0,0 +1,29 @@
From d4e803caf7aabd464f6fb1d43ef39903911a3cec Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Wed, 3 Jul 2024 06:45:24 -1000
Subject: [PATCH] Backport PR #59168: TST: Address UserWarning in matplotlib
test
---
pandas/plotting/_matplotlib/core.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py
index 2979903edf360..52382d9f7d572 100644
--- a/pandas/plotting/_matplotlib/core.py
+++ b/pandas/plotting/_matplotlib/core.py
@@ -893,7 +893,13 @@ def _make_legend(self) -> None:
elif self.subplots and self.legend:
for ax in self.axes:
if ax.get_visible():
- ax.legend(loc="best")
+ with warnings.catch_warnings():
+ warnings.filterwarnings(
+ "ignore",
+ "No artists with labels found to put in legend.",
+ UserWarning,
+ )
+ ax.legend(loc="best")
@final
@staticmethod

@ -0,0 +1,174 @@
diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py
index 361998db8e..87d419e2db 100644
--- a/pandas/_testing/__init__.py
+++ b/pandas/_testing/__init__.py
@@ -111,6 +111,7 @@ ALL_FLOAT_DTYPES: list[Dtype] = [*FLOAT_NUMPY_DTYPES, *FLOAT_EA_DTYPES]
COMPLEX_DTYPES: list[Dtype] = [complex, "complex64", "complex128"]
STRING_DTYPES: list[Dtype] = [str, "str", "U"]
+COMPLEX_FLOAT_DTYPES: list[Dtype] = [*COMPLEX_DTYPES, *FLOAT_NUMPY_DTYPES]
DATETIME64_DTYPES: list[Dtype] = ["datetime64[ns]", "M8[ns]"]
TIMEDELTA64_DTYPES: list[Dtype] = ["timedelta64[ns]", "m8[ns]"]
diff --git a/pandas/conftest.py b/pandas/conftest.py
index 7c35dfdde9..10134c90f8 100644
--- a/pandas/conftest.py
+++ b/pandas/conftest.py
@@ -1403,6 +1403,21 @@ def complex_dtype(request):
return request.param
+@pytest.fixture(params=tm.COMPLEX_FLOAT_DTYPES)
+def complex_or_float_dtype(request):
+ """
+ Parameterized fixture for complex and numpy float dtypes.
+
+ * complex
+ * 'complex64'
+ * 'complex128'
+ * float
+ * 'float32'
+ * 'float64'
+ """
+ return request.param
+
+
@pytest.fixture(params=tm.SIGNED_INT_NUMPY_DTYPES)
def any_signed_int_numpy_dtype(request):
"""
diff --git a/pandas/core/computation/expr.py b/pandas/core/computation/expr.py
index b5861fbaeb..d642c37cea 100644
--- a/pandas/core/computation/expr.py
+++ b/pandas/core/computation/expr.py
@@ -31,7 +31,6 @@ from pandas.core.computation.ops import (
UNARY_OPS_SYMS,
BinOp,
Constant,
- Div,
FuncNode,
Op,
Term,
@@ -370,7 +369,7 @@ class BaseExprVisitor(ast.NodeVisitor):
"Add",
"Sub",
"Mult",
- None,
+ "Div",
"Pow",
"FloorDiv",
"Mod",
@@ -533,9 +532,6 @@ class BaseExprVisitor(ast.NodeVisitor):
left, right = self._maybe_downcast_constants(left, right)
return self._maybe_evaluate_binop(op, op_class, left, right)
- def visit_Div(self, node, **kwargs):
- return lambda lhs, rhs: Div(lhs, rhs)
-
def visit_UnaryOp(self, node, **kwargs):
op = self.visit(node.op)
operand = self.visit(node.operand)
diff --git a/pandas/core/computation/ops.py b/pandas/core/computation/ops.py
index 95ac20ba39..ea8b1c0457 100644
--- a/pandas/core/computation/ops.py
+++ b/pandas/core/computation/ops.py
@@ -332,31 +332,6 @@ for d in (_cmp_ops_dict, _bool_ops_dict, _arith_ops_dict):
_binary_ops_dict.update(d)
-def _cast_inplace(terms, acceptable_dtypes, dtype) -> None:
- """
- Cast an expression inplace.
-
- Parameters
- ----------
- terms : Op
- The expression that should cast.
- acceptable_dtypes : list of acceptable numpy.dtype
- Will not cast if term's dtype in this list.
- dtype : str or numpy.dtype
- The dtype to cast to.
- """
- dt = np.dtype(dtype)
- for term in terms:
- if term.type in acceptable_dtypes:
- continue
-
- try:
- new_value = term.value.astype(dt)
- except AttributeError:
- new_value = dt.type(term.value)
- term.update(new_value)
-
-
def is_term(obj) -> bool:
return isinstance(obj, Term)
@@ -516,31 +491,6 @@ class BinOp(Op):
def isnumeric(dtype) -> bool:
return issubclass(np.dtype(dtype).type, np.number)
-
-class Div(BinOp):
- """
- Div operator to special case casting.
-
- Parameters
- ----------
- lhs, rhs : Term or Op
- The Terms or Ops in the ``/`` expression.
- """
-
- def __init__(self, lhs, rhs) -> None:
- super().__init__("/", lhs, rhs)
-
- if not isnumeric(lhs.return_type) or not isnumeric(rhs.return_type):
- raise TypeError(
- f"unsupported operand type(s) for {self.op}: "
- f"'{lhs.return_type}' and '{rhs.return_type}'"
- )
-
- # do not upcast float32s to float64 un-necessarily
- acceptable_dtypes = [np.float32, np.float64]
- _cast_inplace(com.flatten(self), acceptable_dtypes, np.float64)
-
-
UNARY_OPS_SYMS = ("+", "-", "~", "not")
_unary_ops_funcs = (operator.pos, operator.neg, operator.invert, operator.invert)
_unary_ops_dict = dict(zip(UNARY_OPS_SYMS, _unary_ops_funcs))
diff --git a/pandas/tests/computation/test_eval.py b/pandas/tests/computation/test_eval.py
index 17630f14b0..e8fad6b8cb 100644
--- a/pandas/tests/computation/test_eval.py
+++ b/pandas/tests/computation/test_eval.py
@@ -747,16 +747,26 @@ class TestTypeCasting:
@pytest.mark.parametrize("op", ["+", "-", "*", "**", "/"])
# maybe someday... numexpr has too many upcasting rules now
# chain(*(np.core.sctypes[x] for x in ['uint', 'int', 'float']))
- @pytest.mark.parametrize("dt", [np.float32, np.float64])
@pytest.mark.parametrize("left_right", [("df", "3"), ("3", "df")])
- def test_binop_typecasting(self, engine, parser, op, dt, left_right):
- df = DataFrame(np.random.default_rng(2).standard_normal((5, 3)), dtype=dt)
+ def test_binop_typecasting(
+ self, engine, parser, op, complex_or_float_dtype, left_right, request
+ ):
+ # GH#21374
+ dtype = complex_or_float_dtype
+ df = DataFrame(np.random.default_rng(2).standard_normal((5, 3)), dtype=dtype)
left, right = left_right
s = f"{left} {op} {right}"
res = pd.eval(s, engine=engine, parser=parser)
- assert df.values.dtype == dt
- assert res.values.dtype == dt
- tm.assert_frame_equal(res, eval(s))
+ if dtype == "complex64" and engine == "numexpr":
+ mark = pytest.mark.xfail(
+ reason="numexpr issue with complex that are upcast "
+ "to complex 128 "
+ "https://github.com/pydata/numexpr/issues/492"
+ )
+ request.applymarker(mark)
+ assert df.values.dtype == dtype
+ assert res.values.dtype == dtype
+ tm.assert_frame_equal(res, eval(s), check_exact=False)
# -------------------------------------

@ -1,23 +0,0 @@
From f97f5e107f145fd09133d21cb1902c84c936754c Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Wed, 11 Dec 2024 13:20:10 -0800
Subject: [PATCH] Backport PR #60544: CI/TST: Use tm.external_error_raised for
test_from_arrow_respecting_given_dtype_unsafe
---
pandas/tests/extension/test_arrow.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py
index 03ab7c7f1dad8..470ca0673c60e 100644
--- a/pandas/tests/extension/test_arrow.py
+++ b/pandas/tests/extension/test_arrow.py
@@ -1637,7 +1637,7 @@ def test_from_arrow_respecting_given_dtype():
def test_from_arrow_respecting_given_dtype_unsafe():
array = pa.array([1.5, 2.5], type=pa.float64())
- with pytest.raises(pa.ArrowInvalid, match="Float value 1.5 was truncated"):
+ with tm.external_error_raised(pa.ArrowInvalid):
array.to_pandas(types_mapper={pa.float64(): ArrowDtype(pa.int64())}.get)

@ -1,306 +0,0 @@
From 78b63f87013c8d2fe98fc86ecf685b5cd20da3e1 Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Tue, 17 Dec 2024 15:01:59 -0800
Subject: [PATCH 1/3] Backport PR #60584: TST: Address matplotlib 3.10
deprecation of vert=
---
pandas/plotting/_matplotlib/boxplot.py | 4 +-
pandas/plotting/_matplotlib/tools.py | 2 +-
pandas/tests/plotting/frame/test_frame.py | 41 ++++++++++++----
pandas/tests/plotting/test_boxplot_method.py | 50 +++++++++++++++-----
4 files changed, 74 insertions(+), 23 deletions(-)
diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py
index d2b76decaa75d..f78327896908f 100644
--- a/pandas/plotting/_matplotlib/boxplot.py
+++ b/pandas/plotting/_matplotlib/boxplot.py
@@ -20,6 +20,7 @@
import pandas as pd
import pandas.core.common as com
+from pandas.util.version import Version
from pandas.io.formats.printing import pprint_thing
from pandas.plotting._matplotlib.core import (
@@ -54,7 +55,8 @@ def _set_ticklabels(ax: Axes, labels: list[str], is_vertical: bool, **kwargs) ->
ticks = ax.get_xticks() if is_vertical else ax.get_yticks()
if len(ticks) != len(labels):
i, remainder = divmod(len(ticks), len(labels))
- assert remainder == 0, remainder
+ if Version(mpl.__version__) < Version("3.10"):
+ assert remainder == 0, remainder
labels *= i
if is_vertical:
ax.set_xticklabels(labels, **kwargs)
diff --git a/pandas/plotting/_matplotlib/tools.py b/pandas/plotting/_matplotlib/tools.py
index 898b5b25e7b01..98441c5afbaa4 100644
--- a/pandas/plotting/_matplotlib/tools.py
+++ b/pandas/plotting/_matplotlib/tools.py
@@ -57,7 +57,7 @@ def format_date_labels(ax: Axes, rot) -> None:
fig = ax.get_figure()
if fig is not None:
# should always be a Figure but can technically be None
- maybe_adjust_figure(fig, bottom=0.2)
+ maybe_adjust_figure(fig, bottom=0.2) # type: ignore[arg-type]
def table(
diff --git a/pandas/tests/plotting/frame/test_frame.py b/pandas/tests/plotting/frame/test_frame.py
index 4ca4067214bbd..33366b4eabba5 100644
--- a/pandas/tests/plotting/frame/test_frame.py
+++ b/pandas/tests/plotting/frame/test_frame.py
@@ -1059,28 +1059,43 @@ def test_boxplot_series_positions(self, hist_df):
tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), positions)
assert len(ax.lines) == 7 * len(numeric_cols)
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
+ @pytest.mark.xfail(
+ Version(mpl.__version__) >= Version("3.10"),
+ reason="Fails starting with matplotlib 3.10",
+ )
def test_boxplot_vertical(self, hist_df):
df = hist_df
numeric_cols = df._get_numeric_data().columns
labels = [pprint_thing(c) for c in numeric_cols]
# if horizontal, yticklabels are rotated
- ax = df.plot.box(rot=50, fontsize=8, vert=False)
+ kwargs = (
+ {"vert": False}
+ if Version(mpl.__version__) < Version("3.10")
+ else {"orientation": "horizontal"}
+ )
+ ax = df.plot.box(rot=50, fontsize=8, **kwargs)
_check_ticks_props(ax, xrot=0, yrot=50, ylabelsize=8)
_check_text_labels(ax.get_yticklabels(), labels)
assert len(ax.lines) == 7 * len(numeric_cols)
- @pytest.mark.filterwarnings("ignore:Attempt:UserWarning")
+ @pytest.mark.filterwarnings("ignore::UserWarning")
+ @pytest.mark.xfail(
+ Version(mpl.__version__) >= Version("3.10"),
+ reason="Fails starting with matplotlib version 3.10",
+ )
def test_boxplot_vertical_subplots(self, hist_df):
df = hist_df
numeric_cols = df._get_numeric_data().columns
labels = [pprint_thing(c) for c in numeric_cols]
+ kwargs = (
+ {"vert": False}
+ if Version(mpl.__version__) < Version("3.10")
+ else {"orientation": "horizontal"}
+ )
axes = _check_plot_works(
- df.plot.box,
- default_axes=True,
- subplots=True,
- vert=False,
- logx=True,
+ df.plot.box, default_axes=True, subplots=True, logx=True, **kwargs
)
_check_axes_shape(axes, axes_num=3, layout=(1, 3))
_check_ax_scales(axes, xaxis="log")
@@ -1088,12 +1103,22 @@ def test_boxplot_vertical_subplots(self, hist_df):
_check_text_labels(ax.get_yticklabels(), [label])
assert len(ax.lines) == 7
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
+ @pytest.mark.xfail(
+ Version(mpl.__version__) >= Version("3.10"),
+ reason="Fails starting with matplotlib 3.10",
+ )
def test_boxplot_vertical_positions(self, hist_df):
df = hist_df
numeric_cols = df._get_numeric_data().columns
labels = [pprint_thing(c) for c in numeric_cols]
positions = np.array([3, 2, 8])
- ax = df.plot.box(positions=positions, vert=False)
+ kwargs = (
+ {"vert": False}
+ if Version(mpl.__version__) < Version("3.10")
+ else {"orientation": "horizontal"}
+ )
+ ax = df.plot.box(positions=positions, **kwargs)
_check_text_labels(ax.get_yticklabels(), labels)
tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), positions)
assert len(ax.lines) == 7 * len(numeric_cols)
diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py
index 76f7fa1f22eec..969ea76efd041 100644
--- a/pandas/tests/plotting/test_boxplot_method.py
+++ b/pandas/tests/plotting/test_boxplot_method.py
@@ -1,5 +1,7 @@
""" Test cases for .boxplot method """
+from __future__ import annotations
+
import itertools
import string
@@ -22,6 +24,7 @@
_check_ticks_props,
_check_visible,
)
+from pandas.util.version import Version
from pandas.io.formats.printing import pprint_thing
@@ -35,6 +38,17 @@ def _check_ax_limits(col, ax):
assert y_max >= col.max()
+if Version(mpl.__version__) < Version("3.10"):
+ verts: list[dict[str, bool | str]] = [{"vert": False}, {"vert": True}]
+else:
+ verts = [{"orientation": "horizontal"}, {"orientation": "vertical"}]
+
+
+@pytest.fixture(params=verts)
+def vert(request):
+ return request.param
+
+
class TestDataFramePlots:
def test_stacked_boxplot_set_axis(self):
# GH2980
@@ -315,7 +329,7 @@ def test_specified_props_kwd(self, props, expected):
assert result[expected][0].get_color() == "C1"
- @pytest.mark.parametrize("vert", [True, False])
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
def test_plot_xlabel_ylabel(self, vert):
df = DataFrame(
{
@@ -325,11 +339,11 @@ def test_plot_xlabel_ylabel(self, vert):
}
)
xlabel, ylabel = "x", "y"
- ax = df.plot(kind="box", vert=vert, xlabel=xlabel, ylabel=ylabel)
+ ax = df.plot(kind="box", xlabel=xlabel, ylabel=ylabel, **vert)
assert ax.get_xlabel() == xlabel
assert ax.get_ylabel() == ylabel
- @pytest.mark.parametrize("vert", [True, False])
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
def test_plot_box(self, vert):
# GH 54941
rng = np.random.default_rng(2)
@@ -338,14 +352,14 @@ def test_plot_box(self, vert):
xlabel, ylabel = "x", "y"
_, axs = plt.subplots(ncols=2, figsize=(10, 7), sharey=True)
- df1.plot.box(ax=axs[0], vert=vert, xlabel=xlabel, ylabel=ylabel)
- df2.plot.box(ax=axs[1], vert=vert, xlabel=xlabel, ylabel=ylabel)
+ df1.plot.box(ax=axs[0], xlabel=xlabel, ylabel=ylabel, **vert)
+ df2.plot.box(ax=axs[1], xlabel=xlabel, ylabel=ylabel, **vert)
for ax in axs:
assert ax.get_xlabel() == xlabel
assert ax.get_ylabel() == ylabel
mpl.pyplot.close()
- @pytest.mark.parametrize("vert", [True, False])
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
def test_boxplot_xlabel_ylabel(self, vert):
df = DataFrame(
{
@@ -355,11 +369,11 @@ def test_boxplot_xlabel_ylabel(self, vert):
}
)
xlabel, ylabel = "x", "y"
- ax = df.boxplot(vert=vert, xlabel=xlabel, ylabel=ylabel)
+ ax = df.boxplot(xlabel=xlabel, ylabel=ylabel, **vert)
assert ax.get_xlabel() == xlabel
assert ax.get_ylabel() == ylabel
- @pytest.mark.parametrize("vert", [True, False])
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
def test_boxplot_group_xlabel_ylabel(self, vert):
df = DataFrame(
{
@@ -369,14 +383,20 @@ def test_boxplot_group_xlabel_ylabel(self, vert):
}
)
xlabel, ylabel = "x", "y"
- ax = df.boxplot(by="group", vert=vert, xlabel=xlabel, ylabel=ylabel)
+ ax = df.boxplot(by="group", xlabel=xlabel, ylabel=ylabel, **vert)
for subplot in ax:
assert subplot.get_xlabel() == xlabel
assert subplot.get_ylabel() == ylabel
mpl.pyplot.close()
- @pytest.mark.parametrize("vert", [True, False])
- def test_boxplot_group_no_xlabel_ylabel(self, vert):
+ @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning")
+ def test_boxplot_group_no_xlabel_ylabel(self, vert, request):
+ if Version(mpl.__version__) >= Version("3.10") and vert == {
+ "orientation": "horizontal"
+ }:
+ request.applymarker(
+ pytest.mark.xfail(reason=f"{vert} fails starting with matplotlib 3.10")
+ )
df = DataFrame(
{
"a": np.random.default_rng(2).standard_normal(10),
@@ -384,9 +404,13 @@ def test_boxplot_group_no_xlabel_ylabel(self, vert):
"group": np.random.default_rng(2).choice(["group1", "group2"], 10),
}
)
- ax = df.boxplot(by="group", vert=vert)
+ ax = df.boxplot(by="group", **vert)
for subplot in ax:
- target_label = subplot.get_xlabel() if vert else subplot.get_ylabel()
+ target_label = (
+ subplot.get_xlabel()
+ if vert == {"vert": True} or vert == {"orientation": "vertical"}
+ else subplot.get_ylabel()
+ )
assert target_label == pprint_thing(["group"])
mpl.pyplot.close()
From 8d4c506e4352341dff217f1658a4c1655031eef7 Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Tue, 17 Dec 2024 15:15:51 -0800
Subject: [PATCH 2/3] Add missing import
---
pandas/plotting/_matplotlib/boxplot.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py
index f78327896908f..80f0349b205e6 100644
--- a/pandas/plotting/_matplotlib/boxplot.py
+++ b/pandas/plotting/_matplotlib/boxplot.py
@@ -7,6 +7,7 @@
)
import warnings
+import matplotlib as mpl
from matplotlib.artist import setp
import numpy as np
From 5b0e557934b771b5d4d5d100605d351cf48a3b10 Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Tue, 17 Dec 2024 15:27:55 -0800
Subject: [PATCH 3/3] Ignore pre-commit check
---
pandas/tests/plotting/test_boxplot_method.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py
index 969ea76efd041..e1b03a34086c0 100644
--- a/pandas/tests/plotting/test_boxplot_method.py
+++ b/pandas/tests/plotting/test_boxplot_method.py
@@ -408,7 +408,8 @@ def test_boxplot_group_no_xlabel_ylabel(self, vert, request):
for subplot in ax:
target_label = (
subplot.get_xlabel()
- if vert == {"vert": True} or vert == {"orientation": "vertical"}
+ if vert == {"vert": True} # noqa: PLR1714
+ or vert == {"orientation": "vertical"}
else subplot.get_ylabel()
)
assert target_label == pprint_thing(["group"])

@ -1,75 +1,3 @@
-------------------------------------------------------------------
Thu Mar 20 11:36:22 UTC 2025 - Markéta Machová <mmachova@suse.com>
- Add dropna.patch and timedelta.patch to fix tests with Numpy 2.2
-------------------------------------------------------------------
Thu Feb 20 11:23:33 UTC 2025 - Ben Greiner <code@bnavigator.de>
- Support pyarrow 19
* Add pandas-pr60545-arrow-exception.patch
gh#pandas-dev/pandas#60545
* Skip TestParquetPyArrow.test_roundtrip_decimal: Would require
gh#pandas-dev/pandas#60755 and all other backports of the new
string type system.
-------------------------------------------------------------------
Fri Feb 7 18:40:46 UTC 2025 - Ben Greiner <code@bnavigator.de>
- Add pandas-pr60584-60586-mpl-vert.patch
* Fixes matplotlib deprecation errors in the test suite
* gh#pandas-dev/pandas#60584
* backported in gh#pandas-dev/pandas#60586
-------------------------------------------------------------------
Fri Dec 13 06:51:11 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
- Change skipped tests to also support Python 3.13.
-------------------------------------------------------------------
Wed Nov 27 12:26:36 UTC 2024 - Markéta Machová <mmachova@suse.com>
- Drop tests-nomkl.patch and tests-wasm.patch, not needed anymore
- Skip a test failing with new xarray
------------------------------------------------------------------
Fri Oct 25 05:19:49 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
- Skip two tests that fail with Numpy 2.1.
-------------------------------------------------------------------
Fri Oct 11 04:40:52 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
- Prepare for Python 3.13, by skipping it if we aren't building for it.
-------------------------------------------------------------------
Tue Oct 1 12:35:22 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
- Update to 2.2.3
* Bug in eval() on complex including division /
discards imaginary part. (GH 21374)
* Minor fixes for numpy 2.1 compatibility. (GH 59444)
* Missing licenses for 3rd party dependencies were
added back into the wheels. (GH 58632)
- Drop pandas-pr58269-pyarrow16xpass.patch, merged upstream
- Drop pandas-pr58484-matplotlib.patch, merged upstream
- Drop pandas-pr59175-matplotlib.patch, merged upstream
- Drop pandas-pr59353-np2eval.patch, merged upstream
- Drop tests-npdev.patch, merged upstream
- Drop tests-timedelta.patch, merged upstream
- Refresh tests-nomkl.patch
- Renumber remaining patches
-------------------------------------------------------------------
Mon Sep 16 19:39:38 UTC 2024 - Markéta Machová <mmachova@suse.com>
- Add bunch of patches to fix the testsuite with NumPy 2.1
* tests-wasm.patch
* tests-nomkl.patch
* tests-timedelta.patch
* tests-npdev.patch
- Skip one test failing with new timezone, the patch would be too big
-------------------------------------------------------------------
Sun Sep 8 10:02:47 UTC 2024 - Ben Greiner <code@bnavigator.de>

@ -1,7 +1,7 @@
#
# spec file for package python-pandas
#
# Copyright (c) 2025 SUSE LLC
# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -34,9 +34,6 @@
%if "%{flavor}" != "test-py312"
%define skip_python312 1
%endif
%if "%{flavor}" != "test-py313"
%define skip_python313 1
%endif
# Skip empty buildsets, last one is for sle15_python_module_pythons
%if "%{shrink:%{pythons}}" == "" || ("%pythons" == "python311" && 0%{?skip_python311})
ExclusiveArch: donotbuild
@ -64,7 +61,7 @@ ExclusiveArch: donotbuild
%endif
Name: python-pandas%{psuffix}
# Set version through _service
Version: 2.2.3
Version: 2.2.2
Release: 0
Summary: Python data structures for data analysis, time series, and statistics
License: BSD-3-Clause
@ -72,14 +69,14 @@ URL: https://pandas.pydata.org/
# SourceRepository: https://github.com/pandas-dev/pandas
# Must be created by cloning through `osc service runall`: gh#pandas-dev/pandas#54903, gh#pandas-dev/pandas#54907
Source0: pandas-%{version}.tar.gz
# PATCH-FIX-UPSTREAM pandas-pr60545-arrow-exception.patch gh#pandas-dev/pandas#60545
Patch0: https://github.com/pandas-dev/pandas/pull/60545.patch#/pandas-pr60545-arrow-exception.patch
# PATCH-FIX-UPSTREAM pandas-pr60584-60586-mpl-vert.patch gh#pandas-dev/pandas#60584 gh#pandas-dev/pandas#60586
Patch1: https://github.com/pandas-dev/pandas/pull/60586.patch#/pandas-pr60584-60586-mpl-vert.patch
# PATCH-FIX-UPSTREAM https://github.com/pandas-dev/pandas/pull/61132 BUG: .mode(dropna=False) doesn't work with nullable integers
Patch2: dropna.patch
# PATCH-FIX-UPSTREAM https://github.com/pandas-dev/pandas/pull/60416 TST: Avoid hashing np.timedelta64 without unit
Patch3: timedelta.patch
# PATCH-FIX-UPSTREAM pandas-pr58269-pyarrow16xpass.patch -- gh#pandas-dev/pandas#58269
Patch0: pandas-pr58269-pyarrow16xpass.patch
# PATCH-FIX-UPSTREAM pandas-pr58484-matplotlib.patch -- gh#pandas-dev/pandas#58484 mcepl@suse.com, make pandas compatible with the modern matplotlib
Patch2: pandas-pr58484-matplotlib.patch
# PATCH-FIX-UPSTREAM pandas-pr59175-matplotlib.patch -- gh#pandas-dev/pandas#59175
Patch3: https://github.com/pandas-dev/pandas/pull/59175.patch#/pandas-pr59175-matplotlib.patch
# PATCH-FIX-UPSTREAM pandas-pr59353-np2eval.patch -- gh#pandas-dev/pandas#59144 backported to 2.2, no new tests, see gh#pandas-dev/pandas#58548, gh#pandas-dev/pandas#59353
Patch4: pandas-pr59353-np2eval.patch
%if !%{with test}
BuildRequires: %{python_module Cython >= 3.0.5}
BuildRequires: %{python_module devel >= 3.9}
@ -517,21 +514,12 @@ SKIP_TESTS+=" or test_psycopg2_schema_support"
SKIP_TESTS+=" or test_self_join_date_columns"
# expects a dirty git revision from git repo
SKIP_TESTS+=" or test_git_version"
# https://github.com/pandas-dev/pandas/pull/57391, proposed change is not necessarily the right one
%if "%{flavor}" == "test-py312"
# https://github.com/pandas-dev/pandas/pull/57391, proposed change is not necessarily the right one
SKIP_TESTS+=" or (test_scalar_unary and numexpr-pandas)"
%endif
%if "%{flavor}" == "test-py313"
SKIP_TESTS+=" or (test_scalar_unary and numexpr-pandas)"
%endif
# https://github.com/pandas-dev/pandas/pull/55901, not gonna merge this huge patch to fix one test failing with new timezone, will be included in new release
SKIP_TESTS+=" or test_array_inference[data7-expected7]"
# numpy 2.1 issues?
SKIP_TESTS+=" or test_frame_setitem_dask_array_into_new_col"
# too new xarray, gh#pandas-dev/pandas#60109 backport too much
SKIP_TESTS+=" or (TestDataFrameToXArray and test_to_xarray_index_types)"
# too new pyarrow, gh#pandas-dev/pandas#60755 backport too much
SKIP_TESTS+=" or (TestParquetPyArrow and test_roundtrip_decimal)"
# Numpy2: unexpected 'np.str_(...)' in error message
SKIP_TESTS+=" or test_group_subplot_invalid_column_name"
%ifarch %{ix86} %{arm32}
# https://github.com/pandas-dev/pandas/issues/31856

@ -1,22 +0,0 @@
From 0b6cece3acda1ae6e4f582d8276851b02aeac1ea Mon Sep 17 00:00:00 2001
From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com>
Date: Mon, 25 Nov 2024 11:35:37 -0800
Subject: [PATCH] TST: Avoid hashing np.timedelta64 without unit (#60416)
---
pandas/tests/test_algos.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: pandas-2.2.3/pandas/tests/test_algos.py
===================================================================
--- pandas-2.2.3.orig/pandas/tests/test_algos.py
+++ pandas-2.2.3/pandas/tests/test_algos.py
@@ -1280,7 +1280,7 @@ class TestValueCounts:
result_dt = algos.value_counts(dt)
tm.assert_series_equal(result_dt, exp_dt)
- exp_td = Series({np.timedelta64(10000): 1}, name="count")
+ exp_td = Series([1], index=[np.timedelta64(10000)], name="count")
with tm.assert_produces_warning(FutureWarning, match=msg):
result_td = algos.value_counts(td)
tm.assert_series_equal(result_td, exp_td)