Skip to content

Commit bb712f1

Browse files
committed
Remove support for Python 3.9
It will be end-of-life (or on its last breaths) by the time of the next release. Refs #13719
1 parent d2d57e3 commit bb712f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+190
-279
lines changed

.github/workflows/test.yml

Lines changed: 48 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -56,32 +56,29 @@ jobs:
5656
fail-fast: false
5757
matrix:
5858
name: [
59-
"windows-py39-unittest-asynctest",
60-
"windows-py39-unittest-twisted24",
61-
"windows-py39-unittest-twisted25",
62-
"windows-py39-pluggy",
63-
"windows-py39-xdist",
64-
"windows-py310",
59+
"windows-py310-unittest-asynctest",
60+
"windows-py310-unittest-twisted24",
61+
"windows-py310-unittest-twisted25",
62+
"windows-py310-pluggy",
63+
"windows-py310-xdist",
6564
"windows-py311",
6665
"windows-py312",
6766
"windows-py313",
6867
"windows-py314",
6968

70-
"ubuntu-py39-unittest-asynctest",
71-
"ubuntu-py39-unittest-twisted24",
72-
"ubuntu-py39-unittest-twisted25",
73-
"ubuntu-py39-lsof-numpy-pexpect",
74-
"ubuntu-py39-pluggy",
75-
"ubuntu-py39-freeze",
76-
"ubuntu-py39-xdist",
69+
"ubuntu-py310-unittest-asynctest",
70+
"ubuntu-py310-unittest-twisted24",
71+
"ubuntu-py310-unittest-twisted25",
72+
"ubuntu-py310-lsof-numpy-pexpect",
73+
"ubuntu-py310-pluggy",
74+
"ubuntu-py310-freeze",
7775
"ubuntu-py310-xdist",
7876
"ubuntu-py311",
7977
"ubuntu-py312",
8078
"ubuntu-py313-pexpect",
8179
"ubuntu-py314",
8280
"ubuntu-pypy3-xdist",
8381

84-
"macos-py39",
8582
"macos-py310",
8683
"macos-py312",
8784
"macos-py313",
@@ -93,35 +90,30 @@ jobs:
9390

9491
include:
9592
# Use separate jobs for different unittest flavors (twisted, asynctest) to ensure proper coverage.
96-
- name: "windows-py39-unittest-asynctest"
97-
python: "3.9"
93+
- name: "windows-py310-unittest-asynctest"
94+
python: "3.10"
9895
os: windows-latest
99-
tox_env: "py39-asynctest"
96+
tox_env: "py310-asynctest"
10097
use_coverage: true
10198

102-
- name: "windows-py39-unittest-twisted24"
103-
python: "3.9"
99+
- name: "windows-py310-unittest-twisted24"
100+
python: "3.10"
104101
os: windows-latest
105-
tox_env: "py39-twisted24"
102+
tox_env: "py310-twisted24"
106103
use_coverage: true
107104

108-
- name: "windows-py39-unittest-twisted25"
109-
python: "3.9"
105+
- name: "windows-py310-unittest-twisted25"
106+
python: "3.10"
110107
os: windows-latest
111-
tox_env: "py39-twisted25"
108+
tox_env: "py310-twisted25"
112109
use_coverage: true
113110

114-
- name: "windows-py39-pluggy"
115-
python: "3.9"
116-
os: windows-latest
117-
tox_env: "py39-pluggymain-pylib-xdist"
118-
119-
- name: "windows-py39-xdist"
120-
python: "3.9"
111+
- name: "windows-py310-pluggy"
112+
python: "3.10"
121113
os: windows-latest
122-
tox_env: "py39-xdist"
114+
tox_env: "py310-pluggymain-pylib-xdist"
123115

124-
- name: "windows-py310"
116+
- name: "windows-py310-xdist"
125117
python: "3.10"
126118
os: windows-latest
127119
tox_env: "py310-xdist"
@@ -147,44 +139,39 @@ jobs:
147139
tox_env: "py314"
148140

149141
# Use separate jobs for different unittest flavors (twisted, asynctest) to ensure proper coverage.
150-
- name: "ubuntu-py39-unittest-asynctest"
151-
python: "3.9"
142+
- name: "ubuntu-py310-unittest-asynctest"
143+
python: "3.10"
152144
os: ubuntu-latest
153-
tox_env: "py39-asynctest"
145+
tox_env: "py310-asynctest"
154146
use_coverage: true
155147

156-
- name: "ubuntu-py39-unittest-twisted24"
157-
python: "3.9"
148+
- name: "ubuntu-py310-unittest-twisted24"
149+
python: "3.10"
158150
os: ubuntu-latest
159-
tox_env: "py39-twisted24"
151+
tox_env: "py310-twisted24"
160152
use_coverage: true
161153

162-
- name: "ubuntu-py39-unittest-twisted25"
163-
python: "3.9"
154+
- name: "ubuntu-py310-unittest-twisted25"
155+
python: "3.10"
164156
os: ubuntu-latest
165-
tox_env: "py39-twisted25"
157+
tox_env: "py310-twisted25"
166158
use_coverage: true
167159

168-
- name: "ubuntu-py39-lsof-numpy-pexpect"
169-
python: "3.9"
160+
- name: "ubuntu-py310-lsof-numpy-pexpect"
161+
python: "3.10"
170162
os: ubuntu-latest
171-
tox_env: "py39-lsof-numpy-pexpect"
163+
tox_env: "py310-lsof-numpy-pexpect"
172164
use_coverage: true
173165

174-
- name: "ubuntu-py39-pluggy"
175-
python: "3.9"
176-
os: ubuntu-latest
177-
tox_env: "py39-pluggymain-pylib-xdist"
178-
179-
- name: "ubuntu-py39-freeze"
180-
python: "3.9"
166+
- name: "ubuntu-py310-pluggy"
167+
python: "3.10"
181168
os: ubuntu-latest
182-
tox_env: "py39-freeze"
169+
tox_env: "py310-pluggymain-pylib-xdist"
183170

184-
- name: "ubuntu-py39-xdist"
185-
python: "3.9"
171+
- name: "ubuntu-py310-freeze"
172+
python: "3.10"
186173
os: ubuntu-latest
187-
tox_env: "py39-xdist"
174+
tox_env: "py310-freeze"
188175

189176
- name: "ubuntu-py310-xdist"
190177
python: "3.10"
@@ -216,17 +203,11 @@ jobs:
216203
use_coverage: true
217204

218205
- name: "ubuntu-pypy3-xdist"
219-
python: "pypy-3.9"
206+
python: "pypy-3.10"
220207
os: ubuntu-latest
221208
tox_env: "pypy3-xdist"
222209

223210

224-
- name: "macos-py39"
225-
python: "3.9"
226-
os: macos-latest
227-
tox_env: "py39-xdist"
228-
use_coverage: true
229-
230211
- name: "macos-py310"
231212
python: "3.10"
232213
os: macos-latest
@@ -254,7 +235,7 @@ jobs:
254235

255236

256237
- name: "doctesting"
257-
python: "3.9"
238+
python: "3.10"
258239
os: ubuntu-latest
259240
tox_env: "doctesting"
260241
use_coverage: true
@@ -264,12 +245,12 @@ jobs:
264245
contains(
265246
fromJSON(
266247
'[
267-
"windows-py39-pluggy",
248+
"windows-py310-pluggy",
268249
"windows-py313",
269-
"ubuntu-py39-pluggy",
270-
"ubuntu-py39-freeze",
250+
"ubuntu-py310-pluggy",
251+
"ubuntu-py310-freeze",
271252
"ubuntu-py313",
272-
"macos-py39",
253+
"macos-py310",
273254
"macos-py313"
274255
]'
275256
),

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ repos:
7676
hooks:
7777
- id: pyupgrade
7878
args:
79-
- "--py39-plus"
79+
- "--py310-plus"
8080
# Manual because ruff does what pyupgrade does and the two are not out of sync
8181
# often enough to make launching pyupgrade everytime worth it
8282
stages: [manual]

CONTRIBUTING.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ Short version
197197
#. Follow `PEP-8 <https://www.python.org/dev/peps/pep-0008/>`_ for naming.
198198
#. Tests are run using ``tox``::
199199

200-
tox -e linting,py39
200+
tox -e linting,py313
201201

202202
The test environments above are usually enough to cover most cases locally.
203203

@@ -269,24 +269,24 @@ Here is a simple overview, with pytest-specific bits:
269269

270270
#. Run all the tests
271271

272-
You need to have Python 3.9 or later available in your system. Now
272+
You need to have a supported Python version available in your system. Now
273273
running tests is as simple as issuing this command::
274274

275-
$ tox -e linting,py39
275+
$ tox -e linting,py
276276

277-
This command will run tests via the "tox" tool against Python 3.9
278-
and also perform "lint" coding-style checks.
277+
This command will run tests via the "tox" tool against your default Python
278+
version and also perform "lint" coding-style checks.
279279

280280
#. You can now edit your local working copy and run the tests again as necessary. Please follow `PEP-8 <https://www.python.org/dev/peps/pep-0008/>`_ for naming.
281281

282-
You can pass different options to ``tox``. For example, to run tests on Python 3.9 and pass options to pytest
282+
You can pass different options to ``tox``. For example, to run tests on Python 3.13 and pass options to pytest
283283
(e.g. enter pdb on failure) to pytest you can do::
284284

285-
$ tox -e py39 -- --pdb
285+
$ tox -e py313 -- --pdb
286286

287-
Or to only run tests in a particular test module on Python 3.9::
287+
Or to only run tests in a particular test module on Python 3.12::
288288

289-
$ tox -e py39 -- testing/test_config.py
289+
$ tox -e py312 -- testing/test_config.py
290290

291291

292292
When committing, ``pre-commit`` will re-format the files if necessary.

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Features
9797
- Can run `unittest <https://docs.pytest.org/en/stable/how-to/unittest.html>`_ (or trial)
9898
test suites out of the box
9999

100-
- Python 3.9+ or PyPy3
100+
- Python 3.10+ or PyPy3
101101

102102
- Rich plugin architecture, with over 1300+ `external plugins <https://docs.pytest.org/en/latest/reference/plugin_list.html>`_ and thriving community
103103

changelog/13719.breaking.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support for Python 3.9 is dropped following its end of life.

doc/en/example/multipython.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import pytest
1111

1212

13-
pythonlist = ["python3.9", "python3.10", "python3.11"]
13+
pythonlist = ["python3.11", "python3.12", "python3.13"]
1414

1515

1616
@pytest.fixture(params=pythonlist)

doc/en/getting-started.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ Get Started
99
Install ``pytest``
1010
----------------------------------------
1111

12-
``pytest`` requires: Python 3.8+ or PyPy3.
13-
1412
1. Run the following command in your command line:
1513

1614
.. code-block:: bash

doc/en/how-to/skipping.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ It is also possible to skip the whole module using
8484

8585
If you wish to skip something conditionally then you can use ``skipif`` instead.
8686
Here is an example of marking a test function to be skipped
87-
when run on an interpreter earlier than Python3.10:
87+
when run on an interpreter earlier than Python3.13:
8888

8989
.. code-block:: python
9090
9191
import sys
9292
9393
94-
@pytest.mark.skipif(sys.version_info < (3, 10), reason="requires python3.10 or higher")
94+
@pytest.mark.skipif(sys.version_info < (3, 13), reason="requires python3.13 or higher")
9595
def test_function(): ...
9696
9797
If the condition evaluates to ``True`` during collection, the test function will be skipped,

doc/en/index.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ The ``pytest`` framework makes it easy to write small, readable tests, and can
4646
scale to support complex functional testing for applications and libraries.
4747

4848

49-
``pytest`` requires: Python 3.8+ or PyPy3.
50-
5149
**PyPI package name**: :pypi:`pytest`
5250

5351
A quick example
@@ -104,7 +102,7 @@ Features
104102

105103
- Can run :ref:`unittest <unittest>` (including trial) test suites out of the box
106104

107-
- Python 3.8+ or PyPy 3
105+
- Python 3.10+ or PyPy 3
108106

109107
- Rich plugin architecture, with over 1300+ :ref:`external plugins <plugin-list>` and thriving community
110108

pyproject.toml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ authors = [
2424
{ name = "Florian Bruhin" },
2525
{ name = "Others (See AUTHORS)" },
2626
]
27-
requires-python = ">=3.9"
27+
requires-python = ">=3.10"
2828
classifiers = [
2929
"Development Status :: 6 - Mature",
3030
"Intended Audience :: Developers",
@@ -33,7 +33,6 @@ classifiers = [
3333
"Operating System :: POSIX",
3434
"Operating System :: Unix",
3535
"Programming Language :: Python :: 3 :: Only",
36-
"Programming Language :: Python :: 3.9",
3736
"Programming Language :: Python :: 3.10",
3837
"Programming Language :: Python :: 3.11",
3938
"Programming Language :: Python :: 3.12",
@@ -86,10 +85,10 @@ write_to = "src/_pytest/_version.py"
8685

8786
[tool.black]
8887
# See https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#t-target-version
89-
target-version = [ "py39", "py310", "py311", "py312", "py313" ]
88+
target-version = [ "py310", "py311", "py312", "py313" ]
9089

9190
[tool.ruff]
92-
target-version = "py39"
91+
target-version = "py310"
9392
line-length = 88
9493
src = [
9594
"src",
@@ -520,7 +519,7 @@ files = [
520519
mypy_path = [
521520
"src",
522521
]
523-
python_version = "3.9"
522+
python_version = "3.10"
524523
check_untyped_defs = true
525524
disallow_any_generics = true
526525
disallow_untyped_defs = true
@@ -543,7 +542,7 @@ include = [
543542
extraPaths = [
544543
"src",
545544
]
546-
pythonVersion = "3.9"
545+
pythonVersion = "3.10"
547546
typeCheckingMode = "basic"
548547
reportMissingImports = "none"
549548
reportMissingModuleSource = "none"

0 commit comments

Comments
 (0)