如何在旧Python版本下跳过含f-string的Sphinx .rst doctest文件测试
Got it, let's tackle this problem step by step. The core issue here is that even with :skipif: or :pyversion: markers, the doctest parser tries to parse the f-string code first in Python 2.7/3.5, hitting a SyntaxError before it can check the skip conditions. Here are a couple of solid workarounds that don't require explicitly ignoring the file in pytest arguments:
Method 1: Use a Pytest Hook to Conditionally Skip the File
Create a conftest.py file in your project root directory. This file lets you customize pytest's behavior at runtime. We'll add a hook that checks the Python version and skips the target RST file only in old versions:
import sys import pytest def pytest_collection_modifyitems(config, items): # Replace this with the actual path to your RST file (e.g., "docs/fstring_examples.rst") target_rst = "path/to/your/fstring_docs.rst" # Check if we're running on Python 2.7 or 3.5 skip_versions = ((2, 7), (3, 5)) if sys.version_info[:2] in skip_versions: for item in items: # Skip any test item associated with the target RST file if target_rst in item.nodeid: item.add_marker( pytest.mark.skip(reason="f-strings not supported in Python 2.7/3.5") )
This works because pytest collects all test items first, and we modify the collection to skip the relevant items before any code parsing happens. No SyntaxError, no need to exclude the file from --doctest-glob.
Method 2: Use Sphinx's .. only:: Directive to Hide the Doctest Block
If you're building docs with Sphinx, you can wrap the f-string doctest block in a version-specific directive. This way, the block isn't even included in the parsed content for older Python versions:
.. only:: py>=3.6 .. doctest:: >>> name = "Bob" >>> print(f"Hi, {name}!") Hi, Bob!
To make sure pytest's doctest plugin recognizes this Sphinx directive, you'll need to install pytest-doctestplus (a more feature-rich alternative to pytest's default doctest support):
pip install pytest-doctestplus
Then update your tox commands to use it (though it should work automatically once installed):
[testenv] commands = pytest --doctest-glob='*.rst' deps = pytest pytest-doctestplus
This approach ensures the f-string code is never seen by the parser in Python 2.7/3.5, avoiding the SyntaxError entirely.
Bonus: Verify Tox Configuration
Double-check your tox.ini to make sure each environment is set up correctly. Here's a minimal example:
[tox] envlist = py27,py35,py36,py37,py38 skipsdist = true # Skip building a distribution if you don't need it [testenv] commands = pytest --doctest-glob='*.rst' deps = pytest pytest-doctestplus # Only needed if using Method 2
Both methods let you keep the RST file in your test suite without explicit ignores, and handle the version-specific skip gracefully.
内容的提问来源于stack exchange,提问作者azmeuk

