Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pytest-doctestplus for
openSUSE:Factory checked in at 2026-03-18 16:50:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-doctestplus (Old)
and /work/SRC/openSUSE:Factory/.python-pytest-doctestplus.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-doctestplus"
Wed Mar 18 16:50:31 2026 rev:22 rq:1340816 version:1.7.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-pytest-doctestplus/python-pytest-doctestplus.changes
2025-10-28 14:50:10.556046929 +0100
+++
/work/SRC/openSUSE:Factory/.python-pytest-doctestplus.new.8177/python-pytest-doctestplus.changes
2026-03-18 16:52:08.489122215 +0100
@@ -1,0 +2,23 @@
+Wed Mar 18 04:59:37 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Add patch more-skipping-ufunc-test.patch:
+ * Skip test_ufunc for more Python versions.
+
+-------------------------------------------------------------------
+Fri Feb 13 02:00:58 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Update to 1.7.1:
+ * Fixing bug where __doctest_requires__ with version specifiers (e.g.,
+ numpy>=2.0) incorrectly skipped tests even when dependencies were
+ satisfied.
+ * Fixing crashing sphinx builds where multiple directives are used with the
+ first one expecting content. The order of the directives used does not
+ matter after this fix.
+ * Versions of Python <3.10 and pytest<7 are no longer supported.
+ * Fixing directives that should not have any content and therefore fixing
+ previously crashing sphinx builds. Using these directives with a content
+ now results an error.
+ * Ensure that tests skipped with __doctest_skip__ and __doctest_requires__
+ show up as skipped tests in Pytest's output.
+
+-------------------------------------------------------------------
Old:
----
pytest_doctestplus-1.5.0.tar.gz
New:
----
_scmsync.obsinfo
build.specials.obscpio
more-skipping-ufunc-test.patch
pytest_doctestplus-1.7.1.tar.gz
----------(New B)----------
New:
- Add patch more-skipping-ufunc-test.patch:
* Skip test_ufunc for more Python versions.
----------(New E)----------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytest-doctestplus.spec ++++++
--- /var/tmp/diff_new_pack.jlO3bf/_old 2026-03-18 16:52:09.605168214 +0100
+++ /var/tmp/diff_new_pack.jlO3bf/_new 2026-03-18 16:52:09.605168214 +0100
@@ -27,25 +27,25 @@
%{?sle15_python_module_pythons}
Name: python-pytest-doctestplus%{psuffix}
-Version: 1.5.0
+Version: 1.7.1
Release: 0
Summary: Pytest plugin with advanced doctest features
License: BSD-3-Clause
URL: https://github.com/scientific-python/pytest-doctestplus
Source:
https://files.pythonhosted.org/packages/source/p/pytest-doctestplus/pytest_doctestplus-%{version}.tar.gz
-BuildRequires: %{python_module base >= 3.8}
+# PATCH-FIX-UPSTREAM gh#scientific-python/pytest-doctestplus#322
+Patch0: more-skipping-ufunc-test.patch
+BuildRequires: %{python_module base >= 3.10}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools_scm}
BuildRequires: %{python_module wheel}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-packaging >= 17.0
-Requires: python-pytest >= 4.6
+Requires: python-pytest >= 7
%if %{with test}
BuildRequires: %{python_module Sphinx}
BuildRequires: %{python_module numpy-devel}
-BuildRequires: %{python_module numpy}
-BuildRequires: %{python_module pip >= 19.3.1}
BuildRequires: %{python_module pytest-doctestplus = %{version}}
BuildRequires: %{python_module pytest-remotedata >= 0.3.2}
BuildRequires: git-core
++++++ _scmsync.obsinfo ++++++
mtime: 1773809980
commit: de268ec1c6423e5e91d0b3a36341fe919f98ba28c383d4a6c881bcbb5cc67872
url: https://src.opensuse.org/python-pytest/python-pytest-doctestplus.git
revision: de268ec1c6423e5e91d0b3a36341fe919f98ba28c383d4a6c881bcbb5cc67872
projectscmsync: https://src.opensuse.org/python-pytest/_ObsPrj.git
++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore 1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore 2026-03-18 06:08:18.000000000 +0100
@@ -0,0 +1 @@
+.osc
++++++ more-skipping-ufunc-test.patch ++++++
>From 21754d989677f20d66b4d871c8813c6aef4bb4b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= <[email protected]>
Date: Tue, 17 Mar 2026 10:48:40 -0700
Subject: [PATCH] skip test for more python versions
---
tests/test_doctestplus.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/test_doctestplus.py b/tests/test_doctestplus.py
index cb2c4fa..91542ce 100644
--- a/tests/test_doctestplus.py
+++ b/tests/test_doctestplus.py
@@ -22,6 +22,7 @@
pytest_plugins = ['pytester']
+py_version = Version(python_version())
def test_ignored_whitespace(testdir):
@@ -1211,7 +1212,7 @@ def f():
@pytest.mark.xfail(
- python_version() in ('3.11.9', '3.11.10', '3.11.11', '3.11.12',
'3.11.13', '3.11.14', '3.12.3'),
+ py_version > Version('3.11.8') and py_version < Version('3.12') or
py_version == '3.12.3',
reason='broken by https://github.com/python/cpython/pull/115440')
def test_ufunc(testdir):
pytest.importorskip('numpy')
++++++ pytest_doctestplus-1.5.0.tar.gz -> pytest_doctestplus-1.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/.github/dependabot.yml
new/pytest_doctestplus-1.7.1/.github/dependabot.yml
--- old/pytest_doctestplus-1.5.0/.github/dependabot.yml 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/.github/dependabot.yml 2026-01-26
23:13:09.000000000 +0100
@@ -15,3 +15,5 @@
- "*"
labels:
- "no-changelog-entry-needed"
+ cooldown:
+ default-days: 14
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/.github/workflows/publish.yml
new/pytest_doctestplus-1.7.1/.github/workflows/publish.yml
--- old/pytest_doctestplus-1.5.0/.github/workflows/publish.yml 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/.github/workflows/publish.yml 2026-01-26
23:13:09.000000000 +0100
@@ -18,10 +18,10 @@
if: ((github.event_name == 'push' && startsWith(github.ref, 'refs/tags'))
|| contains(github.event.pull_request.labels.*.name, 'Build wheels'))
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #
v6.0.0
+ - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 #
v6.1.0
with:
python-version: '3.10'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/.github/workflows/python-tests.yml
new/pytest_doctestplus-1.7.1/.github/workflows/python-tests.yml
--- old/pytest_doctestplus-1.5.0/.github/workflows/python-tests.yml
2025-10-18 04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/.github/workflows/python-tests.yml
2026-01-26 23:13:09.000000000 +0100
@@ -20,23 +20,8 @@
matrix:
include:
- os: ubuntu-latest
- python-version: '3.9'
- toxenv: py39-test-pytestoldest
- - os: windows-latest
- python-version: '3.9'
- toxenv: py39-test-pytest50
- - os: macos-13
- python-version: '3.9'
- toxenv: py39-test-pytest51
- - os: ubuntu-latest
- python-version: '3.9'
- toxenv: py39-test-pytest60
- - os: ubuntu-latest
- python-version: '3.9'
- toxenv: py39-test-pytest62
- - os: ubuntu-latest
python-version: '3.10'
- toxenv: py310-test-pytest70
+ toxenv: py10-test-pytestoldest
- os: ubuntu-latest
python-version: '3.10'
toxenv: py310-test-pytest71
@@ -67,6 +52,7 @@
- os: windows-latest
python-version: '3.14'
toxenv: py314-test-pytestdev
+ posargs: -v
- os: macos-latest
python-version: '3.14'
toxenv: py314-test-pytestdev
@@ -78,11 +64,11 @@
toxenv: py313-test-pytest83-pytestasyncio
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #
v6.0.0
+ uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 #
v6.1.0
with:
python-version: ${{ matrix.python-version }}
- name: Install Tox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/CHANGES.rst
new/pytest_doctestplus-1.7.1/CHANGES.rst
--- old/pytest_doctestplus-1.5.0/CHANGES.rst 2025-10-18 04:00:38.000000000
+0200
+++ new/pytest_doctestplus-1.7.1/CHANGES.rst 2026-01-26 23:13:09.000000000
+0100
@@ -1,3 +1,29 @@
+1.7.1 (2026-01-26)
+==================
+
+- Fixing bug where ``__doctest_requires__`` with version specifiers (e.g.,
+ ``numpy>=2.0``) incorrectly skipped tests even when dependencies were
+ satisfied. [#319]
+
+1.7.0 (2026-01-07)
+==================
+
+- Fixing crashing sphinx builds where multiple directives are used with the
+ first one expecting content. The order of the directives used does not
+ matter after this fix. [#316]
+
+- Versions of Python <3.10 and pytest<7 are no longer supported. [#313]
+
+1.6.0 (2025-11-20)
+==================
+
+- Fixing directives that should not have any content and therefore fixing
+ previously crashing sphinx builds. Using these directives with a content
+ now results an error. [#311]
+
+- Ensure that tests skipped with ``__doctest_skip__`` and
+ ``__doctest_requires__`` show up as skipped tests in Pytest's output. [#312]
+
1.5.0 (2025-10-17)
==================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/PKG-INFO
new/pytest_doctestplus-1.7.1/PKG-INFO
--- old/pytest_doctestplus-1.5.0/PKG-INFO 2025-10-18 04:00:49.324933000
+0200
+++ new/pytest_doctestplus-1.7.1/PKG-INFO 2026-01-26 23:13:19.276869800
+0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: pytest-doctestplus
-Version: 1.5.0
+Version: 1.7.1
Summary: Pytest plugin with advanced doctest features.
Home-page: https://github.com/scientific-python/pytest-doctestplus
Author: Scientific Python Developers
@@ -14,18 +14,18 @@
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Utilities
-Requires-Python: >=3.9
+Requires-Python: >=3.10
Description-Content-Type: text/x-rst
License-File: LICENSE.rst
-Requires-Dist: pytest>=4.6
+Requires-Dist: pytest>=7.0
Requires-Dist: packaging>=17.0
Provides-Extra: test
Requires-Dist: numpy; extra == "test"
@@ -289,12 +289,14 @@
.. code-block:: rst
- .. doctest-skip-all
+ .. doctest-skip-all::
- >>> import non_existing
- >>> non_existing.write_pseudo_code()
- All the doctests are skipped in the file below
+ All the doctests are skipped in the file below
+ .. code-block::
+
+ >>> import non_existing
+ >>> non_existing.write_pseudo_code()
Skip Unconditionally
^^^^^^^^^^^^^^^^^^^^
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/README.rst
new/pytest_doctestplus-1.7.1/README.rst
--- old/pytest_doctestplus-1.5.0/README.rst 2025-10-18 04:00:38.000000000
+0200
+++ new/pytest_doctestplus-1.7.1/README.rst 2026-01-26 23:13:09.000000000
+0100
@@ -253,12 +253,14 @@
.. code-block:: rst
- .. doctest-skip-all
+ .. doctest-skip-all::
- >>> import non_existing
- >>> non_existing.write_pseudo_code()
- All the doctests are skipped in the file below
+ All the doctests are skipped in the file below
+ .. code-block::
+
+ >>> import non_existing
+ >>> non_existing.write_pseudo_code()
Skip Unconditionally
^^^^^^^^^^^^^^^^^^^^
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/conftest.py
new/pytest_doctestplus-1.7.1/conftest.py
--- old/pytest_doctestplus-1.5.0/conftest.py 1970-01-01 01:00:00.000000000
+0100
+++ new/pytest_doctestplus-1.7.1/conftest.py 2026-01-26 23:13:09.000000000
+0100
@@ -0,0 +1,14 @@
+import sys
+from packaging.version import Version
+from platform import python_version
+
+import pytest
+
+PYTEST_LT_8_5 = Version(pytest.__version__) < Version('8.5.0.dev')
+
+
+# Windows + Python 3.14.0 + pytest-dev have ResourceWarning, see
+# https://github.com/scientific-python/pytest-doctestplus/issues/305
+def pytest_runtestloop(session):
+ if sys.platform == 'win32' and python_version() == "3.14.0" and not
PYTEST_LT_8_5:
+
session.add_marker(pytest.mark.filterwarnings('ignore::ResourceWarning'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/pytest_doctestplus/plugin.py
new/pytest_doctestplus-1.7.1/pytest_doctestplus/plugin.py
--- old/pytest_doctestplus-1.5.0/pytest_doctestplus/plugin.py 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/pytest_doctestplus/plugin.py 2026-01-26
23:13:09.000000000 +0100
@@ -28,14 +28,8 @@
OutputChecker)
_pytest_version = Version(pytest.__version__)
-PYTEST_GT_5 = _pytest_version > Version('5.9.9')
-PYTEST_GE_5_4 = _pytest_version >= Version('5.4')
-PYTEST_GE_7_0 = _pytest_version >= Version('7.0')
PYTEST_GE_8_0 = _pytest_version >= Version('8.0')
PYTEST_GE_8_1_1 = _pytest_version >= Version('8.1.1')
-PYTEST_GE_8_2 = any([_pytest_version.is_devrelease,
- _pytest_version.is_prerelease,
- _pytest_version >= Version('8.2')])
comment_characters = {
'.txt': '#',
@@ -256,30 +250,21 @@
def collect(self):
# When running directly from pytest we need to make sure that we
# don't accidentally import setup.py!
- if PYTEST_GE_7_0:
- fspath = self.path
- filepath = self.path.name
- else:
- fspath = self.fspath
- filepath = self.fspath.basename
+ fspath = self.path
+ filepath = self.path.name
if filepath in ("setup.py", "__main__.py"):
return
try:
- if PYTEST_GT_5:
- from _pytest.pathlib import import_path
- mode = self.config.getoption("importmode")
+ from _pytest.pathlib import import_path
+ mode = self.config.getoption("importmode")
if PYTEST_GE_8_1_1:
consider_namespace_packages =
self.config.getini("consider_namespace_packages")
module = import_path(fspath, mode=mode,
root=self.config.rootpath,
consider_namespace_packages=consider_namespace_packages)
- elif PYTEST_GE_7_0:
- module = import_path(fspath, mode=mode,
root=self.config.rootpath)
- elif PYTEST_GT_5:
- module = import_path(fspath, mode=mode)
else:
- module = fspath.pyimport()
+ module = import_path(fspath, mode=mode,
root=self.config.rootpath)
except ImportError:
if self.config.getvalue("doctest_ignore_import_errors"):
pytest.skip("unable to import module %r" % fspath)
@@ -345,12 +330,8 @@
obj = None
def collect(self):
- if PYTEST_GE_7_0:
- fspath = self.path
- filepath = self.path.name
- else:
- fspath = self.fspath
- filepath = self.fspath.basename
+ fspath = self.path
+ filepath = self.path.name
encoding = self.config.getini("doctest_encoding")
text = fspath.read_text(encoding)
@@ -689,14 +670,10 @@
Skip paths that match any of the doctest_norecursedirs patterns or
if doctest_only is True then skip all regular test files (eg
test_*.py).
"""
- if PYTEST_GE_7_0:
- dirpath = Path(path).parent
- collect_ignore = config._getconftest_pathlist("collect_ignore",
- path=dirpath,
-
rootpath=config.rootpath)
- else:
- dirpath = path.dirpath()
- collect_ignore =
config._getconftest_pathlist("collect_ignore", path=dirpath)
+ dirpath = Path(path).parent
+ collect_ignore = config._getconftest_pathlist("collect_ignore",
+ path=dirpath,
+
rootpath=config.rootpath)
# The collect_ignore conftest.py variable should cause all test
# runners to ignore this file and all subfiles and subdirectories
@@ -779,12 +756,7 @@
return None
# Don't override the built-in doctest plugin
- if PYTEST_GE_7_0:
- return self._doctest_module_item_cls.from_parent(parent,
path=Path(path))
- elif PYTEST_GE_5_4:
- return self._doctest_module_item_cls.from_parent(parent,
fspath=path)
- else:
- return self._doctest_module_item_cls(path, parent)
+ return self._doctest_module_item_cls.from_parent(parent,
path=Path(path))
elif any([path.check(fnmatch=pat) for pat in self._file_globs]):
# Ignore generated .rst files
@@ -811,12 +783,7 @@
# TODO: Get better names on these items when they are
# displayed in py.test output
- if PYTEST_GE_7_0:
- return self._doctest_textfile_item_cls.from_parent(parent,
path=Path(path))
- elif PYTEST_GE_5_4:
- return self._doctest_textfile_item_cls.from_parent(parent,
fspath=path)
- else:
- return self._doctest_textfile_item_cls(path, parent)
+ return self._doctest_textfile_item_cls.from_parent(parent,
path=Path(path))
class DocTestFinderPlus(doctest.DocTestFinder):
@@ -879,14 +846,17 @@
if hasattr(obj, '__doctest_skip__') or hasattr(obj,
'__doctest_requires__'):
- def test_filter(test):
+ def conditionally_insert_skip(test):
+ """
+ Insert skip statement if `test` matches
`__doctest_(skip|requires)__`.
+ """
for pat in getattr(obj, '__doctest_skip__', []):
if pat == '*':
- return False
+ self._prepend_skip(test)
elif pat == '.' and test.name == name:
- return False
+ self._prepend_skip(test)
elif fnmatch.fnmatch(test.name, '.'.join((name, pat))):
- return False
+ self._prepend_skip(test)
reqs = getattr(obj, '__doctest_requires__', {})
for pats, mods in reqs.items():
@@ -903,14 +873,41 @@
else:
continue # The pattern does not apply
- if not self.check_required_modules(mods):
- return False
+ for mod in mods:
+ self._prepend_module_check(test, module=mod)
return True
- tests = list(filter(test_filter, tests))
+ for _test in tests:
+ conditionally_insert_skip(_test)
return tests
+ def _prepend_skip(self, test):
+ """Prepends `pytest.skip` before the doctest."""
+ source = (
+ "import pytest; "
+ "pytest.skip('listed in `__doctest_skip__`'); "
+ # Don't impact what's available in the namespace
+ "del pytest"
+ )
+ importorskip = doctest.Example(source=source, want="")
+ test.examples.insert(0, importorskip)
+
+ def _prepend_module_check(self, test, *, module):
+ """Prepends module checker before the doctest."""
+ escaped_module = module.replace("'", "\\'")
+ source = (
+ "from pytest_doctestplus.utils import ModuleChecker; "
+ "import pytest; "
+ # Hide output of this statement in `___`, otherwise doctests fail
+ f"___ = ModuleChecker().check('{escaped_module}') or "
+ f"pytest.skip('could not import {escaped_module}'); "
+ # Don't impact what's available in the namespace
+ "del ModuleChecker, pytest, ___"
+ )
+ module_check = doctest.Example(source=source, want="")
+ test.examples.insert(0, module_check)
+
def write_modified_file(fname, new_fname, changes, encoding=None):
# Sort in reversed order to edit the lines:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/pytest_doctestplus/sphinx/doctestplus.py
new/pytest_doctestplus-1.7.1/pytest_doctestplus/sphinx/doctestplus.py
--- old/pytest_doctestplus-1.5.0/pytest_doctestplus/sphinx/doctestplus.py
2025-10-18 04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/pytest_doctestplus/sphinx/doctestplus.py
2026-01-26 23:13:09.000000000 +0100
@@ -10,29 +10,30 @@
tests.
"""
import re
-from docutils.nodes import literal_block
from docutils.parsers.rst import Directive
+from sphinx.util.docutils import SphinxDirective
+class NoRunDirective(Directive):
+ def run(self):
+ # Simply do not add any content when this directive is encountered
+ return []
-class DoctestSkipDirective(Directive):
+
+class DoctestSkipDirective(SphinxDirective):
has_content = True
def run(self):
# Check if there is any valid argument, and skip it. Currently only
# 'win32' is supported.
- if re.match('win32', self.content[0]):
+ if len(self.content) > 0 and re.match("win32", self.content[0]):
self.content = self.content[2:]
- code = '\n'.join(self.content)
- return [literal_block(code, code)]
+ nodes = self.parse_content_to_nodes()
+ return nodes
-class DoctestOmitDirective(Directive):
+class DoctestOmitDirective(NoRunDirective):
has_content = True
- def run(self):
- # Simply do not add any content when this directive is encountered
- return []
-
class DoctestRequiresDirective(DoctestSkipDirective):
# This is silly, but we really support an unbounded number of
@@ -40,15 +41,20 @@
optional_arguments = 64
+class DoctestAllDirective(NoRunDirective):
+ optional_arguments = 64
+ has_content = False
+
+
def setup(app):
app.add_directive('doctest-requires', DoctestRequiresDirective)
- app.add_directive('doctest-requires-all', DoctestRequiresDirective)
+ app.add_directive('doctest-requires-all', DoctestAllDirective)
app.add_directive('doctest-skip', DoctestSkipDirective)
- app.add_directive('doctest-skip-all', DoctestSkipDirective)
+ app.add_directive('doctest-skip-all', DoctestAllDirective)
app.add_directive('doctest', DoctestSkipDirective, override=True)
app.add_directive('doctest-remote-data', DoctestSkipDirective)
- app.add_directive('doctest-remote-data-all', DoctestSkipDirective)
+ app.add_directive('doctest-remote-data-all', DoctestAllDirective)
# Code blocks that use this directive will not appear in the generated
# documentation. This is intended to hide boilerplate code that is only
# useful for testing documentation using doctest, but does not actually
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/pytest_doctestplus/version.py
new/pytest_doctestplus-1.7.1/pytest_doctestplus/version.py
--- old/pytest_doctestplus-1.5.0/pytest_doctestplus/version.py 2025-10-18
04:00:49.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/pytest_doctestplus/version.py 2026-01-26
23:13:19.000000000 +0100
@@ -28,7 +28,7 @@
commit_id: COMMIT_ID
__commit_id__: COMMIT_ID
-__version__ = version = '1.5.0'
-__version_tuple__ = version_tuple = (1, 5, 0)
+__version__ = version = '1.7.1'
+__version_tuple__ = version_tuple = (1, 7, 1)
-__commit_id__ = commit_id = 'gc6d125607'
+__commit_id__ = commit_id = 'g9c3698d35'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/pytest_doctestplus.egg-info/PKG-INFO
new/pytest_doctestplus-1.7.1/pytest_doctestplus.egg-info/PKG-INFO
--- old/pytest_doctestplus-1.5.0/pytest_doctestplus.egg-info/PKG-INFO
2025-10-18 04:00:49.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/pytest_doctestplus.egg-info/PKG-INFO
2026-01-26 23:13:19.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: pytest-doctestplus
-Version: 1.5.0
+Version: 1.7.1
Summary: Pytest plugin with advanced doctest features.
Home-page: https://github.com/scientific-python/pytest-doctestplus
Author: Scientific Python Developers
@@ -14,18 +14,18 @@
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Utilities
-Requires-Python: >=3.9
+Requires-Python: >=3.10
Description-Content-Type: text/x-rst
License-File: LICENSE.rst
-Requires-Dist: pytest>=4.6
+Requires-Dist: pytest>=7.0
Requires-Dist: packaging>=17.0
Provides-Extra: test
Requires-Dist: numpy; extra == "test"
@@ -289,12 +289,14 @@
.. code-block:: rst
- .. doctest-skip-all
+ .. doctest-skip-all::
- >>> import non_existing
- >>> non_existing.write_pseudo_code()
- All the doctests are skipped in the file below
+ All the doctests are skipped in the file below
+ .. code-block::
+
+ >>> import non_existing
+ >>> non_existing.write_pseudo_code()
Skip Unconditionally
^^^^^^^^^^^^^^^^^^^^
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/pytest_doctestplus.egg-info/SOURCES.txt
new/pytest_doctestplus-1.7.1/pytest_doctestplus.egg-info/SOURCES.txt
--- old/pytest_doctestplus-1.5.0/pytest_doctestplus.egg-info/SOURCES.txt
2025-10-18 04:00:49.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/pytest_doctestplus.egg-info/SOURCES.txt
2026-01-26 23:13:19.000000000 +0100
@@ -4,6 +4,7 @@
LICENSE.rst
MANIFEST.in
README.rst
+conftest.py
pyproject.toml
setup.cfg
setup.py
@@ -37,6 +38,8 @@
tests/test_doctestplus.py
tests/test_encoding.py
tests/test_utils.py
+tests/docs/remotedata_all.rst
+tests/docs/requires_all.rst
tests/docs/skip_all.rst
tests/docs/skip_all.tex
tests/docs/skip_some.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/pytest_doctestplus.egg-info/requires.txt
new/pytest_doctestplus-1.7.1/pytest_doctestplus.egg-info/requires.txt
--- old/pytest_doctestplus-1.5.0/pytest_doctestplus.egg-info/requires.txt
2025-10-18 04:00:49.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/pytest_doctestplus.egg-info/requires.txt
2026-01-26 23:13:19.000000000 +0100
@@ -1,4 +1,4 @@
-pytest>=4.6
+pytest>=7.0
packaging>=17.0
[test]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/setup.cfg
new/pytest_doctestplus-1.7.1/setup.cfg
--- old/pytest_doctestplus-1.5.0/setup.cfg 2025-10-18 04:00:49.325532000
+0200
+++ new/pytest_doctestplus-1.7.1/setup.cfg 2026-01-26 23:13:19.277869700
+0100
@@ -11,11 +11,11 @@
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
- Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
+ Programming Language :: Python :: 3.14
Programming Language :: Python :: Implementation :: CPython
Topic :: Software Development :: Testing
Topic :: Utilities
@@ -28,11 +28,11 @@
[options]
zip_safe = False
packages = find:
-python_requires = >=3.9
+python_requires = >=3.10
setup_requires =
setuptools_scm
install_requires =
- pytest>=4.6
+ pytest>=7.0
packaging>=17.0
[options.extras_require]
@@ -51,7 +51,7 @@
tests
[tool:pytest]
-minversion = 4.6
+minversion = 7.0
testpaths = tests pytest_doctestplus
xfail_strict = true
filterwarnings =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/tests/conftest.py
new/pytest_doctestplus-1.7.1/tests/conftest.py
--- old/pytest_doctestplus-1.5.0/tests/conftest.py 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/tests/conftest.py 2026-01-26
23:13:09.000000000 +0100
@@ -1,11 +1,10 @@
-from functools import partial
import textwrap
+from functools import partial
from packaging.version import Version
import pytest
import numpy as np
-
# Keep this until we require numpy to be >=2.0 or there is a directive in
doctestplus
# to support multiple ways of repr
if Version(np.__version__) >= Version("2.0.dev"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/tests/docs/remotedata_all.rst
new/pytest_doctestplus-1.7.1/tests/docs/remotedata_all.rst
--- old/pytest_doctestplus-1.5.0/tests/docs/remotedata_all.rst 1970-01-01
01:00:00.000000000 +0100
+++ new/pytest_doctestplus-1.7.1/tests/docs/remotedata_all.rst 2026-01-26
23:13:09.000000000 +0100
@@ -0,0 +1,20 @@
+:orphan:
+
+.. doctest-remote-data-all::
+
+.. _label_to_check_that_no_content_works_probably_unnecessary2:
+
+Some Bad Test Cases
+*******************
+
+All of the example code blocks in this file are going to fail if they run. So
+if the directive used at the top of this file does not work, then there are
+going to be test failures.
+
+Undefined Variables
+===================
+
+This one will fail because the variables haven't been defined::
+
+ >>> 2 + 3
+ 5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/tests/docs/requires_all.rst
new/pytest_doctestplus-1.7.1/tests/docs/requires_all.rst
--- old/pytest_doctestplus-1.5.0/tests/docs/requires_all.rst 1970-01-01
01:00:00.000000000 +0100
+++ new/pytest_doctestplus-1.7.1/tests/docs/requires_all.rst 2026-01-26
23:13:09.000000000 +0100
@@ -0,0 +1,38 @@
+:orphan:
+
+.. doctest-requires-all:: asdfasdfasdf
+
+.. _label_to_check_that_no_content_works_probably_unnecessary:
+
+Some Bad Test Cases
+*******************
+
+All of the example code blocks in this file are going to fail if they run. So
+if the directive used at the top of this file does not work, then there are
+going to be test failures.
+
+Undefined Variables
+===================
+
+This one will fail because the variables haven't been defined::
+
+ >>> x + y
+ 5
+
+No Such Module
+==============
+
+This one will fail because there's (probably) no such module::
+
+ >>> import foobar
+ >>> foobar.baz(42)
+ 0
+
+What???
+=======
+
+This one will fail because it's just not valid python::
+
+ >>> NOT VALID PYTHON, OKAY?
+ >>> + 5
+ 10
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/tests/docs/skip_some.rst
new/pytest_doctestplus-1.7.1/tests/docs/skip_some.rst
--- old/pytest_doctestplus-1.5.0/tests/docs/skip_some.rst 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/tests/docs/skip_some.rst 2026-01-26
23:13:09.000000000 +0100
@@ -102,3 +102,41 @@
.. doctest-requires:: pytest>=1.0 pytest>=2.0
>>> import pytest
+
+
+Combined Directives
+===================
+
+
+Marking code with two directives:
+
+.. deprecated:: 1.0
+.. doctest-requires:: numpy<=0.1
+
+ >>> 1 + 3
+ 2
+
+
+The order should not matter:
+
+.. doctest-requires:: numpy<=0.1
+.. deprecated:: 1.0
+
+ >>> 1 + 3
+ 2
+
+Try two doctestplus directives:
+
+.. doctest-requires:: sys
+.. doctest-skip::
+
+ >>> 1 + 3
+ 2
+
+Switch the order and it should still not run:
+
+.. doctest-skip::
+.. doctest-requires:: sys
+
+ >>> 1 + 3
+ 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_doctestplus-1.5.0/tests/docs/skip_some_remote_data.rst
new/pytest_doctestplus-1.7.1/tests/docs/skip_some_remote_data.rst
--- old/pytest_doctestplus-1.5.0/tests/docs/skip_some_remote_data.rst
2025-10-18 04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/tests/docs/skip_some_remote_data.rst
2026-01-26 23:13:09.000000000 +0100
@@ -87,6 +87,8 @@
.. doctest-remote-data-all::
+.. code-block::
+
>>> 1 + 1
3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/tests/test_doctestplus.py
new/pytest_doctestplus-1.7.1/tests/test_doctestplus.py
--- old/pytest_doctestplus-1.5.0/tests/test_doctestplus.py 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/tests/test_doctestplus.py 2026-01-26
23:13:09.000000000 +0100
@@ -1,8 +1,8 @@
import glob
import os
+import sys
from platform import python_version
from textwrap import dedent
-import sys
from packaging.version import Version
@@ -24,9 +24,6 @@
pytest_plugins = ['pytester']
-PYTEST_LT_6 = Version(pytest.__version__) < Version('6.0.0')
-
-
def test_ignored_whitespace(testdir):
testdir.makeini(
"""
@@ -450,6 +447,7 @@
"""
.. doctest-requires-all:: foobar
+ .. code-block::
>>> import foobar
This is a narrative line, before another doctest snippet
@@ -862,8 +860,6 @@
@pytest.fixture()
def subpackage_requires_testdir(testdir, request):
- if request.param[0] == 'makepyprojecttoml' and PYTEST_LT_6:
- return None, None
config_file = getattr(testdir, request.param[0])(request.param[1])
@@ -901,7 +897,6 @@
@pytest.mark.parametrize(('import_mode', 'expected'), [
- pytest.param('importlib', dict(passed=2),
marks=pytest.mark.skipif(PYTEST_LT_6, reason="importlib import mode not
supported on Pytest <6"), id="importlib"),
pytest.param('append', dict(failed=1), id="append"),
pytest.param('prepend', dict(failed=1), id="prepend"),
])
@@ -963,6 +958,8 @@
.. doctest-remote-data-all::
+ .. code-block::
+
>>> from contextlib import closing
>>> from urllib.request import urlopen
>>> with closing(urlopen('https://www.astropy.org')) as remote:
@@ -1387,8 +1384,6 @@
@pytest.fixture()
def norecursedirs_testdir(testdir, request):
- if request.param[0] == 'makepyprojecttoml' and PYTEST_LT_6:
- return None, None
config_file = getattr(testdir, request.param[0])(request.param[1])
@@ -1542,3 +1537,79 @@
original_fixed = original.replace("1\n 2", "\n ".join(["0", "1",
"2", "3"]))
assert result == original_fixed
+
+
+def test_skip_module_variable(testdir):
+ p = testdir.makepyfile("""
+ __doctest_skip__ = ["f"]
+
+ def f():
+ '''
+ >>> 1 + 2
+ 5
+ '''
+ pass
+
+ def g():
+ '''
+ >>> 1 + 1
+ 2
+ '''
+ pass
+ """)
+ testdir.inline_run(p, '--doctest-plus').assertoutcome(passed=1, skipped=1)
+
+
+def test_requires_module_variable(testdir):
+ p = testdir.makepyfile("""
+ __doctest_requires__ = {
+ ("f",): ["module_that_is_not_availabe"],
+ ("g",): ["pytest"],
+ ("h",): ["pytest>=1.0"],
+ ("i",): ["pytest<1.0"],
+ ("j",): ["module_that_is_not_availabe>=1.0"],
+ }
+
+ def f():
+ '''
+ >>> import module_that_is_not_availabe
+ '''
+ pass
+
+ def g():
+ '''
+ Make sure our internal variables are not visible.
+
+ >>> assert "ModuleChecker" not in locals()
+ >>> assert "pytest" not in locals()
+ >>> assert "___" not in locals()
+ >>> 1 + 1
+ 2
+ '''
+ pass
+
+ def h():
+ '''
+ Make sure our internal variables are not visible.
+
+ >>> assert "ModuleChecker" not in locals()
+ >>> assert "pytest" not in locals()
+ >>> assert "___" not in locals()
+ >>> 1 + 1
+ 2
+ '''
+ pass
+
+ def i():
+ '''
+ >>> assert False, "This should be skipped due to version
requirement not being met"
+ '''
+ pass
+
+ def j():
+ '''
+ >>> import module_that_is_not_availabe
+ '''
+ pass
+ """)
+ testdir.inline_run(p, '--doctest-plus').assertoutcome(passed=2, skipped=3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/tests/test_encoding.py
new/pytest_doctestplus-1.7.1/tests/test_encoding.py
--- old/pytest_doctestplus-1.5.0/tests/test_encoding.py 2025-10-18
04:00:38.000000000 +0200
+++ new/pytest_doctestplus-1.7.1/tests/test_encoding.py 2026-01-26
23:13:09.000000000 +0100
@@ -2,7 +2,8 @@
import os
from pathlib import Path
from textwrap import dedent
-from typing import Callable, Optional
+from typing import Optional
+from collections.abc import Callable
import pytest
@@ -66,7 +67,7 @@
def ini_file(testdir) -> Callable[..., Path]:
def makeini(
- encoding: Optional[str] = None,
+ encoding: str | None = None,
) -> Path:
"""Create a pytest.ini file with the specified encoding."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_doctestplus-1.5.0/tox.ini
new/pytest_doctestplus-1.7.1/tox.ini
--- old/pytest_doctestplus-1.5.0/tox.ini 2025-10-18 04:00:38.000000000
+0200
+++ new/pytest_doctestplus-1.7.1/tox.ini 2026-01-26 23:13:09.000000000
+0100
@@ -1,6 +1,6 @@
[tox]
envlist =
- py{39,310,311,312,313,314}-test
+ py{310,311,312,313,314}-test
codestyle
requires =
setuptools >= 30.3.0
@@ -14,15 +14,7 @@
numpydev: PIP_EXTRA_INDEX_URL =
https://pypi.anaconda.org/scientific-python-nightly-wheels/simple
description = run tests
deps =
- pytestoldest: pytest==4.6.0
- pytest50: pytest==5.0.*
- pytest51: pytest==5.1.*
- pytest52: pytest==5.2.*
- pytest53: pytest==5.3.*
- pytest60: pytest==6.0.*
- pytest61: pytest==6.1.*
- pytest62: pytest==6.2.*
- pytest70: pytest==7.0.*
+ pytestoldest: pytest==7.0.0
pytest71: pytest==7.1.*
pytest72: pytest==7.2.*
pytest73: pytest==7.3.*