Skip to content

Commit

Permalink
Merge pull request #17530 from BvB93/fspath
Browse files Browse the repository at this point in the history
ENH: Allow `ctypeslib.load_library` to take any path-like object
  • Loading branch information
charris committed Oct 9, 2021
2 parents 6217121 + b3dbd78 commit 83d8df9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
5 changes: 5 additions & 0 deletions doc/release/upcoming_changes/17530.improvement.rst
@@ -0,0 +1,5 @@
`ctypeslib.load_library` can now take any path-like object
-----------------------------------------------------------------------
All parameters in the can now take any :term:`python:path-like object`.
This includes the likes of strings, bytes and objects implementing the
:meth:`__fspath__<os.PathLike.__fspath__>` protocol.
13 changes: 11 additions & 2 deletions numpy/ctypeslib.py
Expand Up @@ -90,18 +90,23 @@ def _dummy(*args, **kwds):
def load_library(libname, loader_path):
"""
It is possible to load a library using
>>> lib = ctypes.cdll[<full_path_name>] # doctest: +SKIP
But there are cross-platform considerations, such as library file extensions,
plus the fact Windows will just load the first library it finds with that name.
NumPy supplies the load_library function as a convenience.
.. versionchanged:: 1.20.0
Allow libname and loader_path to take any
:term:`python:path-like object`.
Parameters
----------
libname : str
libname : path-like
Name of the library, which can have 'lib' as a prefix,
but without an extension.
loader_path : str
loader_path : path-like
Where the library can be found.
Returns
Expand All @@ -120,6 +125,10 @@ def load_library(libname, loader_path):
warnings.warn("All features of ctypes interface may not work "
"with ctypes < 1.0.1", stacklevel=2)

# Convert path-like objects into strings
libname = os.fsdecode(libname)
loader_path = os.fsdecode(loader_path)

ext = os.path.splitext(libname)[1]
if not ext:
# Try to load library with platform-specific name, otherwise
Expand Down
17 changes: 10 additions & 7 deletions numpy/tests/test_ctypeslib.py
@@ -1,6 +1,7 @@
import sys
import pytest
import weakref
from pathlib import Path

import numpy as np
from numpy.ctypeslib import ndpointer, load_library, as_array
Expand Down Expand Up @@ -37,13 +38,15 @@
reason="Known to fail on cygwin")
class TestLoadLibrary:
def test_basic(self):
try:
# Should succeed
load_library('_multiarray_umath', np.core._multiarray_umath.__file__)
except ImportError as e:
msg = ("ctypes is not available on this python: skipping the test"
" (import error was: %s)" % str(e))
print(msg)
loader_path = np.core._multiarray_umath.__file__

out1 = load_library('_multiarray_umath', loader_path)
out2 = load_library(Path('_multiarray_umath'), loader_path)
out3 = load_library('_multiarray_umath', Path(loader_path))
out4 = load_library(b'_multiarray_umath', loader_path)

assert isinstance(out1, ctypes.CDLL)
assert out1 is out2 is out3 is out4

def test_basic2(self):
# Regression for #801: load_library with a full library name
Expand Down

0 comments on commit 83d8df9

Please sign in to comment.