Accepting request 1292272 from devel:languages:python:numeric

- Update to 2.3.1
  * This release includes some improvements and fixes to the future
    string data type (preview feature for the upcoming pandas 3.0)
  ## Improvements and fixes for the StringDtype
  * Comparisons between different string dtypes
  * Index set operations ignore empty RangeIndex and object dtype
    Index
  ## Bug fixes
  * Bug in DataFrameGroupBy.min(), DataFrameGroupBy.max(),
    Resampler.min(), Resampler.max() where all NA values of string
    dtype would return float instead of string dtype (GH 60810)
  * Bug in DataFrame.join() incorrectly downcasting object-dtype
    indexes (GH 61771)
  * Bug in DataFrame.sum() with axis=1, DataFrameGroupBy.sum() or
    SeriesGroupBy.sum() with skipna=True, and Resampler.sum() with
    all NA values of StringDtype resulted in 0 instead of the empty
    string "" (GH 60229)
  * Fixed bug in DataFrame.explode() and Series.explode() where
    methods would fail with dtype="str" (GH 61623)
  * Fixed bug in unpickling objects pickled in pandas versions
    pre-2.3.0 that used StringDtype (GH 61763)
- Release 2.3.0
  ## Enhancements
  * The semantics for the copy keyword in __array__ methods (i.e.
    called when using np.array() or np.asarray() on pandas objects)
    has been updated to work correctly with NumPy >= 2 (GH 57739)
  * Series.str.decode() result now has StringDtype when
    future.infer_string is True (GH 60709)
  * to_hdf() and to_hdf() now round-trip with StringDtype (GH
    60663)

OBS-URL: https://build.opensuse.org/request/show/1292272
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-pandas?expand=0&rev=77
This commit is contained in:
2025-07-15 14:42:43 +00:00
committed by Git OBS Bridge
9 changed files with 149 additions and 421 deletions

View File

@@ -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.3.1</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">v(.*)</param>
<param name="filename">pandas</param>

View File

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

3
pandas-2.3.1.tar.gz Normal file
View File

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

View File

@@ -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)

View File

@@ -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"])

View File

@@ -22,10 +22,10 @@ Subject: [PATCH] BUG: .mode(dropna=False) doesn't work with nullable integers
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
Index: pandas-2.3.1/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
--- pandas-2.3.1.orig/pandas/_libs/hashtable_func_helper.pxi.in
+++ pandas-2.3.1/pandas/_libs/hashtable_func_helper.pxi.in
@@ -443,7 +443,7 @@ def mode(ndarray[htfunc_t] values, bint
if na_counter > 0:
@@ -35,10 +35,10 @@ Index: pandas-2.2.3/pandas/_libs/hashtable_func_helper.pxi.in
return modes[:j + 1], res_mask
Index: pandas-2.2.3/pandas/core/algorithms.py
Index: pandas-2.3.1/pandas/core/algorithms.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/algorithms.py
+++ pandas-2.2.3/pandas/core/algorithms.py
--- pandas-2.3.1.orig/pandas/core/algorithms.py
+++ pandas-2.3.1/pandas/core/algorithms.py
@@ -1022,7 +1022,7 @@ def duplicated(
def mode(
@@ -69,7 +69,7 @@ Index: pandas-2.2.3/pandas/core/algorithms.py
+ return npresult, res_mask
try:
npresult = np.sort(npresult)
npresult = safe_sort(npresult)
@@ -1061,7 +1063,7 @@ def mode(
)
@@ -79,10 +79,10 @@ Index: pandas-2.2.3/pandas/core/algorithms.py
def rank(
Index: pandas-2.2.3/pandas/core/arrays/base.py
Index: pandas-2.3.1/pandas/core/arrays/base.py
===================================================================
--- pandas-2.2.3.orig/pandas/core/arrays/base.py
+++ pandas-2.2.3/pandas/core/arrays/base.py
--- pandas-2.3.1.orig/pandas/core/arrays/base.py
+++ pandas-2.3.1/pandas/core/arrays/base.py
@@ -2270,8 +2270,9 @@ class ExtensionArray:
Sorted, if possible.
"""
@@ -95,11 +95,11 @@ Index: pandas-2.2.3/pandas/core/arrays/base.py
def __array_ufunc__(self, ufunc: np.ufunc, method: str, *inputs, **kwargs):
if any(
Index: pandas-2.2.3/pandas/core/arrays/categorical.py
Index: pandas-2.3.1/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
--- pandas-2.3.1.orig/pandas/core/arrays/categorical.py
+++ pandas-2.3.1/pandas/core/arrays/categorical.py
@@ -2459,7 +2459,7 @@ class Categorical(NDArrayBackedExtension
if dropna:
mask = self.isna()
@@ -108,11 +108,11 @@ Index: pandas-2.2.3/pandas/core/arrays/categorical.py
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
Index: pandas-2.3.1/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
--- pandas-2.3.1.orig/pandas/core/arrays/datetimelike.py
+++ pandas-2.3.1/pandas/core/arrays/datetimelike.py
@@ -1669,7 +1669,7 @@ class DatetimeLikeArrayMixin( # type: i
if dropna:
mask = self.isna()
@@ -121,11 +121,11 @@ Index: pandas-2.2.3/pandas/core/arrays/datetimelike.py
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
Index: pandas-2.3.1/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
--- pandas-2.3.1.orig/pandas/core/arrays/masked.py
+++ pandas-2.3.1/pandas/core/arrays/masked.py
@@ -1124,12 +1124,8 @@ class BaseMaskedArray(OpsMixin, Extensio
return Series(arr, index=index, name="count", copy=False)
def _mode(self, dropna: bool = True) -> Self:
@@ -140,11 +140,11 @@ Index: pandas-2.2.3/pandas/core/arrays/masked.py
return result[result.argsort()]
@doc(ExtensionArray.equals)
Index: pandas-2.2.3/pandas/core/series.py
Index: pandas-2.3.1/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
--- pandas-2.3.1.orig/pandas/core/series.py
+++ pandas-2.3.1/pandas/core/series.py
@@ -2337,7 +2337,7 @@ class Series(base.IndexOpsMixin, NDFrame
# TODO: Add option for bins like value_counts()
values = self._values
if isinstance(values, np.ndarray):
@@ -153,10 +153,10 @@ Index: pandas-2.2.3/pandas/core/series.py
else:
res_values = values._mode(dropna=dropna)
Index: pandas-2.2.3/pandas/tests/series/test_reductions.py
Index: pandas-2.3.1/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
--- pandas-2.3.1.orig/pandas/tests/series/test_reductions.py
+++ pandas-2.3.1/pandas/tests/series/test_reductions.py
@@ -51,6 +51,29 @@ def test_mode_nullable_dtype(any_numeric
tm.assert_series_equal(result, expected)
@@ -187,11 +187,11 @@ Index: pandas-2.2.3/pandas/tests/series/test_reductions.py
def test_mode_infer_string():
# GH#56183
pytest.importorskip("pyarrow")
Index: pandas-2.2.3/pandas/tests/test_algos.py
Index: pandas-2.3.1/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:
--- pandas-2.3.1.orig/pandas/tests/test_algos.py
+++ pandas-2.3.1/pandas/tests/test_algos.py
@@ -1855,7 +1855,8 @@ class TestRank:
class TestMode:
def test_no_mode(self):
exp = Series([], dtype=np.float64, index=Index([], dtype=int))
@@ -201,7 +201,7 @@ Index: pandas-2.2.3/pandas/tests/test_algos.py
@pytest.mark.parametrize("dt", np.typecodes["AllInteger"] + np.typecodes["Float"])
def test_mode_single(self, dt):
@@ -1853,20 +1854,24 @@ class TestMode:
@@ -1868,20 +1869,24 @@ class TestMode:
ser = Series(data_single, dtype=dt)
exp = Series(exp_single, dtype=dt)
@@ -230,7 +230,7 @@ Index: pandas-2.2.3/pandas/tests/test_algos.py
@pytest.mark.parametrize("dt", np.typecodes["AllInteger"] + np.typecodes["Float"])
def test_number_mode(self, dt):
@@ -1878,12 +1883,14 @@ class TestMode:
@@ -1893,12 +1898,14 @@ class TestMode:
ser = Series(data_single, dtype=dt)
exp = Series(exp_single, dtype=dt)
@@ -247,7 +247,7 @@ Index: pandas-2.2.3/pandas/tests/test_algos.py
tm.assert_series_equal(ser.mode(), exp)
def test_strobj_mode(self):
@@ -1892,7 +1899,8 @@ class TestMode:
@@ -1907,7 +1914,8 @@ class TestMode:
ser = Series(data, dtype="c")
exp = Series(exp, dtype="c")
@@ -257,17 +257,17 @@ Index: pandas-2.2.3/pandas/tests/test_algos.py
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)
@@ -1920,7 +1928,8 @@ class TestMode:
if using_infer_string and dt is str:
tm.assert_extension_array_equal(algos.mode(ser.values), exp.values)
else:
- 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:
@@ -1954,18 +1963,21 @@ class TestMode:
def test_mixed_dtype(self):
exp = Series(["foo"], dtype=object)
ser = Series([1, "foo", "foo"])
@@ -292,7 +292,7 @@ Index: pandas-2.2.3/pandas/tests/test_algos.py
tm.assert_series_equal(ser.mode(), exp)
def test_categorical(self):
@@ -1969,15 +1981,18 @@ class TestMode:
@@ -1987,15 +1999,18 @@ class TestMode:
def test_index(self):
idx = Index([1, 2, 3])
exp = Series([1, 2, 3], dtype=np.int64)

View File

@@ -1,3 +1,94 @@
-------------------------------------------------------------------
Fri Jul 11 19:29:45 UTC 2025 - Ben Greiner <code@bnavigator.de>
- Update to 2.3.1
* This release includes some improvements and fixes to the future
string data type (preview feature for the upcoming pandas 3.0)
## Improvements and fixes for the StringDtype
* Comparisons between different string dtypes
* Index set operations ignore empty RangeIndex and object dtype
Index
## Bug fixes
* Bug in DataFrameGroupBy.min(), DataFrameGroupBy.max(),
Resampler.min(), Resampler.max() where all NA values of string
dtype would return float instead of string dtype (GH 60810)
* Bug in DataFrame.join() incorrectly downcasting object-dtype
indexes (GH 61771)
* Bug in DataFrame.sum() with axis=1, DataFrameGroupBy.sum() or
SeriesGroupBy.sum() with skipna=True, and Resampler.sum() with
all NA values of StringDtype resulted in 0 instead of the empty
string "" (GH 60229)
* Fixed bug in DataFrame.explode() and Series.explode() where
methods would fail with dtype="str" (GH 61623)
* Fixed bug in unpickling objects pickled in pandas versions
pre-2.3.0 that used StringDtype (GH 61763)
- Release 2.3.0
## Enhancements
* The semantics for the copy keyword in __array__ methods (i.e.
called when using np.array() or np.asarray() on pandas objects)
has been updated to work correctly with NumPy >= 2 (GH 57739)
* Series.str.decode() result now has StringDtype when
future.infer_string is True (GH 60709)
* to_hdf() and to_hdf() now round-trip with StringDtype (GH
60663)
* Improved repr of NumpyExtensionArray to account for NEP51 (GH
61085)
* The Series.str.decode() has gained the argument dtype to
control the dtype of the result (GH 60940)
* The cumsum(), cummin(), and cummax() reductions are now
implemented for StringDtype columns (GH 60633)
* The sum() reduction is now implemented for StringDtype columns
(GH 59853)
## Deprecations
* Deprecated allowing non-bool values for na in str.contains(),
str.startswith(), and str.endswith() for dtypes that do not
already disallow these (GH 59615)
* Deprecated the "pyarrow_numpy" storage option for StringDtype
(GH 60152)
* The deprecation of setting the argument include_groups to True
in DataFrameGroupBy.apply() has been promoted from a
DeprecationWarning to FutureWarning; only False will be allowed
(GH 7155)
## Bug fixes
### Numeric
* Bug in Series.mode() and DataFrame.mode() with dropna=False
where not all dtypes would sort in the presence of NA values
(GH 60702)
* Bug in Series.round() where a TypeError would always raise with
object dtype (GH 61206)
### Strings
* Bug in Series.__pos__() and DataFrame.__pos__() where an
Exception was not raised for StringDtype with storage="pyarrow"
(GH 60710)
* Bug in Series.rank() for StringDtype with storage="pyarrow"
that incorrectly returned integer results with method="average"
and raised an error if it would truncate results (GH 59768)
* Bug in Series.replace() with StringDtype when replacing with a
non-string value was not upcasting to object dtype (GH 60282)
* Bug in Series.str.center() with StringDtype with
storage="pyarrow" not matching the python behavior in corner
cases with an odd number of fill characters (GH 54792)
* Bug in Series.str.replace() when n < 0 for StringDtype with
storage="pyarrow" (GH 59628)
* Bug in Series.str.slice() with negative step with ArrowDtype
and StringDtype with storage="pyarrow" giving incorrect results
(GH 59710)
### Indexing
Bug in Index.get_indexer() round-tripping through string dtype
when infer_string is enabled (GH 55834)
### I/O
* Bug in DataFrame.to_excel() which stored decimals as strings
instead of numbers (GH 49598)
### Other
* Fixed usage of inspect when the optional dependencies pyarrow
or jinja2 are not installed (GH 60196)
- Drop patches:
* timedelta.patch
* pandas-pr60545-arrow-exception.patch
* pandas-pr60584-60586-mpl-vert.patch
- Refresh dropna.patch to pandas-pr61132-dropna.patch
* gh#pandas-dev/pandas#61132
-------------------------------------------------------------------
Thu Mar 20 11:36:22 UTC 2025 - Markéta Machová <mmachova@suse.com>

View File

@@ -37,7 +37,7 @@
%if "%{flavor}" != "test-py313"
%define skip_python313 1
%endif
# Skip empty buildsets, last one is for sle15_python_module_pythons
# Skip empty buildsets on tumbleweed or flavors other than python311 on leap with sle15_python_module_pythons
%if "%{shrink:%{pythons}}" == "" || ("%pythons" == "python311" && 0%{?skip_python311})
ExclusiveArch: donotbuild
%define python_module() %flavor-not-enabled-in-buildset-for-suse-%{?suse_version}
@@ -64,7 +64,7 @@ ExclusiveArch: donotbuild
%endif
Name: python-pandas%{psuffix}
# Set version through _service
Version: 2.2.3
Version: 2.3.1
Release: 0
Summary: Python data structures for data analysis, time series, and statistics
License: BSD-3-Clause
@@ -72,14 +72,8 @@ 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-pr61132-dropna.patch gh#pandas-dev/pandas#61132 BUG: .mode(dropna=False) doesn't work with nullable integers
Patch1: pandas-pr61132-dropna.patch
%if !%{with test}
BuildRequires: %{python_module Cython >= 3.0.5}
BuildRequires: %{python_module devel >= 3.9}
@@ -91,7 +85,7 @@ BuildRequires: %{python_module wheel}
BuildRequires: fdupes
BuildRequires: gcc%{?gccver}-c++
BuildRequires: git-core
BuildRequires: meson >= 1.2.1
BuildRequires: (meson >= 1.2.1 with meson < 2)
%endif
BuildRequires: python-rpm-macros
Requires: python-python-dateutil >= 2.8.2
@@ -518,21 +512,15 @@ 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"
%if "%{flavor}" == "test-py312" || "%{flavor}" == "test-py313"
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
# 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 3.0
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)"
# xpass strict: our xarray seems to handle this fine
SKIP_TESTS+=" or (TestSeriesToXArray and test_to_xarray_index_types)"
%ifarch %{ix86} %{arm32}
# https://github.com/pandas-dev/pandas/issues/31856
SKIP_TESTS+=" or test_maybe_promote_int_with_int"

View File

@@ -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)