gh-153903: Fix ctypes wrap_dll_function() with string annotations (#154042)

vstinner <[email protected]>
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/d5eb31209699ef59857780a5530191031ee3f796
commit: d5eb31209699ef59857780a5530191031ee3f796
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-07-19T12:04:40+02:00
summary:

gh-153903: Fix ctypes wrap_dll_function() with string annotations (#154042)

Call get_annotations() with eval_str=True.

files:
A Lib/test/test_ctypes/wrap_str_ann.py
M Lib/ctypes/util.py
M Lib/test/test_ctypes/test_funcptr.py

diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index b035bfb99feee0..c65fc3032fdfad 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -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")
diff --git a/Lib/test/test_ctypes/test_funcptr.py b/Lib/test/test_ctypes/test_funcptr.py
index 94d03ad553d222..86699ad8109827 100644
--- a/Lib/test/test_ctypes/test_funcptr.py
+++ b/Lib/test/test_ctypes/test_funcptr.py
@@ -151,6 +151,11 @@ def noexist():
             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
index 00000000000000..aa114a640c3a99
--- /dev/null
+++ b/Lib/test/test_ctypes/wrap_str_ann.py
@@ -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")
+
[email protected]_dll_function(ctypes.pythonapi)
+def Py_GetVersion() -> ctypes.c_char_p:
+    ...

_______________________________________________
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]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.