DoctTest line numbers not found due to method wrapping (#8861)

Closes #8796
This commit is contained in:
denivyruck 2021-11-01 04:01:25 -03:00 committed by GitHub
parent 1de5c07b95
commit 0191563fd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 2 deletions

View File

@ -96,6 +96,7 @@ David Vierra
Daw-Ran Liou Daw-Ran Liou
Debi Mishra Debi Mishra
Denis Kirisov Denis Kirisov
Denivy Braiam Rück
Dhiren Serai Dhiren Serai
Diego Russo Diego Russo
Dmitry Dygalo Dmitry Dygalo

View File

@ -0,0 +1 @@
Fixed internal error when skipping doctests.

View File

@ -504,12 +504,18 @@ class DoctestModule(pytest.Module):
def _find_lineno(self, obj, source_lines): def _find_lineno(self, obj, source_lines):
"""Doctest code does not take into account `@property`, this """Doctest code does not take into account `@property`, this
is a hackish way to fix it. is a hackish way to fix it. https://bugs.python.org/issue17446
https://bugs.python.org/issue17446 Wrapped Doctests will need to be unwrapped so the correct
line number is returned. This will be reported upstream. #8796
""" """
if isinstance(obj, property): if isinstance(obj, property):
obj = getattr(obj, "fget", obj) obj = getattr(obj, "fget", obj)
if hasattr(obj, "__wrapped__"):
# Get the main obj in case of it being wrapped
obj = inspect.unwrap(obj)
# Type ignored because this is a private function. # Type ignored because this is a private function.
return super()._find_lineno( # type:ignore[misc] return super()._find_lineno( # type:ignore[misc]
obj, obj,

View File

@ -1170,6 +1170,41 @@ class TestDoctestSkips:
["*4: UnexpectedException*", "*5: DocTestFailure*", "*8: DocTestFailure*"] ["*4: UnexpectedException*", "*5: DocTestFailure*", "*8: DocTestFailure*"]
) )
def test_skipping_wrapped_test(self, pytester):
"""
Issue 8796: INTERNALERROR raised when skipping a decorated DocTest
through pytest_collection_modifyitems.
"""
pytester.makeconftest(
"""
import pytest
from _pytest.doctest import DoctestItem
def pytest_collection_modifyitems(config, items):
skip_marker = pytest.mark.skip()
for item in items:
if isinstance(item, DoctestItem):
item.add_marker(skip_marker)
"""
)
pytester.makepyfile(
"""
from contextlib import contextmanager
@contextmanager
def my_config_context():
'''
>>> import os
'''
"""
)
result = pytester.runpytest("--doctest-modules")
assert "INTERNALERROR" not in result.stdout.str()
result.assert_outcomes(skipped=1)
class TestDoctestAutoUseFixtures: class TestDoctestAutoUseFixtures: