From f73783da95f513b233e91cb4e111a09ceda4f4b8 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Wed, 22 Jul 2026 12:20:43 -0400 Subject: [PATCH 1/2] wrap_dll_function: copy doc, etc from wrapped stub --- Doc/library/ctypes.rst | 1 + Lib/ctypes/util.py | 2 ++ Lib/test/test_ctypes/test_funcptr.py | 2 ++ 3 files changed, 5 insertions(+) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 34c8636abaa925d..1a10267bd628eb8 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -708,6 +708,7 @@ Specifying function pointers using type annotations @wrap_dll_function(dll_to_wrap) def function_ptr_name(arg_name: ctypes_type, ...) -> ctypes_type: + """Optional docstring.""" # There should be no body pass diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index a73422598b2cd96..1f2b9cf0e3ce8dd 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -590,6 +590,8 @@ def decorator(func): ptr.restype = restype ptr.argtypes = tuple(annotations.values()) + functools.update_wrapper(ptr, func, updated=()) + return ptr return decorator diff --git a/Lib/test/test_ctypes/test_funcptr.py b/Lib/test/test_ctypes/test_funcptr.py index 86699ad81098275..28ff34f9048454d 100644 --- a/Lib/test/test_ctypes/test_funcptr.py +++ b/Lib/test/test_ctypes/test_funcptr.py @@ -134,12 +134,14 @@ def test_abstract(self): def test_wrap_dll_function(self): @wrap_dll_function(ctypes.pythonapi) def PyObject_GetAttr(op: ctypes.py_object, attr: ctypes.py_object) -> ctypes.py_object: + """Call the PythonAPI function underlying getattr""" pass class Foo: a = "abc" self.assertEqual(PyObject_GetAttr(Foo, "a"), "abc") + self.assertEqual(PyObject_GetAttr.__doc__, "Call the PythonAPI function underlying getattr") with self.assertRaises(AttributeError): @wrap_dll_function(ctypes.pythonapi) From 9d59e7e28cce22468734ed17d84cebcafcfadae3 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Thu, 23 Jul 2026 12:23:42 -0400 Subject: [PATCH 2/2] Documentation updates Co-authored-by: Peter Bierma --- Doc/library/ctypes.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 1a10267bd628eb8..a4de7cb09cca9da 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -708,9 +708,7 @@ Specifying function pointers using type annotations @wrap_dll_function(dll_to_wrap) def function_ptr_name(arg_name: ctypes_type, ...) -> ctypes_type: - """Optional docstring.""" - # There should be no body - pass + """Optional docstring. There should be no function body.""" The body of the decorated function is ignored, and any parameters that are missing type annotations are skipped. The names of the parameters are ignored