https://github.com/python/cpython/commit/653ed76442d2988e587f4da1fc1cf1bd2bb51fbb
commit: 653ed76442d2988e587f4da1fc1cf1bd2bb51fbb
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: AlexWaygood <[email protected]>
date: 2024-04-10T14:17:15Z
summary:

[3.12] gh-117692: Fix `AttributeError` in `DocTestFinder` on wrapped 
`builtin_or_method` (GH-117699) (#117708)

* gh-117692: Fix `AttributeError` in `DocTestFinder` on wrapped 
`builtin_or_method` (GH-117699)
(cherry picked from commit 4bb7d121bc0a3fd00a3c72cd915b5dd8fac5616e)

Co-authored-by: Nikita Sobolev <[email protected]>
Co-authored-by: Alex Waygood <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-04-09-23-22-21.gh-issue-117692.EciInD.rst
M Lib/doctest.py
M Lib/test/test_doctest/test_doctest.py

diff --git a/Lib/doctest.py b/Lib/doctest.py
index 696bb966549255..d617d96a35a85a 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -1124,7 +1124,14 @@ def _find_lineno(self, obj, source_lines):
             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 = inspect.unwrap(obj).__code__
+            obj = inspect.unwrap(obj)
+            try:
+                obj = obj.__code__
+            except AttributeError:
+                # Functions implemented in C don't necessarily
+                # have a __code__ attribute.
+                # If there's no code, there's no lineno
+                return None
         if inspect.istraceback(obj): obj = obj.tb_frame
         if inspect.isframe(obj): obj = obj.f_code
         if inspect.iscode(obj):
diff --git a/Lib/test/test_doctest/test_doctest.py 
b/Lib/test/test_doctest/test_doctest.py
index 9c8a8ba690d557..2722661a2363fe 100644
--- a/Lib/test/test_doctest/test_doctest.py
+++ b/Lib/test/test_doctest/test_doctest.py
@@ -2496,6 +2496,20 @@ def test_look_in_unwrapped():
     'one other test'
     """
 
+if support.check_impl_detail(cpython=True):
+    def test_wrapped_c_func():
+        """
+        # https://github.com/python/cpython/issues/117692
+        >>> import binascii
+        >>> from test.test_doctest.decorator_mod import decorator
+
+        >>> c_func_wrapped = decorator(binascii.b2a_hex)
+        >>> tests = 
doctest.DocTestFinder(exclude_empty=False).find(c_func_wrapped)
+        >>> for test in tests:
+        ...    print(test.lineno, test.name)
+        None b2a_hex
+        """
+
 def test_unittest_reportflags():
     """Default unittest reporting flags can be set to control reporting
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-04-09-23-22-21.gh-issue-117692.EciInD.rst 
b/Misc/NEWS.d/next/Library/2024-04-09-23-22-21.gh-issue-117692.EciInD.rst
new file mode 100644
index 00000000000000..98a6e125c440ef
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-04-09-23-22-21.gh-issue-117692.EciInD.rst
@@ -0,0 +1,2 @@
+Fixes a bug when :class:`doctest.DocTestFinder` was failing on wrapped
+``builtin_function_or_method``.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to