Skip to content

Commit d9d6c97

Browse files
author
Nikolay Kondratyev
committed
Fix line detection for properties in doctest tests
Grammar fix Co-Authored-By: Daniel Hahler <[email protected]> Add python issue link Explicit check for the property Test when lineno is not detected Fix changelog entry
1 parent 85288b5 commit d9d6c97

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

changelog/6082.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix line detection for doctest samples inside ``property`` docstrings, as workaround to `bpo-17446 <https://bugs.python.org/issue17446>`__.

src/_pytest/doctest.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,16 @@ class MockAwareDocTestFinder(doctest.DocTestFinder):
401401
https://bugs.python.org/issue25532
402402
"""
403403

404+
def _find_lineno(self, obj, source_lines):
405+
"""
406+
Doctest code does not take into account @property, hackish way to fix it.
407+
408+
https://bugs.python.org/issue17446
409+
"""
410+
if isinstance(obj, property):
411+
obj = getattr(obj, "fget", obj)
412+
return doctest.DocTestFinder._find_lineno(self, obj, source_lines)
413+
404414
def _find(self, tests, obj, name, module, source_lines, globs, seen):
405415
if _is_mocked(obj):
406416
return

testing/test_doctest.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,50 @@ def test(self):
287287
)
288288
)
289289
result = testdir.runpytest("--doctest-modules")
290+
result.stdout.fnmatch_lines(
291+
["*hello*", "006*>>> 1/0*", "*UNEXPECTED*ZeroDivision*", "*1 failed*"]
292+
)
293+
294+
def test_doctest_linedata_on_property(self, testdir):
295+
testdir.tmpdir.join("hello.py").write(
296+
textwrap.dedent(
297+
"""\
298+
class Sample(object):
299+
@property
300+
def some_property(self):
301+
'''
302+
>>> Sample().some_property
303+
'another thing'
304+
'''
305+
return 'something'
306+
"""
307+
)
308+
)
309+
result = testdir.runpytest("--doctest-modules")
310+
result.stdout.fnmatch_lines(["*hello*", "005*>>> Sample().some_property"])
311+
312+
def test_doctest_no_linedata_on_overriden_property(self, testdir):
313+
testdir.tmpdir.join("hello.py").write(
314+
textwrap.dedent(
315+
"""\
316+
class Sample(object):
317+
@property
318+
def some_property(self):
319+
'''
320+
>>> Sample().some_property
321+
'another thing'
322+
'''
323+
return 'something'
324+
some_property = property(some_property.__get__, None, None, some_property.__doc__)
325+
"""
326+
)
327+
)
328+
result = testdir.runpytest("--doctest-modules")
290329
result.stdout.fnmatch_lines(
291330
[
292331
"*hello*",
293332
"*EXAMPLE LOCATION UNKNOWN, not showing all tests of that example*",
294-
"*1/0*",
295-
"*UNEXPECTED*ZeroDivision*",
296-
"*1 failed*",
333+
"???*>>> Sample().some_property",
297334
]
298335
)
299336

0 commit comments

Comments
 (0)