Skip to content

bpo-33591: Fix CDLL to accept PathLike objects #7032

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 5, 2023
16 changes: 16 additions & 0 deletions Doc/library/ctypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,10 @@ way is to instantiate one of the following classes:
DLLs and determine which one is not found using Windows debugging and
tracing tools.

.. versionchanged:: 3.12

The *name* parameter can now be a :term:`path-like object`.

.. seealso::

`Microsoft DUMPBIN tool <https://docs.microsoft.com/cpp/build/reference/dependents>`_
Expand All @@ -1398,13 +1402,21 @@ way is to instantiate one of the following classes:
.. versionchanged:: 3.3
:exc:`WindowsError` used to be raised.

.. versionchanged:: 3.12

The *name* parameter can now be a :term:`path-like object`.


.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)

Windows only: Instances of this class represent loaded shared libraries,
functions in these libraries use the ``stdcall`` calling convention, and are
assumed to return :c:expr:`int` by default.

.. versionchanged:: 3.12

The *name* parameter can now be a :term:`path-like object`.

The Python :term:`global interpreter lock` is released before calling any
function exported by these libraries, and reacquired afterwards.

Expand All @@ -1418,6 +1430,10 @@ function exported by these libraries, and reacquired afterwards.

Thus, this is only useful to call Python C api functions directly.

.. versionchanged:: 3.12

The *name* parameter can now be a :term:`path-like object`.

All these classes can be instantiated by calling them with at least one
argument, the pathname of the shared library. If you have an existing handle to
an already loaded shared library, it can be passed as the ``handle`` named
Expand Down
2 changes: 2 additions & 0 deletions Lib/ctypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False,
use_last_error=False,
winmode=None):
if name:
name = _os.fspath(name)
self._name = name
flags = self._func_flags_
if use_errno:
Expand Down
18 changes: 14 additions & 4 deletions Lib/test/test_ctypes/test_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ class LoaderTest(unittest.TestCase):
unknowndll = "xxrandomnamexx"

def test_load(self):
if libc_name is None:
self.skipTest('could not find libc')
CDLL(libc_name)
CDLL(os.path.basename(libc_name))
if libc_name is not None:
test_lib = libc_name
else:
if os.name == "nt":
import _ctypes_test
test_lib = _ctypes_test.__file__
else:
self.skipTest('could not find library to load')
CDLL(test_lib)
CDLL(os.path.basename(test_lib))
class CTypesTestPathLikeCls:
def __fspath__(self):
return test_lib
CDLL(CTypesTestPathLikeCls())
self.assertRaises(OSError, CDLL, self.unknowndll)

def test_load_version(self):
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@ Tim Hochberg
Benjamin Hodgson
Joerg-Cyril Hoehle
Douwe Hoekstra
Robert Hoelzl
Gregor Hoffleit
Chris Hoffman
Tim Hoffmann
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:class:`ctypes.CDLL`, :class:`ctypes.OleDLL`, :class:`ctypes.WinDLL`,
and :class:`ctypes.PyDLL` now accept :term:`path-like objects
<path-like object>` as their ``name`` argument. Patch by Robert Hoelzl.