]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-153903: Fix ctypes wrap_dll_function() with string annotations (#154042)
authorVictor Stinner <vstinner@python.org>
Sun, 19 Jul 2026 10:04:40 +0000 (12:04 +0200)
committerGitHub <noreply@github.com>
Sun, 19 Jul 2026 10:04:40 +0000 (12:04 +0200)
Call get_annotations() with eval_str=True.

Lib/ctypes/util.py
Lib/test/test_ctypes/test_funcptr.py
Lib/test/test_ctypes/wrap_str_ann.py [new file with mode: 0644]

index b035bfb99feee0aaf43c695d4b901119d8ffe133..c65fc3032fdfad4833e0342f1a2b20d016a60478 100644 (file)
@@ -579,7 +579,7 @@ def wrap_dll_function(dll):
     def decorator(func):
         name = func.__name__
         ptr = getattr(dll, name)
-        annotations = annotationlib.get_annotations(func)
+        annotations = annotationlib.get_annotations(func, eval_str=True)
 
         try:
             restype = annotations.pop("return")
index 94d03ad553d2227312f6f27f3886c651b6c98904..86699ad81098275c54340705266ec10a38e07c29 100644 (file)
@@ -151,6 +151,11 @@ class CFuncPtrTestCase(unittest.TestCase, StructCheckMixin):
             def PyObject_GetAttrString(op: ctypes.py_object, attr: ctypes.c_char_p):
                 pass
 
+    def test_wrap_dll_function_str_ann(self):
+        from test.test_ctypes import wrap_str_ann
+        version = wrap_str_ann.Py_GetVersion()
+        self.assertIsInstance(version, bytes)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_ctypes/wrap_str_ann.py b/Lib/test/test_ctypes/wrap_str_ann.py
new file mode 100644 (file)
index 0000000..aa114a6
--- /dev/null
@@ -0,0 +1,13 @@
+from __future__ import annotations
+import ctypes.util
+
+def test_ann() -> ctypes.c_char_p:
+    ...
+
+# Check that "from __future__ import annotations" works as expected
+if not isinstance(test_ann.__annotations__['return'], str):
+    raise Exception("annotations must be strings")
+
+@ctypes.util.wrap_dll_function(ctypes.pythonapi)
+def Py_GetVersion() -> ctypes.c_char_p:
+    ...