obj = obj.fget
if inspect.isfunction(obj) and getattr(obj, '__doc__', None):
# We don't use `docstring` var here, because `obj` can be changed.
- obj = obj.__code__
+ obj = inspect.unwrap(obj).__code__
if inspect.istraceback(obj): obj = obj.tb_frame
if inspect.isframe(obj): obj = obj.f_code
if inspect.iscode(obj):
--- /dev/null
+# This module is used in `doctest_lineno.py`.
+import functools
+
+
+def decorator(f):
+ @functools.wraps(f)
+ def inner():
+ return f()
+
+ return inner
# https://github.com/python/cpython/issues/99433
str_wrapper = object().__str__
+
+
+# https://github.com/python/cpython/issues/115392
+from test.test_doctest.decorator_mod import decorator
+
+@decorator
+@decorator
+def func_with_docstring_wrapped():
+ """Some unrelated info."""
None test.test_doctest.doctest_lineno.MethodWrapper.method_without_docstring
61 test.test_doctest.doctest_lineno.MethodWrapper.property_with_doctest
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
None test.test_doctest.doctest_lineno.func_without_docstring
--- /dev/null
+Fix a bug in :mod:`doctest` where incorrect line numbers would be
+reported for decorated functions.