Skip to content

Commit 671f0a6

Browse files
authored
Merge pull request #313 from bsipocz/MAINT_remove_py39_pytest_lt_7
MAINT: dropping python 3.9 support and pytest<7
2 parents c235213 + 5ab5024 commit 671f0a6

File tree

7 files changed

+27
-88
lines changed

7 files changed

+27
-88
lines changed

.github/workflows/python-tests.yml

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,9 @@ jobs:
1919
# The aim with the matrix below is to walk through a representative but not full combination of OS, Python, and pytest versions.
2020
matrix:
2121
include:
22-
- os: ubuntu-latest
23-
python-version: '3.9'
24-
toxenv: py39-test-pytestoldest
25-
- os: windows-latest
26-
python-version: '3.9'
27-
toxenv: py39-test-pytest50
28-
- os: ubuntu-latest
29-
python-version: '3.9'
30-
toxenv: py39-test-pytest60
31-
- os: macos-latest
32-
python-version: '3.9'
33-
toxenv: py39-test-pytest62
3422
- os: ubuntu-latest
3523
python-version: '3.10'
36-
toxenv: py310-test-pytest70
24+
toxenv: py10-test-pytestoldest
3725
- os: ubuntu-latest
3826
python-version: '3.10'
3927
toxenv: py310-test-pytest71

CHANGES.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
1.7.0 (unreleased)
22
==================
33

4-
4+
- Versions of Python <3.10 and pytest<7 are no longer supported. [#313]
55

66
1.6.0 (2025-11-20)
77
==================

pytest_doctestplus/plugin.py

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,8 @@
2828
OutputChecker)
2929

3030
_pytest_version = Version(pytest.__version__)
31-
PYTEST_GT_5 = _pytest_version > Version('5.9.9')
32-
PYTEST_GE_5_4 = _pytest_version >= Version('5.4')
33-
PYTEST_GE_7_0 = _pytest_version >= Version('7.0')
3431
PYTEST_GE_8_0 = _pytest_version >= Version('8.0')
3532
PYTEST_GE_8_1_1 = _pytest_version >= Version('8.1.1')
36-
PYTEST_GE_8_2 = any([_pytest_version.is_devrelease,
37-
_pytest_version.is_prerelease,
38-
_pytest_version >= Version('8.2')])
3933

4034
comment_characters = {
4135
'.txt': '#',
@@ -256,30 +250,21 @@ class DocTestModulePlus(doctest_plugin.DoctestModule):
256250
def collect(self):
257251
# When running directly from pytest we need to make sure that we
258252
# don't accidentally import setup.py!
259-
if PYTEST_GE_7_0:
260-
fspath = self.path
261-
filepath = self.path.name
262-
else:
263-
fspath = self.fspath
264-
filepath = self.fspath.basename
253+
fspath = self.path
254+
filepath = self.path.name
265255

266256
if filepath in ("setup.py", "__main__.py"):
267257
return
268258
try:
269-
if PYTEST_GT_5:
270-
from _pytest.pathlib import import_path
271-
mode = self.config.getoption("importmode")
259+
from _pytest.pathlib import import_path
260+
mode = self.config.getoption("importmode")
272261

273262
if PYTEST_GE_8_1_1:
274263
consider_namespace_packages = self.config.getini("consider_namespace_packages")
275264
module = import_path(fspath, mode=mode, root=self.config.rootpath,
276265
consider_namespace_packages=consider_namespace_packages)
277-
elif PYTEST_GE_7_0:
278-
module = import_path(fspath, mode=mode, root=self.config.rootpath)
279-
elif PYTEST_GT_5:
280-
module = import_path(fspath, mode=mode)
281266
else:
282-
module = fspath.pyimport()
267+
module = import_path(fspath, mode=mode, root=self.config.rootpath)
283268
except ImportError:
284269
if self.config.getvalue("doctest_ignore_import_errors"):
285270
pytest.skip("unable to import module %r" % fspath)
@@ -345,12 +330,8 @@ class DocTestTextfilePlus(pytest.Module):
345330
obj = None
346331

347332
def collect(self):
348-
if PYTEST_GE_7_0:
349-
fspath = self.path
350-
filepath = self.path.name
351-
else:
352-
fspath = self.fspath
353-
filepath = self.fspath.basename
333+
fspath = self.path
334+
filepath = self.path.name
354335

355336
encoding = self.config.getini("doctest_encoding")
356337
text = fspath.read_text(encoding)
@@ -689,14 +670,10 @@ def pytest_ignore_collect(self, path, config):
689670
Skip paths that match any of the doctest_norecursedirs patterns or
690671
if doctest_only is True then skip all regular test files (eg test_*.py).
691672
"""
692-
if PYTEST_GE_7_0:
693-
dirpath = Path(path).parent
694-
collect_ignore = config._getconftest_pathlist("collect_ignore",
695-
path=dirpath,
696-
rootpath=config.rootpath)
697-
else:
698-
dirpath = path.dirpath()
699-
collect_ignore = config._getconftest_pathlist("collect_ignore", path=dirpath)
673+
dirpath = Path(path).parent
674+
collect_ignore = config._getconftest_pathlist("collect_ignore",
675+
path=dirpath,
676+
rootpath=config.rootpath)
700677

701678
# The collect_ignore conftest.py variable should cause all test
702679
# runners to ignore this file and all subfiles and subdirectories
@@ -779,12 +756,7 @@ def pytest_collect_file(self, path, parent):
779756
return None
780757

781758
# Don't override the built-in doctest plugin
782-
if PYTEST_GE_7_0:
783-
return self._doctest_module_item_cls.from_parent(parent, path=Path(path))
784-
elif PYTEST_GE_5_4:
785-
return self._doctest_module_item_cls.from_parent(parent, fspath=path)
786-
else:
787-
return self._doctest_module_item_cls(path, parent)
759+
return self._doctest_module_item_cls.from_parent(parent, path=Path(path))
788760

789761
elif any([path.check(fnmatch=pat) for pat in self._file_globs]):
790762
# Ignore generated .rst files
@@ -811,12 +783,7 @@ def pytest_collect_file(self, path, parent):
811783

812784
# TODO: Get better names on these items when they are
813785
# displayed in py.test output
814-
if PYTEST_GE_7_0:
815-
return self._doctest_textfile_item_cls.from_parent(parent, path=Path(path))
816-
elif PYTEST_GE_5_4:
817-
return self._doctest_textfile_item_cls.from_parent(parent, fspath=path)
818-
else:
819-
return self._doctest_textfile_item_cls(path, parent)
786+
return self._doctest_textfile_item_cls.from_parent(parent, path=Path(path))
820787

821788

822789
class DocTestFinderPlus(doctest.DocTestFinder):
@@ -930,7 +897,7 @@ def _prepend_importorskip(self, test, *, module):
930897
"""Prepends `pytest.importorskip` before the doctest."""
931898
source = (
932899
"import pytest; "
933-
# Hide output of this statement in `___`, otherwise doctests fail
900+
# Hide output of this statement in `___`, otherwise doctests fail
934901
f"___ = pytest.importorskip({module!r}); "
935902
# Don't impact what's available in the namespace
936903
"del pytest; del ___"

setup.cfg

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ classifiers =
1111
Programming Language :: Python
1212
Programming Language :: Python :: 3
1313
Programming Language :: Python :: 3 :: Only
14-
Programming Language :: Python :: 3.9
1514
Programming Language :: Python :: 3.10
1615
Programming Language :: Python :: 3.11
1716
Programming Language :: Python :: 3.12
@@ -29,11 +28,11 @@ keywords = doctest, rst, pytest, py.test
2928
[options]
3029
zip_safe = False
3130
packages = find:
32-
python_requires = >=3.9
31+
python_requires = >=3.10
3332
setup_requires =
3433
setuptools_scm
3534
install_requires =
36-
pytest>=4.6
35+
pytest>=7.0
3736
packaging>=17.0
3837

3938
[options.extras_require]
@@ -52,7 +51,7 @@ exclude =
5251
tests
5352

5453
[tool:pytest]
55-
minversion = 4.6
54+
minversion = 7.0
5655
testpaths = tests pytest_doctestplus
5756
xfail_strict=true
5857
filterwarnings =

tests/test_doctestplus.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
pytest_plugins = ['pytester']
2525

2626

27-
PYTEST_LT_6 = Version(pytest.__version__) < Version('6.0.0')
28-
29-
3027
def test_ignored_whitespace(testdir):
3128
testdir.makeini(
3229
"""
@@ -863,8 +860,6 @@ def test_doctest_float_replacement(tmp_path):
863860

864861
@pytest.fixture()
865862
def subpackage_requires_testdir(testdir, request):
866-
if request.param[0] == 'makepyprojecttoml' and PYTEST_LT_6:
867-
return None, None
868863

869864
config_file = getattr(testdir, request.param[0])(request.param[1])
870865

@@ -902,7 +897,6 @@ def test_doctest_subpackage_requires(subpackage_requires_testdir, caplog):
902897

903898

904899
@pytest.mark.parametrize(('import_mode', 'expected'), [
905-
pytest.param('importlib', dict(passed=2), marks=pytest.mark.skipif(PYTEST_LT_6, reason="importlib import mode not supported on Pytest <6"), id="importlib"),
906900
pytest.param('append', dict(failed=1), id="append"),
907901
pytest.param('prepend', dict(failed=1), id="prepend"),
908902
])
@@ -1390,8 +1384,6 @@ def wrapper(*args, **kwargs):
13901384

13911385
@pytest.fixture()
13921386
def norecursedirs_testdir(testdir, request):
1393-
if request.param[0] == 'makepyprojecttoml' and PYTEST_LT_6:
1394-
return None, None
13951387

13961388
config_file = getattr(testdir, request.param[0])(request.param[1])
13971389

@@ -1550,14 +1542,14 @@ def f():
15501542
def test_skip_module_variable(testdir):
15511543
p = testdir.makepyfile("""
15521544
__doctest_skip__ = ["f"]
1553-
1545+
15541546
def f():
15551547
'''
15561548
>>> 1 + 2
15571549
5
15581550
'''
15591551
pass
1560-
1552+
15611553
def g():
15621554
'''
15631555
>>> 1 + 1
@@ -1580,7 +1572,7 @@ def f():
15801572
>>> import module_that_is_not_availabe
15811573
'''
15821574
pass
1583-
1575+
15841576
def g():
15851577
'''
15861578
Test that call to `pytest.importorskip` is not visible

tests/test_encoding.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import os
33
from pathlib import Path
44
from textwrap import dedent
5-
from typing import Callable, Optional
5+
from typing import Optional
6+
from collections.abc import Callable
67

78
import pytest
89

@@ -66,7 +67,7 @@ def f():
6667
def ini_file(testdir) -> Callable[..., Path]:
6768

6869
def makeini(
69-
encoding: Optional[str] = None,
70+
encoding: str | None = None,
7071
) -> Path:
7172
"""Create a pytest.ini file with the specified encoding."""
7273

tox.ini

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22
envlist =
3-
py{39,310,311,312,313,314}-test
3+
py{310,311,312,313,314}-test
44
codestyle
55
requires =
66
setuptools >= 30.3.0
@@ -14,15 +14,7 @@ setenv =
1414
numpydev: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/scientific-python-nightly-wheels/simple
1515
description = run tests
1616
deps =
17-
pytestoldest: pytest==4.6.0
18-
pytest50: pytest==5.0.*
19-
pytest51: pytest==5.1.*
20-
pytest52: pytest==5.2.*
21-
pytest53: pytest==5.3.*
22-
pytest60: pytest==6.0.*
23-
pytest61: pytest==6.1.*
24-
pytest62: pytest==6.2.*
25-
pytest70: pytest==7.0.*
17+
pytestoldest: pytest==7.0.0
2618
pytest71: pytest==7.1.*
2719
pytest72: pytest==7.2.*
2820
pytest73: pytest==7.3.*

0 commit comments

Comments
 (0)