summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2018-02-27 21:18:33 +0100
committerArmin Rigo <arigo@tunes.org>2018-02-27 21:18:33 +0100
commita4c04234554d1791ff904539078d6f7826434970 (patch)
treeccf06aeba430b30581e7fa4a90fbe273aeec37e2
parentdf3534a0953119d149d7b8cd3665d2e9859d7c2a (diff)
downloadcffi-a4c04234554d1791ff904539078d6f7826434970.tar.gz
Ignore multiple dlclose(), like file.close() does in Python
-rw-r--r--c/_cffi_backend.c9
-rw-r--r--c/cdlopen.c23
-rw-r--r--c/test_c.py1
-rw-r--r--testing/cffi0/test_function.py4
-rw-r--r--testing/cffi1/test_re_python.py4
5 files changed, 17 insertions, 24 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
index 7106c65..7f44d12 100644
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4099,10 +4099,11 @@ static PyObject *dl_write_variable(DynLibObject *dlobj, PyObject *args)
static PyObject *dl_close_lib(DynLibObject *dlobj, PyObject *no_args)
{
- if (dl_check_closed(dlobj) < 0)
- return NULL;
- dlclose(dlobj->dl_handle);
- dlobj->dl_handle = NULL;
+ if (dlobj->dl_handle != NULL)
+ {
+ dlclose(dlobj->dl_handle);
+ dlobj->dl_handle = NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
diff --git a/c/cdlopen.c b/c/cdlopen.c
index 361b0d1..46ce153 100644
--- a/c/cdlopen.c
+++ b/c/cdlopen.c
@@ -62,22 +62,17 @@ static PyObject *ffi_dlclose(PyObject *self, PyObject *args)
return NULL;
libhandle = lib->l_libhandle;
- lib->l_libhandle = NULL;
-
- if (libhandle == NULL) {
- PyErr_Format(FFIError, "library '%s' is already closed "
- "or was not created with ffi.dlopen()",
- PyText_AS_UTF8(lib->l_libname));
- return NULL;
- }
-
- /* Clear the dict to force further accesses to do cdlopen_fetch()
- again, and fail because the library was closed. */
- PyDict_Clear(lib->l_dict);
+ if (libhandle != NULL)
+ {
+ lib->l_libhandle = NULL;
- if (cdlopen_close(lib->l_libname, libhandle) < 0)
- return NULL;
+ /* Clear the dict to force further accesses to do cdlopen_fetch()
+ again, and fail because the library was closed. */
+ PyDict_Clear(lib->l_dict);
+ if (cdlopen_close(lib->l_libname, libhandle) < 0)
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
diff --git a/c/test_c.py b/c/test_c.py
index 4ff1549..caecbec 100644
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -409,6 +409,7 @@ def test_load_standard_library():
#
x.close_lib()
py.test.raises(ValueError, x.load_function, BVoidP, 'sqrt')
+ x.close_lib()
def test_no_len_on_nonarray():
p = new_primitive_type("int")
diff --git a/testing/cffi0/test_function.py b/testing/cffi0/test_function.py
index 077f806..6af8aa6 100644
--- a/testing/cffi0/test_function.py
+++ b/testing/cffi0/test_function.py
@@ -507,9 +507,6 @@ class TestFunction(object):
ffi.cdef("int foobar(void); int foobaz;")
lib = ffi.dlopen(lib_m)
ffi.dlclose(lib)
- e = py.test.raises(ValueError, ffi.dlclose, lib)
- assert str(e.value).startswith("library '")
- assert str(e.value).endswith("' has already been closed")
e = py.test.raises(ValueError, getattr, lib, 'foobar')
assert str(e.value).startswith("library '")
assert str(e.value).endswith("' has already been closed")
@@ -519,3 +516,4 @@ class TestFunction(object):
e = py.test.raises(ValueError, setattr, lib, 'foobaz', 42)
assert str(e.value).startswith("library '")
assert str(e.value).endswith("' has already been closed")
+ ffi.dlclose(lib) # does not raise
diff --git a/testing/cffi1/test_re_python.py b/testing/cffi1/test_re_python.py
index 815c435..65c2882 100644
--- a/testing/cffi1/test_re_python.py
+++ b/testing/cffi1/test_re_python.py
@@ -119,12 +119,10 @@ def test_dlclose():
str_extmod = extmod.encode('utf-8')
else:
str_extmod = extmod
- e = py.test.raises(ffi.error, ffi.dlclose, lib)
- assert str(e.value).startswith(
- "library '%s' is already closed" % (str_extmod,))
e = py.test.raises(ffi.error, getattr, lib, 'add42')
assert str(e.value) == (
"library '%s' has been closed" % (str_extmod,))
+ ffi.dlclose(lib) # does not raise
def test_constant_via_lib():
from re_python_pysrc import ffi