From ba403996b2b351264c7392526a3d89244c990051 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 6 Apr 2025 13:19:06 +0800 Subject: [PATCH 1/2] SPEC 0: Bump minimum supported version to pandas>=2.1 --- .github/workflows/ci_tests.yaml | 2 +- environment.yml | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci_tests.yaml b/.github/workflows/ci_tests.yaml index e2524889b1c..1beb45768c8 100644 --- a/.github/workflows/ci_tests.yaml +++ b/.github/workflows/ci_tests.yaml @@ -73,7 +73,7 @@ jobs: # Python 3.11 + core packages (minimum supported versions) + optional packages (minimum supported versions if any) - python-version: '3.11' numpy-version: '1.25' - pandas-version: '=2.0' + pandas-version: '=2.1' xarray-version: '=2023.04' optional-packages: ' contextily geopandas<1 ipython pyarrow-core rioxarray sphinx-gallery' # Python 3.13 + core packages (latest versions) + optional packages diff --git a/environment.yml b/environment.yml index bc18bcaaae6..dbfce7afc96 100644 --- a/environment.yml +++ b/environment.yml @@ -8,7 +8,7 @@ dependencies: - gmt=6.5.0 - ghostscript=10.04.0 - numpy>=1.25 - - pandas>=2.0 + - pandas>=2.1 - xarray>=2023.04 - netCDF4 - packaging diff --git a/pyproject.toml b/pyproject.toml index 89f9d907bad..8d613df7022 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ classifiers = [ ] dependencies = [ "numpy>=1.25", - "pandas>=2.0", + "pandas>=2.1", "xarray>=2023.04", "netCDF4", "packaging", diff --git a/requirements.txt b/requirements.txt index 61f6282dc7d..26eb08060a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ # Required packages numpy>=1.25 -pandas>=2.0 +pandas>=2.1 xarray>=2023.04 netCDF4 packaging From 7cc02bf4e0128d4c6bd34911fb395cb0460c41c1 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 6 Apr 2025 13:19:31 +0800 Subject: [PATCH 2/2] Remove compatibility codes with pandas<2.1 --- pygmt/clib/conversion.py | 4 ---- pygmt/tests/test_clib_to_numpy.py | 19 ++----------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/pygmt/clib/conversion.py b/pygmt/clib/conversion.py index c23ea22b9d9..c7d713647ef 100644 --- a/pygmt/clib/conversion.py +++ b/pygmt/clib/conversion.py @@ -198,10 +198,6 @@ def _to_numpy(data: Any) -> np.ndarray: elif isinstance(dtype, pd.ArrowDtype) and hasattr(dtype.pyarrow_dtype, "tz"): # pd.ArrowDtype[pa.Timestamp] numpy_dtype = getattr(dtype, "numpy_dtype", None) - # TODO(pandas>=2.1): Remove the workaround for pandas<2.1. - if Version(pd.__version__) < Version("2.1"): - # In pandas 2.0, dtype.numpy_type is dtype("O"). - numpy_dtype = np.dtype(f"M8[{dtype.pyarrow_dtype.unit}]") # type: ignore[assignment, attr-defined] array = np.ascontiguousarray(data, dtype=numpy_dtype) diff --git a/pygmt/tests/test_clib_to_numpy.py b/pygmt/tests/test_clib_to_numpy.py index 95bfcb3aaa8..29efc245d30 100644 --- a/pygmt/tests/test_clib_to_numpy.py +++ b/pygmt/tests/test_clib_to_numpy.py @@ -391,17 +391,7 @@ def test_to_numpy_pandas_numeric_with_na(dtype, expected_dtype): "U10", "string[python]", pytest.param("string[pyarrow]", marks=skip_if_no(package="pyarrow")), - pytest.param( - "string[pyarrow_numpy]", - marks=[ - skip_if_no(package="pyarrow"), - # TODO(pandas>=2.1): Remove the skipif marker for pandas<2.1. - pytest.mark.skipif( - Version(pd.__version__) < Version("2.1"), - reason="string[pyarrow_numpy] was added since pandas 2.1", - ), - ], - ), + pytest.param("string[pyarrow_numpy]", marks=skip_if_no(package="pyarrow")), ], ) def test_to_numpy_pandas_string(dtype): @@ -536,12 +526,7 @@ def test_to_numpy_pandas_datetime(dtype, expected_dtype): # Convert to UTC if the dtype is timezone-aware if "," in str(dtype): # A hacky way to decide if the dtype is timezone-aware. - # TODO(pandas>=2.1): Simplify the if-else statement. - if Version(pd.__version__) < Version("2.1") and dtype.startswith("timestamp"): - # pandas 2.0 doesn't have the dt.tz_convert method for pyarrow.Timestamp. - series = pd.to_datetime(series, utc=True) - else: - series = series.dt.tz_convert("UTC") + series = series.dt.tz_convert("UTC") # Remove time zone information and preserve local time. expected_series = series.dt.tz_localize(tz=None) npt.assert_array_equal(result, np.array(expected_series, dtype=expected_dtype))