Skip to content

Commit 0191563

Browse files
authored
DoctTest line numbers not found due to method wrapping (#8861)
Closes #8796
1 parent 1de5c07 commit 0191563

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ David Vierra
9696
Daw-Ran Liou
9797
Debi Mishra
9898
Denis Kirisov
99+
Denivy Braiam Rück
99100
Dhiren Serai
100101
Diego Russo
101102
Dmitry Dygalo

changelog/8796.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed internal error when skipping doctests.

src/_pytest/doctest.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,12 +504,18 @@ class MockAwareDocTestFinder(doctest.DocTestFinder):
504504

505505
def _find_lineno(self, obj, source_lines):
506506
"""Doctest code does not take into account `@property`, this
507-
is a hackish way to fix it.
507+
is a hackish way to fix it. https://bugs.python.org/issue17446
508508
509-
https://bugs.python.org/issue17446
509+
Wrapped Doctests will need to be unwrapped so the correct
510+
line number is returned. This will be reported upstream. #8796
510511
"""
511512
if isinstance(obj, property):
512513
obj = getattr(obj, "fget", obj)
514+
515+
if hasattr(obj, "__wrapped__"):
516+
# Get the main obj in case of it being wrapped
517+
obj = inspect.unwrap(obj)
518+
513519
# Type ignored because this is a private function.
514520
return super()._find_lineno( # type:ignore[misc]
515521
obj,

testing/test_doctest.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,41 @@ def test_continue_on_failure(self, pytester: Pytester):
11701170
["*4: UnexpectedException*", "*5: DocTestFailure*", "*8: DocTestFailure*"]
11711171
)
11721172

1173+
def test_skipping_wrapped_test(self, pytester):
1174+
"""
1175+
Issue 8796: INTERNALERROR raised when skipping a decorated DocTest
1176+
through pytest_collection_modifyitems.
1177+
"""
1178+
pytester.makeconftest(
1179+
"""
1180+
import pytest
1181+
from _pytest.doctest import DoctestItem
1182+
1183+
def pytest_collection_modifyitems(config, items):
1184+
skip_marker = pytest.mark.skip()
1185+
1186+
for item in items:
1187+
if isinstance(item, DoctestItem):
1188+
item.add_marker(skip_marker)
1189+
"""
1190+
)
1191+
1192+
pytester.makepyfile(
1193+
"""
1194+
from contextlib import contextmanager
1195+
1196+
@contextmanager
1197+
def my_config_context():
1198+
'''
1199+
>>> import os
1200+
'''
1201+
"""
1202+
)
1203+
1204+
result = pytester.runpytest("--doctest-modules")
1205+
assert "INTERNALERROR" not in result.stdout.str()
1206+
result.assert_outcomes(skipped=1)
1207+
11731208

11741209
class TestDoctestAutoUseFixtures:
11751210

0 commit comments

Comments
 (0)