From a303722b08bc6226f4ac5c31f9237b5aa5b18e62 Mon Sep 17 00:00:00 2001 From: CHINMAY <89741289+Das-Chinmay@users.noreply.github.com> Date: Thu, 26 Mar 2026 21:27:44 -0700 Subject: [PATCH 1/3] gh-52008: document that absolute paths can break use_errno=True in ctypes Loading a shared library via an absolute path (e.g. CDLL('/lib/libc.so.6')) can cause use_errno=True to silently malfunction on Linux because dlopen may return a separate library instance with its own errno variable. Add a note to the CDLL.use_errno parameter docs warning about this and recommending the use of an unqualified name or ctypes.util.find_library instead. --- Doc/library/ctypes.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 0b3ad4573f5fcf..cdb8ddae28c53c 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1524,6 +1524,17 @@ way is to instantiate :py:class:`CDLL` or one of its subclasses: copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy to a new value and returns the former value. + .. note:: + + On some platforms (notably Linux), loading a library by absolute path (e.g. + ``CDLL('/lib/libc.so.6')``) may cause ``use_errno=True`` to malfunction. + If the absolute path resolves to a different :manpage:`dlopen(3)` instance + of the library than the one already linked into the process, the two + instances have *separate* :data:`errno` variables and ctypes will swap the + wrong one. To avoid this, load the library by its unqualified name (e.g. + ``CDLL('libc.so.6')`` or use :func:`ctypes.util.find_library` to obtain + a name that the linker can resolve to the already-loaded instance. + The *use_last_error* parameter, when set to true, enables the same mechanism for the Windows error code which is managed by the :func:`GetLastError` and :func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and From 65fc6a2cbb7ae7c359eacebc55dc746d8901d207 Mon Sep 17 00:00:00 2001 From: CHINMAY <89741289+Das-Chinmay@users.noreply.github.com> Date: Thu, 26 Mar 2026 22:46:14 -0700 Subject: [PATCH 2/3] gh-52008: add news entry --- .../2026-03-26-00-00-00.gh-issue-52008.y2n4w9.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2026-03-26-00-00-00.gh-issue-52008.y2n4w9.rst diff --git a/Misc/NEWS.d/next/Documentation/2026-03-26-00-00-00.gh-issue-52008.y2n4w9.rst b/Misc/NEWS.d/next/Documentation/2026-03-26-00-00-00.gh-issue-52008.y2n4w9.rst new file mode 100644 index 00000000000000..f055f23981e0aa --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2026-03-26-00-00-00.gh-issue-52008.y2n4w9.rst @@ -0,0 +1,4 @@ +Add a note to :class:`ctypes.CDLL` documenting that loading a shared library +via an absolute path can silently break ``use_errno=True`` on Linux, because +:manpage:`dlopen(3)` may return a separate library instance with its own +:data:`errno` variable. From e45327b475afacd89caf6a9de061f723c44bfb73 Mon Sep 17 00:00:00 2001 From: CHINMAY <89741289+Das-Chinmay@users.noreply.github.com> Date: Thu, 26 Mar 2026 23:14:45 -0700 Subject: [PATCH 3/3] gh-52008: fix RST cross-reference and unclosed parenthesis in note --- Doc/library/ctypes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index cdb8ddae28c53c..98200093e15e19 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1532,8 +1532,8 @@ way is to instantiate :py:class:`CDLL` or one of its subclasses: of the library than the one already linked into the process, the two instances have *separate* :data:`errno` variables and ctypes will swap the wrong one. To avoid this, load the library by its unqualified name (e.g. - ``CDLL('libc.so.6')`` or use :func:`ctypes.util.find_library` to obtain - a name that the linker can resolve to the already-loaded instance. + ``CDLL('libc.so.6')``) or use :func:`!find_library` to obtain a name that + the linker can resolve to the already-loaded instance. The *use_last_error* parameter, when set to true, enables the same mechanism for the Windows error code which is managed by the :func:`GetLastError` and