Skip to content

Internal error when adding a skip mark to a doctest inside a contextmanager #8796

@lesteve

Description

@lesteve

To reproduce:

# conftest.py
import pytest
from _pytest.doctest import DoctestItem


def pytest_collection_modifyitems(config, items):
    skip_marker = pytest.mark.skip(reason='Skipping doctests')

    for item in items:
        if isinstance(item, DoctestItem):
            item.add_marker(skip_marker)
# test.py
from contextlib import contextmanager

@contextmanager
def my_config_context():
    """
    >>> import os
    """
❯ pytest test.py --doctest-modules
=========================================================== test session starts ============================================================
platform linux -- Python 3.9.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /tmp
collected 1 item                                                                                                                           

test.py 
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/main.py", line 269, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/main.py", line 323, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR>     self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/main.py", line 348, in pytest_runtestloop
INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR>     self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/runner.py", line 109, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/runner.py", line 120, in runtestprotocol
INTERNALERROR>     rep = call_and_report(item, "setup", log)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/runner.py", line 217, in call_and_report
INTERNALERROR>     report: TestReport = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR>     self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/pluggy/callers.py", line 203, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "/home/lesteve/miniconda3/envs/test/lib/python3.9/site-packages/_pytest/skipping.py", line 314, in pytest_runtest_makereport
INTERNALERROR>     assert line is not None
INTERNALERROR> AssertionError

========================================================== no tests ran in 0.01s ===========================================================

This is a simplified issue from a real use case in the scikit-learn repo. We sometimes want to skip doctests, for example when matplotlib (an optional dependency) is not installed. If there is be a better way to do it with pytest than using pytest_collection_modifyitems, let me know.

conda list output
❯ conda list
# packages in environment at /home/lesteve/miniconda3/envs/test:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main  
_openmp_mutex             4.5                       1_gnu  
attrs                     21.2.0             pyhd3eb1b0_0  
ca-certificates           2021.5.25            h06a4308_1  
certifi                   2021.5.30        py39h06a4308_0  
iniconfig                 1.1.1              pyhd3eb1b0_0  
ld_impl_linux-64          2.35.1               h7274673_9  
libffi                    3.3                  he6710b0_2  
libgcc-ng                 9.3.0               h5101ec6_17  
libgomp                   9.3.0               h5101ec6_17  
libstdcxx-ng              9.3.0               hd4cf53a_17  
more-itertools            8.8.0              pyhd3eb1b0_0  
ncurses                   6.2                  he6710b0_1  
openssl                   1.1.1k               h27cfd23_0  
packaging                 20.9               pyhd3eb1b0_0  
pip                       21.1.2           py39h06a4308_0  
pluggy                    0.13.1           py39h06a4308_0  
py                        1.10.0             pyhd3eb1b0_0  
pyparsing                 2.4.7              pyhd3eb1b0_0  
pytest                    6.2.4            py39h06a4308_2  
python                    3.9.5                h12debd9_4  
readline                  8.1                  h27cfd23_0  
setuptools                52.0.0           py39h06a4308_0  
six                       1.16.0             pyhd3eb1b0_0  
sqlite                    3.36.0               hc218d9a_0  
tk                        8.6.10               hbc83047_0  
toml                      0.10.2             pyhd3eb1b0_0  
tzdata                    2021a                h52ac0ba_0  
wheel                     0.36.2             pyhd3eb1b0_0  
xz                        5.2.5                h7b6447c_0  
zlib                      1.2.11               h7b6447c_3  

Metadata

Metadata

Assignees

No one assigned

    Labels

    plugin: doctestsrelated to the doctests builtin plugintype: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions