Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r3114:99940f1f5402
Date: 2018-02-27 21:18 +0100
http://bitbucket.org/cffi/cffi/changeset/99940f1f5402/

Log:    Ignore multiple dlclose(), like file.close() does in Python

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4099,10 +4099,11 @@
 
 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
--- a/c/cdlopen.c
+++ b/c/cdlopen.c
@@ -62,22 +62,17 @@
         return NULL;
 
     libhandle = lib->l_libhandle;
-    lib->l_libhandle = NULL;
+    if (libhandle != NULL)
+    {
+        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 (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
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -409,6 +409,7 @@
     #
     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
--- a/testing/cffi0/test_function.py
+++ b/testing/cffi0/test_function.py
@@ -507,9 +507,6 @@
         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 @@
         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
--- a/testing/cffi1/test_re_python.py
+++ b/testing/cffi1/test_re_python.py
@@ -119,12 +119,10 @@
         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
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to