From db2f895082a7d4de7a1e62134cfa969e4bb67040 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 3 Jul 2024 00:13:48 -0400 Subject: [PATCH] Bump minimum Python to 3.10 --- .circleci/config.yml | 6 ++-- .github/workflows/cibuildwheel.yml | 14 ++------- .github/workflows/circleci.yml | 6 ++-- .github/workflows/cygwin.yml | 6 ++-- .github/workflows/mypy-stubtest.yml | 4 +-- .github/workflows/reviewdog.yml | 4 +-- .github/workflows/tests.yml | 31 +++++++++---------- azure-pipelines.yml | 13 ++------ .../next_api_changes/development/28503-ES.rst | 14 +++++++++ doc/devel/testing.rst | 4 +-- doc/install/dependencies.rst | 4 +-- doc/install/index.rst | 4 +-- environment.yml | 1 + galleries/users_explain/customizing.py | 4 +-- lib/matplotlib/_api/__init__.pyi | 4 +-- lib/matplotlib/_api/deprecation.pyi | 3 +- lib/matplotlib/axis.pyi | 4 +-- lib/matplotlib/backends/registry.py | 10 ++---- lib/matplotlib/dviread.pyi | 7 ++--- lib/matplotlib/sankey.pyi | 4 +-- lib/matplotlib/style/core.py | 12 ++----- lib/matplotlib/tests/test_backend_inline.py | 2 -- lib/matplotlib/tests/test_sphinxext.py | 3 +- pyproject.toml | 6 ++-- requirements/testing/extra.txt | 2 +- requirements/testing/minver.txt | 4 +-- requirements/testing/mypy.txt | 2 -- tools/boilerplate.py | 24 +------------- tox.ini | 2 +- 29 files changed, 77 insertions(+), 127 deletions(-) create mode 100644 doc/api/next_api_changes/development/28503-ES.rst diff --git a/.circleci/config.yml b/.circleci/config.yml index 5b4cbf5570b8..7436698c8068 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -216,9 +216,9 @@ commands: # jobs: - docs-python39: + docs-python310: docker: - - image: cimg/python:3.9 + - image: cimg/python:3.10 resource_class: large steps: - checkout @@ -259,4 +259,4 @@ workflows: jobs: # NOTE: If you rename this job, then you must update the `if` condition # and `circleci-jobs` option in `.github/workflows/circleci.yml`. - - docs-python39 + - docs-python310 diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml index 050ff16cfbbd..50adc91980de 100644 --- a/.github/workflows/cibuildwheel.yml +++ b/.github/workflows/cibuildwheel.yml @@ -46,7 +46,7 @@ jobs: - uses: actions/setup-python@v5 name: Install Python with: - python-version: 3.9 + python-version: '3.10' # Something changed somewhere that prevents the downloaded-at-build-time # licenses from being included in built wheels, so pre-download them so @@ -158,22 +158,14 @@ jobs: CIBW_BUILD: "cp310-*" CIBW_ARCHS: ${{ matrix.cibw_archs }} - - name: Build wheels for CPython 3.9 - uses: pypa/cibuildwheel@7e5a838a63ac8128d71ab2dfd99e4634dd1bca09 # v2.19.2 - with: - package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} - env: - CIBW_BUILD: "cp39-*" - CIBW_ARCHS: ${{ matrix.cibw_archs }} - - name: Build wheels for PyPy uses: pypa/cibuildwheel@7e5a838a63ac8128d71ab2dfd99e4634dd1bca09 # v2.19.2 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: - CIBW_BUILD: "pp39-*" + CIBW_BUILD: "pp310-*" CIBW_ARCHS: ${{ matrix.cibw_archs }} - if: matrix.cibw_archs != 'aarch64' + if: matrix.cibw_archs != 'aarch64' && matrix.os != 'windows-latest' - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/circleci.yml b/.github/workflows/circleci.yml index 3aead720cf20..c96dbecda7a1 100644 --- a/.github/workflows/circleci.yml +++ b/.github/workflows/circleci.yml @@ -3,7 +3,7 @@ name: "CircleCI artifact handling" on: [status] jobs: circleci_artifacts_redirector_job: - if: "${{ github.event.context == 'ci/circleci: docs-python39' }}" + if: "${{ github.event.context == 'ci/circleci: docs-python310' }}" permissions: statuses: write runs-on: ubuntu-latest @@ -16,11 +16,11 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} api-token: ${{ secrets.CIRCLECI_TOKEN }} artifact-path: 0/doc/build/html/index.html - circleci-jobs: docs-python39 + circleci-jobs: docs-python310 job-title: View the built docs post_warnings_as_review: - if: "${{ github.event.context == 'ci/circleci: docs-python39' }}" + if: "${{ github.event.context == 'ci/circleci: docs-python310' }}" permissions: contents: read checks: write diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index 58c132315b6f..b8bb4400f2f3 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -49,10 +49,12 @@ jobs: test-cygwin: runs-on: windows-latest name: Python 3.${{ matrix.python-minor-version }} on Cygwin + # Enable these when Cygwin has Python 3.12. if: >- github.event_name == 'workflow_dispatch' || - github.event_name == 'schedule' || + (false && github.event_name == 'schedule') || ( + false && github.repository == 'matplotlib/matplotlib' && !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]') && @@ -72,7 +74,7 @@ jobs: ) strategy: matrix: - python-minor-version: [9] + python-minor-version: [12] steps: - name: Fix line endings diff --git a/.github/workflows/mypy-stubtest.yml b/.github/workflows/mypy-stubtest.yml index 969aacccad74..5b29a93b7533 100644 --- a/.github/workflows/mypy-stubtest.yml +++ b/.github/workflows/mypy-stubtest.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Python 3 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Set up reviewdog uses: reviewdog/action-setup@v1 @@ -30,7 +30,7 @@ jobs: run: | set -o pipefail tox -e stubtest | \ - sed -e "s!.tox/stubtest/lib/python3.9/site-packages!lib!g" | \ + sed -e "s!.tox/stubtest/lib/python3.10/site-packages!lib!g" | \ reviewdog \ -efm '%Eerror: %m' \ -efm '%CStub: in file %f:%l' \ diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index fbd724571d80..12b59d866e42 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Python 3 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install flake8 run: pip3 install -r requirements/testing/flake8.txt @@ -42,7 +42,7 @@ jobs: - name: Set up Python 3 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install mypy run: pip3 install -r requirements/testing/mypy.txt -r requirements/testing/all.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8875a38cc1bb..230c42c136d5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -50,31 +50,28 @@ jobs: include: - name-suffix: "(Minimum Versions)" os: ubuntu-20.04 - python-version: 3.9 + python-version: '3.10' extra-requirements: '-c requirements/testing/minver.txt' - pyqt5-ver: '==5.12.2 sip==5.0.0' # oldest versions with a Py3.9 wheel. - pyqt6-ver: '==6.1.0 PyQt6-Qt6==6.1.0' - pyside2-ver: '==5.15.1' # oldest version with working Py3.9 wheel. - pyside6-ver: '==6.0.0' delete-font-cache: true + # Oldest versions with Py3.10 wheels. + pyqt5-ver: '==5.15.5 sip==6.3.0' + pyqt6-ver: '==6.2.0 PyQt6-Qt6==6.2.0' + pyside2-ver: '==5.15.2.1' + pyside6-ver: '==6.2.0' - os: ubuntu-20.04 - python-version: 3.9 + python-version: '3.10' # One CI run tests ipython/matplotlib-inline before backend mapping moved to mpl - extra-requirements: '-r requirements/testing/extra.txt "ipython==7.19" "matplotlib-inline<0.1.7"' + extra-requirements: + -r requirements/testing/extra.txt + "ipython==7.29.0" + "ipykernel==5.5.6" + "matplotlib-inline<0.1.7" CFLAGS: "-fno-lto" # Ensure that disabling LTO works. # https://github.com/matplotlib/matplotlib/pull/26052#issuecomment-1574595954 # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html pyqt6-ver: '!=6.5.1,!=6.6.0' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' - - os: ubuntu-20.04 - python-version: '3.10' - extra-requirements: '-r requirements/testing/extra.txt' - # https://github.com/matplotlib/matplotlib/pull/26052#issuecomment-1574595954 - # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html - pyqt6-ver: '!=6.5.1,!=6.6.0' - # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 - pyside6-ver: '!=6.5.1' - os: ubuntu-22.04 python-version: '3.11' # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html @@ -88,8 +85,8 @@ jobs: pyqt6-ver: '!=6.6.0' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' - - os: macos-12 # This runnre is on Intel chips. - python-version: 3.9 + - os: macos-12 # This runner is on Intel chips. + python-version: '3.10' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' - os: macos-14 # This runner is on M1 (arm64) chips. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 91e653b033f2..35c95c3b1f94 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -49,29 +49,20 @@ stages: - job: Pytest strategy: matrix: - Linux_py39: - vmImage: 'ubuntu-20.04' # keep one job pinned to the oldest image - python.version: '3.9' Linux_py310: - vmImage: 'ubuntu-latest' + vmImage: 'ubuntu-20.04' # keep one job pinned to the oldest image python.version: '3.10' Linux_py311: vmImage: 'ubuntu-latest' python.version: '3.11' - macOS_py39: - vmImage: 'macOS-latest' - python.version: '3.9' macOS_py310: vmImage: 'macOS-latest' python.version: '3.10' macOS_py311: vmImage: 'macOS-latest' python.version: '3.11' - Windows_py39: - vmImage: 'windows-2019' # keep one job pinned to the oldest image - python.version: '3.9' Windows_py310: - vmImage: 'windows-latest' + vmImage: 'windows-2019' # keep one job pinned to the oldest image python.version: '3.10' Windows_py311: vmImage: 'windows-latest' diff --git a/doc/api/next_api_changes/development/28503-ES.rst b/doc/api/next_api_changes/development/28503-ES.rst new file mode 100644 index 000000000000..e9b109cb8515 --- /dev/null +++ b/doc/api/next_api_changes/development/28503-ES.rst @@ -0,0 +1,14 @@ +Increase to minimum supported versions of dependencies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For Matplotlib 3.10, the :ref:`minimum supported versions ` are +being bumped: + ++------------+-----------------+----------------+ +| Dependency | min in mpl3.9 | min in mpl3.10 | ++============+=================+================+ +| Python | 3.9 | 3.10 | ++------------+-----------------+----------------+ + +This is consistent with our :ref:`min_deps_policy` and `SPEC0 +`__ diff --git a/doc/devel/testing.rst b/doc/devel/testing.rst index 668d4bd56b83..72f787eca746 100644 --- a/doc/devel/testing.rst +++ b/doc/devel/testing.rst @@ -252,7 +252,7 @@ Using tox `Tox `_ is a tool for running tests against multiple Python environments, including multiple versions of Python -(e.g., 3.7, 3.8) and even different Python implementations altogether +(e.g., 3.10, 3.11) and even different Python implementations altogether (e.g., CPython, PyPy, Jython, etc.), as long as all these versions are available on your system's $PATH (consider using your system package manager, e.g. apt-get, yum, or Homebrew, to install them). @@ -269,7 +269,7 @@ You can also run tox on a subset of environments: .. code-block:: bash - $ tox -e py38,py39 + $ tox -e py310,py311 Tox processes everything serially so it can take a long time to test several environments. To speed it up, you might try using a new, diff --git a/doc/install/dependencies.rst b/doc/install/dependencies.rst index 8da22a16753b..3d921d2d10c9 100644 --- a/doc/install/dependencies.rst +++ b/doc/install/dependencies.rst @@ -20,7 +20,7 @@ When installing through a package manager like ``pip`` or ``conda``, the mandatory dependencies are automatically installed. This list is mainly for reference. -* `Python `_ (>= 3.9) +* `Python `_ (>= 3.10) * `contourpy `_ (>= 1.0.1) * `cycler `_ (>= 0.10.0) * `dateutil `_ (>= 2.7) @@ -30,8 +30,6 @@ reference. * `packaging `_ (>= 20.0) * `Pillow `_ (>= 8.0) * `pyparsing `_ (>= 2.3.1) -* `importlib-resources `_ - (>= 3.2.0; only required on Python < 3.10) .. _optional_dependencies: diff --git a/doc/install/index.rst b/doc/install/index.rst index 867e4600a77e..99ccc163a82e 100644 --- a/doc/install/index.rst +++ b/doc/install/index.rst @@ -267,9 +267,9 @@ at the Terminal.app command line:: You should see something like :: - 3.6.0 /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/__init__.py + 3.10.0 /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib/__init__.py -where ``3.6.0`` is the Matplotlib version you just installed, and the path +where ``3.10.0`` is the Matplotlib version you just installed, and the path following depends on whether you are using Python.org Python, Homebrew or Macports. If you see another version, or you get an error like :: diff --git a/environment.yml b/environment.yml index ccd5270e9149..264f02800690 100644 --- a/environment.yml +++ b/environment.yml @@ -24,6 +24,7 @@ dependencies: - pygobject - pyparsing>=2.3.1 - pyqt + - python>=3.10 - python-dateutil>=2.1 - setuptools_scm - wxpython diff --git a/galleries/users_explain/customizing.py b/galleries/users_explain/customizing.py index b0aaee03239e..05b75ba7d0a4 100644 --- a/galleries/users_explain/customizing.py +++ b/galleries/users_explain/customizing.py @@ -234,8 +234,8 @@ def plotting_function(): # # 4. :file:`{INSTALL}/matplotlib/mpl-data/matplotlibrc`, where # :file:`{INSTALL}` is something like -# :file:`/usr/lib/python3.9/site-packages` on Linux, and maybe -# :file:`C:\\Python39\\Lib\\site-packages` on Windows. Every time you +# :file:`/usr/lib/python3.10/site-packages` on Linux, and maybe +# :file:`C:\\Python310\\Lib\\site-packages` on Windows. Every time you # install matplotlib, this file will be overwritten, so if you want # your customizations to be saved, please move this file to your # user-specific matplotlib directory. diff --git a/lib/matplotlib/_api/__init__.pyi b/lib/matplotlib/_api/__init__.pyi index 4baff7cd804c..8dbef9528a82 100644 --- a/lib/matplotlib/_api/__init__.pyi +++ b/lib/matplotlib/_api/__init__.pyi @@ -1,5 +1,6 @@ from collections.abc import Callable, Generator, Mapping, Sequence from typing import Any, Iterable, TypeVar, overload +from typing_extensions import Self # < Py 3.11 from numpy.typing import NDArray @@ -25,9 +26,8 @@ class classproperty(Any): fdel: None = ..., doc: str | None = None, ): ... - # Replace return with Self when py3.9 is dropped @overload - def __get__(self, instance: None, owner: None) -> classproperty: ... + def __get__(self, instance: None, owner: None) -> Self: ... @overload def __get__(self, instance: object, owner: type[object]) -> Any: ... @property diff --git a/lib/matplotlib/_api/deprecation.pyi b/lib/matplotlib/_api/deprecation.pyi index 9619d1b484fc..d0d04d987410 100644 --- a/lib/matplotlib/_api/deprecation.pyi +++ b/lib/matplotlib/_api/deprecation.pyi @@ -1,8 +1,7 @@ from collections.abc import Callable import contextlib -from typing import Any, TypedDict, TypeVar, overload +from typing import Any, ParamSpec, TypedDict, TypeVar, overload from typing_extensions import ( - ParamSpec, # < Py 3.10 Unpack, # < Py 3.11 ) diff --git a/lib/matplotlib/axis.pyi b/lib/matplotlib/axis.pyi index e23ae381c338..8f69fe4039a8 100644 --- a/lib/matplotlib/axis.pyi +++ b/lib/matplotlib/axis.pyi @@ -1,6 +1,7 @@ from collections.abc import Callable, Iterable, Sequence import datetime from typing import Any, Literal, overload +from typing_extensions import Self # < Py 3.11 import numpy as np from numpy.typing import ArrayLike @@ -93,9 +94,8 @@ class Ticker: class _LazyTickList: def __init__(self, major: bool) -> None: ... - # Replace return with Self when py3.9 is dropped @overload - def __get__(self, instance: None, owner: None) -> _LazyTickList: ... + def __get__(self, instance: None, owner: None) -> Self: ... @overload def __get__(self, instance: Axis, owner: type[Axis]) -> list[Tick]: ... diff --git a/lib/matplotlib/backends/registry.py b/lib/matplotlib/backends/registry.py index e08817bb089b..3c85a9b47d7b 100644 --- a/lib/matplotlib/backends/registry.py +++ b/lib/matplotlib/backends/registry.py @@ -132,14 +132,8 @@ def _read_entry_points(self): # [project.entry-points."matplotlib.backend"] # inline = "matplotlib_inline.backend_inline" import importlib.metadata as im - import sys - - # entry_points group keyword not available before Python 3.10 - group = "matplotlib.backend" - if sys.version_info >= (3, 10): - entry_points = im.entry_points(group=group) - else: - entry_points = im.entry_points().get(group, ()) + + entry_points = im.entry_points(group="matplotlib.backend") entries = [(entry.name, entry.value) for entry in entry_points] # For backward compatibility, if matplotlib-inline and/or ipympl are installed diff --git a/lib/matplotlib/dviread.pyi b/lib/matplotlib/dviread.pyi index bf5cfcbe317a..270818278f17 100644 --- a/lib/matplotlib/dviread.pyi +++ b/lib/matplotlib/dviread.pyi @@ -5,6 +5,7 @@ from enum import Enum from collections.abc import Generator from typing import NamedTuple +from typing_extensions import Self # < Py 3.11 class _dvistate(Enum): pre: int @@ -47,8 +48,7 @@ class Dvi: fonts: dict[int, DviFont] state: _dvistate def __init__(self, filename: str | os.PathLike, dpi: float | None) -> None: ... - # Replace return with Self when py3.9 is dropped - def __enter__(self) -> Dvi: ... + def __enter__(self) -> Self: ... def __exit__(self, etype, evalue, etrace) -> None: ... def __iter__(self) -> Generator[Page, None, None]: ... def close(self) -> None: ... @@ -83,8 +83,7 @@ class PsFont(NamedTuple): filename: str class PsfontsMap: - # Replace return with Self when py3.9 is dropped - def __new__(cls, filename: str | os.PathLike) -> PsfontsMap: ... + def __new__(cls, filename: str | os.PathLike) -> Self: ... def __getitem__(self, texname: bytes) -> PsFont: ... def find_tex_file(filename: str | os.PathLike) -> str: ... diff --git a/lib/matplotlib/sankey.pyi b/lib/matplotlib/sankey.pyi index 4a40c31e3c6a..33565b998a9c 100644 --- a/lib/matplotlib/sankey.pyi +++ b/lib/matplotlib/sankey.pyi @@ -2,6 +2,7 @@ from matplotlib.axes import Axes from collections.abc import Callable, Iterable from typing import Any +from typing_extensions import Self # < Py 3.11 import numpy as np @@ -56,6 +57,5 @@ class Sankey: connect: tuple[int, int] = ..., rotation: float = ..., **kwargs - # Replace return with Self when py3.9 is dropped - ) -> Sankey: ... + ) -> Self: ... def finish(self) -> list[Any]: ... diff --git a/lib/matplotlib/style/core.py b/lib/matplotlib/style/core.py index 7e9008c56165..e36c3c37a882 100644 --- a/lib/matplotlib/style/core.py +++ b/lib/matplotlib/style/core.py @@ -12,19 +12,12 @@ """ import contextlib +import importlib.resources import logging import os from pathlib import Path -import sys import warnings -if sys.version_info >= (3, 10): - import importlib.resources as importlib_resources -else: - # Even though Py3.9 has importlib.resources, it doesn't properly handle - # modules added in sys.path. - import importlib_resources - import matplotlib as mpl from matplotlib import _api, _docstring, _rc_params_in_file, rcParamsDefault @@ -121,8 +114,7 @@ def use(style): elif "." in style: pkg, _, name = style.rpartition(".") try: - path = (importlib_resources.files(pkg) - / f"{name}.{STYLE_EXTENSION}") + path = importlib.resources.files(pkg) / f"{name}.{STYLE_EXTENSION}" style = _rc_params_in_file(path) except (ModuleNotFoundError, OSError, TypeError) as exc: # There is an ambiguity whether a dotted name refers to a diff --git a/lib/matplotlib/tests/test_backend_inline.py b/lib/matplotlib/tests/test_backend_inline.py index 4112eb213e2c..6f0d67d51756 100644 --- a/lib/matplotlib/tests/test_backend_inline.py +++ b/lib/matplotlib/tests/test_backend_inline.py @@ -1,7 +1,6 @@ import os from pathlib import Path from tempfile import TemporaryDirectory -import sys import pytest @@ -13,7 +12,6 @@ pytest.importorskip('matplotlib_inline') -@pytest.mark.skipif(sys.version_info[:2] <= (3, 9), reason="Requires Python 3.10+") def test_ipynb(): nb_path = Path(__file__).parent / 'test_inline_01.ipynb' diff --git a/lib/matplotlib/tests/test_sphinxext.py b/lib/matplotlib/tests/test_sphinxext.py index 6624e3b17ba5..24efecbeae9d 100644 --- a/lib/matplotlib/tests/test_sphinxext.py +++ b/lib/matplotlib/tests/test_sphinxext.py @@ -10,8 +10,7 @@ import pytest -pytest.importorskip('sphinx', - minversion=None if sys.version_info < (3, 10) else '4.1.3') +pytest.importorskip('sphinx', minversion='4.1.3') def build_sphinx_html(source_dir, doctree_dir, html_dir, extra_args=None): diff --git a/pyproject.toml b/pyproject.toml index 14ad28d23603..40222fe266da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,6 @@ classifiers=[ "License :: OSI Approved :: Python Software Foundation License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -40,9 +39,8 @@ dependencies = [ "pillow >= 8", "pyparsing >= 2.3.1", "python-dateutil >= 2.7", - "importlib-resources >= 3.2.0; python_version < '3.10'", ] -requires-python = ">=3.9" +requires-python = ">=3.10" [project.optional-dependencies] # Should be a copy of the build dependencies below. @@ -160,7 +158,7 @@ external = [ "E703", ] -target-version = "py39" +target-version = "py310" [tool.ruff.pydocstyle] convention = "numpy" diff --git a/requirements/testing/extra.txt b/requirements/testing/extra.txt index b3e9009b561c..a5c1bef5f03a 100644 --- a/requirements/testing/extra.txt +++ b/requirements/testing/extra.txt @@ -1,4 +1,4 @@ -# Extra pip requirements for the Python 3.9+ builds +# Extra pip requirements for the Python 3.10+ builds --prefer-binary ipykernel diff --git a/requirements/testing/minver.txt b/requirements/testing/minver.txt index 1a95367eff14..3932e68eb015 100644 --- a/requirements/testing/minver.txt +++ b/requirements/testing/minver.txt @@ -4,12 +4,12 @@ contourpy==1.0.1 cycler==0.10 fonttools==4.22.0 importlib-resources==3.2.0 -kiwisolver==1.3.1 +kiwisolver==1.3.2 meson-python==0.13.1 meson==1.1.0 numpy==1.23.0 packaging==20.0 -pillow==8.0.0 +pillow==8.3.2 pyparsing==2.3.1 pytest==7.0.0 python-dateutil==2.7 diff --git a/requirements/testing/mypy.txt b/requirements/testing/mypy.txt index a5ca15cfbdad..9e3738556a8f 100644 --- a/requirements/testing/mypy.txt +++ b/requirements/testing/mypy.txt @@ -25,5 +25,3 @@ pyparsing>=2.3.1 python-dateutil>=2.7 setuptools_scm>=7 setuptools>=64 - -importlib-resources>=3.2.0 ; python_version < "3.10" diff --git a/tools/boilerplate.py b/tools/boilerplate.py index a0943df00866..db93b102fce9 100644 --- a/tools/boilerplate.py +++ b/tools/boilerplate.py @@ -27,31 +27,9 @@ import numpy as np from matplotlib import _api, mlab from matplotlib.axes import Axes -from matplotlib.backend_bases import MouseButton from matplotlib.figure import Figure -# we need to define a custom str because py310 change -# In Python 3.10 the repr and str representation of Enums changed from -# -# str: 'ClassName.NAME' -> 'NAME' -# repr: '' -> 'ClassName.NAME' -# -# which is more consistent with what str/repr should do, however this breaks -# boilerplate which needs to get the ClassName.NAME version in all versions of -# Python. Thus, we locally monkey patch our preferred str representation in -# here. -# -# bpo-40066 -# https://github.com/python/cpython/pull/22392/ -def enum_str_back_compat_patch(self): - return f'{type(self).__name__}.{self.name}' - -# only monkey patch if we have to. -if str(MouseButton.LEFT) != 'MouseButton.Left': - MouseButton.__str__ = enum_str_back_compat_patch - - # This is the magic line that must exist in pyplot, after which the boilerplate # content will be appended. PYPLOT_MAGIC_HEADER = ( @@ -112,7 +90,7 @@ def __init__(self, value): self._repr = "_api.deprecation._deprecated_parameter" elif isinstance(value, Enum): # Enum str is Class.Name whereas their repr is . - self._repr = str(value) + self._repr = f'{type(value).__name__}.{value.name}' else: self._repr = repr(value) diff --git a/tox.ini b/tox.ini index cb2fcc979076..00ea746c8923 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py38, py39, py310, stubtest +envlist = py310, py311, py312, stubtest [testenv] changedir = /tmp