diff --git a/.binder/environment.yml b/.binder/environment.yml
index a60eb372831..2c57bd1121c 100644
--- a/.binder/environment.yml
+++ b/.binder/environment.yml
@@ -2,7 +2,7 @@ name: xarray-examples
channels:
- conda-forge
dependencies:
- - python=3.10
+ - python=3.11
- boto3
- bottleneck
- cartopy
diff --git a/.github/workflows/ci-additional.yaml b/.github/workflows/ci-additional.yaml
index 95181ae3761..345c7a8e234 100644
--- a/.github/workflows/ci-additional.yaml
+++ b/.github/workflows/ci-additional.yaml
@@ -132,7 +132,7 @@ jobs:
fail_ci_if_error: false
mypy-min:
- name: Mypy 3.10
+ name: Mypy 3.11
runs-on: "ubuntu-latest"
needs: detect-ci-trigger
defaults:
@@ -140,7 +140,7 @@ jobs:
shell: bash -l {0}
env:
CONDA_ENV_FILE: ci/requirements/environment.yml
- PYTHON_VERSION: "3.10"
+ PYTHON_VERSION: "3.11"
steps:
- uses: actions/checkout@v4
@@ -239,7 +239,7 @@ jobs:
fail_ci_if_error: false
pyright39:
- name: Pyright 3.10
+ name: Pyright 3.11
runs-on: "ubuntu-latest"
needs: detect-ci-trigger
if: |
@@ -252,7 +252,7 @@ jobs:
shell: bash -l {0}
env:
CONDA_ENV_FILE: ci/requirements/environment.yml
- PYTHON_VERSION: "3.10"
+ PYTHON_VERSION: "3.11"
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 76f4f0d5e7e..b115d605ee3 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -47,18 +47,18 @@ jobs:
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
# Bookend python versions
- python-version: ["3.10", "3.13"]
+ python-version: ["3.11", "3.13"]
env: [""]
include:
# Minimum python version:
- env: "bare-minimum"
- python-version: "3.10"
+ python-version: "3.11"
os: ubuntu-latest
- env: "bare-min-and-scipy"
- python-version: "3.10"
+ python-version: "3.11"
os: ubuntu-latest
- env: "min-all-deps"
- python-version: "3.10"
+ python-version: "3.11"
os: ubuntu-latest
# Latest python version:
- env: "all-but-numba"
@@ -73,7 +73,7 @@ jobs:
# The mypy tests must be executed using only 1 process in order to guarantee
# predictable mypy output messages for comparison to expectations.
- env: "mypy"
- python-version: "3.10"
+ python-version: "3.11"
numprocesses: 1
os: ubuntu-latest
- env: "mypy"
diff --git a/ci/requirements/all-but-numba.yml b/ci/requirements/all-but-numba.yml
index 7c492aec704..712055a0ec2 100644
--- a/ci/requirements/all-but-numba.yml
+++ b/ci/requirements/all-but-numba.yml
@@ -4,7 +4,7 @@ channels:
- nodefaults
dependencies:
# Pin a "very new numpy" (updated Sept 24, 2024)
- - numpy>=2.1.1
+ - numpy>=2.2
- aiobotocore
- array-api-strict<2.4
- boto3
diff --git a/ci/requirements/bare-min-and-scipy.yml b/ci/requirements/bare-min-and-scipy.yml
index 5e5522faaea..bb25af67651 100644
--- a/ci/requirements/bare-min-and-scipy.yml
+++ b/ci/requirements/bare-min-and-scipy.yml
@@ -3,7 +3,7 @@ channels:
- conda-forge
- nodefaults
dependencies:
- - python=3.10
+ - python=3.11
- coveralls
- pip
- pytest
@@ -12,7 +12,7 @@ dependencies:
- pytest-mypy-plugins
- pytest-timeout
- pytest-xdist
- - numpy=1.24
- - packaging=23.1
- - pandas=2.1
- - scipy=1.11
+ - numpy=1.26
+ - packaging=24.1
+ - pandas=2.2
+ - scipy=1.13
diff --git a/ci/requirements/bare-minimum.yml b/ci/requirements/bare-minimum.yml
index 02e99d34af2..fafc1aa034a 100644
--- a/ci/requirements/bare-minimum.yml
+++ b/ci/requirements/bare-minimum.yml
@@ -3,7 +3,7 @@ channels:
- conda-forge
- nodefaults
dependencies:
- - python=3.10
+ - python=3.11
- coveralls
- pip
- pytest
@@ -12,6 +12,6 @@ dependencies:
- pytest-mypy-plugins
- pytest-timeout
- pytest-xdist
- - numpy=1.24
- - packaging=23.1
- - pandas=2.1
+ - numpy=1.26
+ - packaging=24.1
+ - pandas=2.2
diff --git a/ci/requirements/doc.yml b/ci/requirements/doc.yml
index 0559f393bd0..64ea08b73ff 100644
--- a/ci/requirements/doc.yml
+++ b/ci/requirements/doc.yml
@@ -23,7 +23,7 @@ dependencies:
- ncdata
- netcdf4
- numba
- - numpy>=2
+ - numpy>=2.2
- packaging
- pandas
- pooch
diff --git a/ci/requirements/environment.yml b/ci/requirements/environment.yml
index fc54b6600fe..cc33d8b4681 100644
--- a/ci/requirements/environment.yml
+++ b/ci/requirements/environment.yml
@@ -26,7 +26,7 @@ dependencies:
- numba
- numbagg
- numexpr
- - numpy>=2
+ - numpy>=2.2
- opt_einsum
- packaging
- pandas
diff --git a/ci/requirements/min-all-deps.yml b/ci/requirements/min-all-deps.yml
index 03e14773d53..b7698c0abd3 100644
--- a/ci/requirements/min-all-deps.yml
+++ b/ci/requirements/min-all-deps.yml
@@ -7,40 +7,36 @@ dependencies:
# Run ci/min_deps_check.py to verify that this file respects the policy.
# When upgrading python, numpy, or pandas, must also change
# doc/user-guide/installing.rst, doc/user-guide/plotting.rst and setup.py.
- - python=3.10
- - array-api-strict=1.0 # dependency for testing the array api compat
- - boto3=1.29
- - bottleneck=1.3
- - cartopy=0.22
+ - python=3.11
+ - array-api-strict=1.1 # dependency for testing the array api compat
+ - boto3=1.34
+ - bottleneck=1.4
+ - cartopy=0.23
- cftime=1.6
- coveralls
- - dask-core=2023.11
- - distributed=2023.11
- # Flox > 0.8 has a bug with numbagg versions
- # It will require numbagg > 0.6
- # so we should just skip that series eventually
- # or keep flox pinned for longer than necessary
- - flox=0.7
+ - dask-core=2024.6
+ - distributed=2024.6
+ - flox=0.9
- h5netcdf=1.3
# h5py and hdf5 tend to cause conflicts
# for e.g. hdf5 1.12 conflicts with h5py=3.1
# prioritize bumping other packages instead
- - h5py=3.8
- - hdf5=1.12
+ - h5py=3.11
+ - hdf5=1.14
- hypothesis
- - iris=3.7
- - lxml=4.9 # Optional dep of pydap
+ - iris=3.9
+ - lxml=5.1 # Optional dep of pydap
- matplotlib-base=3.8
- nc-time-axis=1.4
# netcdf follows a 1.major.minor[.patch] convention
# (see https://github.com/Unidata/netcdf4-python/issues/1090)
- - netcdf4=1.6.0
- - numba=0.57
- - numbagg=0.6
- - numpy=1.24
- - packaging=23.2
- - pandas=2.1
- - pint=0.22
+ - netcdf4=1.6
+ - numba=0.60
+ - numbagg=0.8
+ - numpy=1.26
+ - packaging=24.1
+ - pandas=2.2
+ - pint=0.24
- pip
- pydap=3.5
- pytest
@@ -50,9 +46,8 @@ dependencies:
- pytest-timeout
- pytest-xdist
- rasterio=1.3
- - scipy=1.11
+ - scipy=1.13
- seaborn=0.13
- - sparse=0.14
+ - sparse=0.15
- toolz=0.12
- - typing_extensions=4.8
- - zarr=2.16
+ - zarr=2.18
diff --git a/doc/contribute/contributing.rst b/doc/contribute/contributing.rst
index e0ece730cd1..339050a7f8a 100644
--- a/doc/contribute/contributing.rst
+++ b/doc/contribute/contributing.rst
@@ -290,7 +290,7 @@ We'll now kick off a two-step process:
.. code-block:: sh
# Create and activate the build environment
- conda create -c conda-forge -n xarray-tests python=3.10
+ conda create -c conda-forge -n xarray-tests python=3.11
# This is for Linux and MacOS
conda env update -f ci/requirements/environment.yml
diff --git a/doc/getting-started-guide/installing.rst b/doc/getting-started-guide/installing.rst
index 4910047014e..cca54585c5f 100644
--- a/doc/getting-started-guide/installing.rst
+++ b/doc/getting-started-guide/installing.rst
@@ -6,10 +6,10 @@ Installation
Required dependencies
---------------------
-- Python (3.10 or later)
-- `numpy `__ (1.23 or later)
-- `packaging `__ (23.1 or later)
-- `pandas `__ (2.0 or later)
+- Python (3.11 or later)
+- `numpy `__ (1.26 or later)
+- `packaging `__ (24.1 or later)
+- `pandas `__ (2.2 or later)
.. _optional-dependencies:
diff --git a/doc/whats-new.rst b/doc/whats-new.rst
index 607661ed30b..140487185ee 100644
--- a/doc/whats-new.rst
+++ b/doc/whats-new.rst
@@ -13,10 +13,91 @@ v2025.07.0 (unreleased)
New Features
~~~~~~~~~~~~
-
Breaking changes
~~~~~~~~~~~~~~~~
+The minimum versions of some dependencies were changed (:issue:`10417`, :pull:`10438`):
+By `Dhruva Kumar Kaushal `_.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 20 20
+
+ * - Dependency
+ - Old Version
+ - New Version
+ * - Python
+ - 3.10
+ - 3.11
+ * - array-api-strict
+ - 1.0
+ - 1.1
+ * - boto3
+ - 1.29
+ - 1.34
+ * - bottleneck
+ - 1.3
+ - 1.4
+ * - cartopy
+ - 0.22
+ - 0.23
+ * - dask-core
+ - 2023.11
+ - 2024.6
+ * - distributed
+ - 2023.11
+ - 2024.6
+ * - flox
+ - 0.7
+ - 0.9
+ * - h5py
+ - 3.8
+ - 3.11
+ * - hdf5
+ - 1.12
+ - 1.14
+ * - iris
+ - 3.7
+ - 3.9
+ * - lxml
+ - 4.9
+ - 5.1
+ * - matplotlib-base
+ - 3.7
+ - 3.8
+ * - numba
+ - 0.57
+ - 0.60
+ * - numbagg
+ - 0.6
+ - 0.8
+ * - numpy
+ - 1.24
+ - 1.26
+ * - packaging
+ - 23.2
+ - 24.1
+ * - pandas
+ - 2.1
+ - 2.2
+ * - pint
+ - 0.22
+ - 0.24
+ * - pydap
+ - N/A
+ - 3.5
+ * - scipy
+ - 1.11
+ - 1.13
+ * - sparse
+ - 0.14
+ - 0.15
+ * - typing_extensions
+ - 4.8
+ - Removed
+ * - zarr
+ - 2.16
+ - 2.18
Deprecations
~~~~~~~~~~~~
diff --git a/pyproject.toml b/pyproject.toml
index c980c204b5f..0c1e9fb25f4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,6 @@ classifiers = [
"Intended Audience :: Science/Research",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
@@ -17,9 +16,9 @@ dynamic = ["version"]
license = "Apache-2.0"
name = "xarray"
readme = "README.md"
-requires-python = ">=3.10"
+requires-python = ">=3.11"
-dependencies = ["numpy>=1.24", "packaging>=23.2", "pandas>=2.1"]
+dependencies = ["numpy>=1.26", "packaging>=24.1", "pandas>=2.2"]
# We don't encode minimum requirements here (though if we can write a script to
# generate the text from `min_deps_check.py`, that's welcome...). We do add
@@ -27,21 +26,28 @@ dependencies = ["numpy>=1.24", "packaging>=23.2", "pandas>=2.1"]
# note that it's not a direct dependency of xarray.
[project.optional-dependencies]
-accel = ["scipy", "bottleneck", "numbagg", "numba>=0.54", "flox", "opt_einsum"]
+accel = [
+ "scipy>=1.13",
+ "bottleneck",
+ "numbagg>=0.8",
+ "numba>=0.59",
+ "flox>=0.9",
+ "opt_einsum",
+]
complete = ["xarray[accel,etc,io,parallel,viz]"]
io = [
- "netCDF4",
+ "netCDF4>=1.6.0",
"h5netcdf",
- "scipy",
- 'pydap; python_version<"3.10"',
- "zarr",
+ "pydap",
+ "scipy>=1.13",
+ "zarr>=2.18",
"fsspec",
"cftime",
"pooch",
]
-etc = ["sparse"]
+etc = ["sparse>=0.15"]
parallel = ["dask[complete]"]
-viz = ["cartopy", "matplotlib", "nc-time-axis", "seaborn"]
+viz = ["cartopy>=0.23", "matplotlib", "nc-time-axis", "seaborn"]
types = [
"pandas-stubs",
"scipy-stubs",
diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py
index c78b38caf63..86e875cab5c 100644
--- a/xarray/core/accessor_dt.py
+++ b/xarray/core/accessor_dt.py
@@ -20,7 +20,7 @@
from xarray.namedarray.utils import is_duck_dask_array
if TYPE_CHECKING:
- import sys
+ from typing import Self
from numpy.typing import DTypeLike
@@ -28,11 +28,6 @@
from xarray.core.dataset import Dataset
from xarray.core.types import CFCalendar
- if sys.version_info >= (3, 11):
- from typing import Self
- else:
- from typing_extensions import Self
-
def _season_from_months(months):
"""Compute season (DJF, MAM, JJA, SON) from month ordinal"""
diff --git a/xarray/core/datatree_mapping.py b/xarray/core/datatree_mapping.py
index 6262c7f19cd..00e575ef448 100644
--- a/xarray/core/datatree_mapping.py
+++ b/xarray/core/datatree_mapping.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import sys
from collections.abc import Callable, Mapping
from typing import TYPE_CHECKING, Any, cast, overload
@@ -162,11 +161,7 @@ def wrapper(*args, **kwargs):
def add_note(err: BaseException, msg: str) -> None:
- # TODO: remove once python 3.10 can be dropped
- if sys.version_info < (3, 11):
- err.__notes__ = getattr(err, "__notes__", []) + [msg] # type: ignore[attr-defined]
- else:
- err.add_note(msg)
+ err.add_note(msg)
def _check_single_set_return_values(path_to_node: str, obj: Any) -> int | None:
diff --git a/xarray/core/types.py b/xarray/core/types.py
index 2124aee0ad4..d3fd0180104 100644
--- a/xarray/core/types.py
+++ b/xarray/core/types.py
@@ -1,7 +1,6 @@
from __future__ import annotations
import datetime
-import sys
from collections.abc import Callable, Collection, Hashable, Iterator, Mapping, Sequence
from types import EllipsisType
from typing import (
@@ -9,7 +8,9 @@
Any,
Literal,
Protocol,
+ Self,
SupportsIndex,
+ TypeAlias,
TypeVar,
Union,
overload,
@@ -18,21 +19,6 @@
import numpy as np
import pandas as pd
-
-try:
- if sys.version_info >= (3, 11):
- from typing import Self, TypeAlias
- else:
- from typing import TypeAlias
-
- from typing_extensions import Self
-except ImportError:
- if TYPE_CHECKING:
- raise
- else:
- Self: Any = None
-
-
from numpy._typing import _SupportsDType
from numpy.typing import ArrayLike
diff --git a/xarray/namedarray/_typing.py b/xarray/namedarray/_typing.py
index 2dba06a5d44..635adc89f08 100644
--- a/xarray/namedarray/_typing.py
+++ b/xarray/namedarray/_typing.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import sys
from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence
from enum import Enum
from types import EllipsisType, ModuleType
@@ -20,10 +19,7 @@
import numpy as np
try:
- if sys.version_info >= (3, 11):
- from typing import TypeAlias
- else:
- from typing import TypeAlias
+ from typing import TypeAlias
except ImportError:
if TYPE_CHECKING:
raise
diff --git a/xarray/namedarray/core.py b/xarray/namedarray/core.py
index 9d5b058439e..dac8162ca45 100644
--- a/xarray/namedarray/core.py
+++ b/xarray/namedarray/core.py
@@ -2,7 +2,6 @@
import copy
import math
-import sys
import warnings
from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence
from itertools import starmap
@@ -86,10 +85,7 @@
PostComputeCallable: Any # type: ignore[no-redef]
PostPersistCallable: Any # type: ignore[no-redef]
- if sys.version_info >= (3, 11):
- from typing import Self
- else:
- from typing_extensions import Self
+ from typing import Self
T_NamedArray = TypeVar("T_NamedArray", bound="_NamedArray[Any]")
T_NamedArrayInteger = TypeVar(
diff --git a/xarray/util/generate_ops.py b/xarray/util/generate_ops.py
index 3300bbf594a..0c5ac2f2eb8 100644
--- a/xarray/util/generate_ops.py
+++ b/xarray/util/generate_ops.py
@@ -133,7 +133,7 @@ def {{ method }}(self, *args: Any, **kwargs: Any) -> Self:
# We require a "hack" to tell type checkers that e.g. Variable + DataArray = DataArray
# In reality this returns NotImplemented, but this is not a valid type in python 3.9.
# Therefore, we return DataArray. In reality this would call DataArray.__add__(Variable)
-# TODO: change once python 3.10 is the minimum.
+# TODO: change once python 3.11 is the minimum.
#
# Mypy seems to require that __iadd__ and __add__ have the same signature.
# This requires some extra type: ignores[misc] in the inplace methods :/