mirror of
https://github.com/python/cpython.git
synced 2025-11-01 14:11:41 +00:00
gh-136914: Fix support of cached functions and properties in DocTest's lineno computation (GH-136930)
Previously, DocTest's lineno of functions and methods decorated with functools.cache(), functools.lru_cache() and functools.cached_property() was not properly returned (None was returned) because the computation relied on inspect.isfunction() which does not consider the decorated result as a function. We now use the more generic inspect.isroutine(), as elsewhere in doctest's logic. Also, added a special case for functools.cached_property().
This commit is contained in:
parent
d5e75c0768
commit
fece15d29f
4 changed files with 39 additions and 1 deletions
|
|
@ -94,6 +94,7 @@ def _test():
|
|||
|
||||
import __future__
|
||||
import difflib
|
||||
import functools
|
||||
import inspect
|
||||
import linecache
|
||||
import os
|
||||
|
|
@ -1141,7 +1142,9 @@ def _find_lineno(self, obj, source_lines):
|
|||
if inspect.ismethod(obj): obj = obj.__func__
|
||||
if isinstance(obj, property):
|
||||
obj = obj.fget
|
||||
if inspect.isfunction(obj) and getattr(obj, '__doc__', None):
|
||||
if isinstance(obj, functools.cached_property):
|
||||
obj = obj.func
|
||||
if inspect.isroutine(obj) and getattr(obj, '__doc__', None):
|
||||
# We don't use `docstring` var here, because `obj` can be changed.
|
||||
obj = inspect.unwrap(obj)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -76,3 +76,32 @@ def property_with_doctest(self):
|
|||
@decorator
|
||||
def func_with_docstring_wrapped():
|
||||
"""Some unrelated info."""
|
||||
|
||||
|
||||
# https://github.com/python/cpython/issues/136914
|
||||
import functools
|
||||
|
||||
|
||||
@functools.cache
|
||||
def cached_func_with_doctest(value):
|
||||
"""
|
||||
>>> cached_func_with_doctest(1)
|
||||
-1
|
||||
"""
|
||||
return -value
|
||||
|
||||
|
||||
@functools.cache
|
||||
def cached_func_without_docstring(value):
|
||||
return value + 1
|
||||
|
||||
|
||||
class ClassWithACachedProperty:
|
||||
|
||||
@functools.cached_property
|
||||
def cached(self):
|
||||
"""
|
||||
>>> X().cached
|
||||
-1
|
||||
"""
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -678,6 +678,8 @@ def basics(): r"""
|
|||
>>> for t in tests:
|
||||
... print('%5s %s' % (t.lineno, t.name))
|
||||
None test.test_doctest.doctest_lineno
|
||||
None test.test_doctest.doctest_lineno.ClassWithACachedProperty
|
||||
102 test.test_doctest.doctest_lineno.ClassWithACachedProperty.cached
|
||||
22 test.test_doctest.doctest_lineno.ClassWithDocstring
|
||||
30 test.test_doctest.doctest_lineno.ClassWithDoctest
|
||||
None test.test_doctest.doctest_lineno.ClassWithoutDocstring
|
||||
|
|
@ -687,6 +689,8 @@ def basics(): r"""
|
|||
45 test.test_doctest.doctest_lineno.MethodWrapper.method_with_doctest
|
||||
None test.test_doctest.doctest_lineno.MethodWrapper.method_without_docstring
|
||||
61 test.test_doctest.doctest_lineno.MethodWrapper.property_with_doctest
|
||||
86 test.test_doctest.doctest_lineno.cached_func_with_doctest
|
||||
None test.test_doctest.doctest_lineno.cached_func_without_docstring
|
||||
4 test.test_doctest.doctest_lineno.func_with_docstring
|
||||
77 test.test_doctest.doctest_lineno.func_with_docstring_wrapped
|
||||
12 test.test_doctest.doctest_lineno.func_with_doctest
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Fix retrieval of :attr:`doctest.DocTest.lineno` for objects decorated with
|
||||
:func:`functools.cache` or :class:`functools.cached_property`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue