robot-piglet 7 месяцев назад
Родитель
Сommit
a1a81f282c

+ 2 - 1
contrib/python/cffi/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: cffi
-Version: 1.16.0
+Version: 1.17.0
 Summary: Foreign Function Interface for Python calling C code.
 Home-page: http://cffi.readthedocs.org
 Author: Armin Rigo, Maciej Fijalkowski
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: MIT License

+ 11 - 3
contrib/python/cffi/py3/README.md

@@ -1,9 +1,14 @@
+[![GitHub Actions Status](https://github.com/python-cffi/cffi/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/python-cffi/cffi/actions/workflows/ci.yaml?query=branch%3Amain++)
+[![PyPI version](https://img.shields.io/pypi/v/cffi.svg)](https://pypi.org/project/cffi)
+[![Read the Docs](https://img.shields.io/badge/docs-latest-blue.svg)][Documentation]
+
+
 CFFI
 ====
 
 Foreign Function Interface for Python calling C code.
-Please see the [Documentation](http://cffi.readthedocs.org/) or uncompiled
-in the doc/ subdirectory.
+
+Please see the [Documentation] or uncompiled in the `doc/` subdirectory.
 
 Download
 --------
@@ -24,8 +29,11 @@ Contact
 Testing/development tips
 ------------------------
 
-To run tests under CPython, run the following in the source root directory::
+To run tests under CPython, run the following in the source root directory:
 
     pip install pytest
     pip install -e .  # editable install of CFFI for local development
     pytest c/ testing/
+
+
+[Documentation]: http://cffi.readthedocs.org/

+ 57 - 6
contrib/python/cffi/py3/c/_cffi_backend.c

@@ -2,7 +2,7 @@
 #include <Python.h>
 #include "structmember.h"
 
-#define CFFI_VERSION  "1.16.0"
+#define CFFI_VERSION  "1.17.0"
 
 #ifdef MS_WIN32
 #include <windows.h>
@@ -53,11 +53,15 @@
 # if _MSC_VER < 1800   /* MSVC < 2013 */
    typedef unsigned char _Bool;
 # endif
+# define _cffi_float_complex_t   _Fcomplex    /* include <complex.h> for it */
+# define _cffi_double_complex_t  _Dcomplex    /* include <complex.h> for it */
 #else
 # include <stdint.h>
 # if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux)
 #  include <alloca.h>
 # endif
+# define _cffi_float_complex_t   float _Complex
+# define _cffi_double_complex_t  double _Complex
 #endif
 
 /* Convert from closure pointer to function pointer. */
@@ -112,6 +116,15 @@
 # define CFFI_CHECK_FFI_PREP_CIF_VAR __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)
 # define CFFI_CHECK_FFI_PREP_CIF_VAR_MAYBE 1
 
+#elif defined(__EMSCRIPTEN__)
+
+# define CFFI_CHECK_FFI_CLOSURE_ALLOC 1
+# define CFFI_CHECK_FFI_CLOSURE_ALLOC_MAYBE 1
+# define CFFI_CHECK_FFI_PREP_CLOSURE_LOC 1
+# define CFFI_CHECK_FFI_PREP_CLOSURE_LOC_MAYBE 1
+# define CFFI_CHECK_FFI_PREP_CIF_VAR 1
+# define CFFI_CHECK_FFI_PREP_CIF_VAR_MAYBE 1
+
 #else
 
 # define CFFI_CHECK_FFI_CLOSURE_ALLOC 0
@@ -134,8 +147,8 @@
 # define PyText_Check PyUnicode_Check
 # define PyTextAny_Check PyUnicode_Check
 # define PyText_FromFormat PyUnicode_FromFormat
-# define PyText_AsUTF8 _PyUnicode_AsString   /* PyUnicode_AsUTF8 in Py3.3 */
-# define PyText_AS_UTF8 _PyUnicode_AsString
+# define PyText_AsUTF8 PyUnicode_AsUTF8
+# define PyText_AS_UTF8 PyUnicode_AsUTF8
 # if PY_VERSION_HEX >= 0x03030000
 #  define PyText_GetSize PyUnicode_GetLength
 # else
@@ -1612,6 +1625,8 @@ convert_struct_from_object(char *data, CTypeDescrObject *ct, PyObject *init,
     return _convert_error(init, ct, expected);
 }
 
+static PyObject* try_extract_directfnptr(PyObject *x);   /* forward */
+
 #ifdef __GNUC__
 # if __GNUC__ >= 4
 /* Don't go inlining this huge function.  Needed because occasionally
@@ -1639,9 +1654,18 @@ convert_from_object(char *data, CTypeDescrObject *ct, PyObject *init)
         CTypeDescrObject *ctinit;
 
         if (!CData_Check(init)) {
-            expected = "cdata pointer";
-            goto cannot_convert;
+            PyObject *func_cdata = try_extract_directfnptr(init);
+            if (func_cdata != NULL && CData_Check(func_cdata)) {
+                init = func_cdata;
+            }
+            else {
+                if (PyErr_Occurred())
+                    return -1;
+                expected = "cdata pointer";
+                goto cannot_convert;
+            }
         }
+
         ctinit = ((CDataObject *)init)->c_type;
         if (!(ctinit->ct_flags & (CT_POINTER|CT_FUNCTIONPTR))) {
             if (ctinit->ct_flags & CT_ARRAY)
@@ -2445,7 +2469,11 @@ static Py_hash_t cdata_hash(PyObject *v)
         }
         Py_DECREF(vv);
     }
+#if PY_VERSION_HEX < 0x030D0000
     return _Py_HashPointer(((CDataObject *)v)->c_data);
+#else
+    return Py_HashPointer(((CDataObject *)v)->c_data);
+#endif
 }
 
 static Py_ssize_t
@@ -4080,10 +4108,20 @@ static CDataObject *cast_to_integer_or_char(CTypeDescrObject *ct, PyObject *ob)
         value = res;
     }
     else {
+        if (PyCFunction_Check(ob)) {
+            PyObject *func_cdata = try_extract_directfnptr(ob);
+            if (func_cdata != NULL && CData_Check(func_cdata)) {
+                value = (Py_intptr_t)((CDataObject *)func_cdata)->c_data;
+                goto got_value;
+            }
+            if (PyErr_Occurred())
+                return NULL;
+        }
         value = _my_PyLong_AsUnsignedLongLong(ob, 0);
         if (value == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
             return NULL;
     }
+  got_value:
     if (ct->ct_flags & CT_IS_BOOL)
         value = !!value;
     cd = _new_casted_primitive(ct);
@@ -4140,6 +4178,15 @@ static PyObject *do_cast(CTypeDescrObject *ct, PyObject *ob)
                 return new_simple_cdata(cdsrc->c_data, ct);
             }
         }
+        if (PyCFunction_Check(ob)) {
+            PyObject *func_cdata = try_extract_directfnptr(ob);
+            if (func_cdata != NULL && CData_Check(func_cdata)) {
+                char *ptr = ((CDataObject *)func_cdata)->c_data;
+                return new_simple_cdata(ptr, ct);
+            }
+            if (PyErr_Occurred())
+                return NULL;
+        }
         if ((ct->ct_flags & CT_POINTER) &&
                 (ct->ct_itemdescr->ct_flags & CT_IS_FILE) &&
                 PyFile_Check(ob)) {
@@ -4522,7 +4569,7 @@ static void *b_do_dlopen(PyObject *args, const char **p_printable_filename,
             if (sz1 < 0)
                 return NULL;
             w1[sz1] = 0;
-            handle = dlopenW(w1);
+            handle = dlopenWinW(w1, flags);
             goto got_handle;
         }
         PyErr_Clear();
@@ -6117,7 +6164,11 @@ static void _my_PyErr_WriteUnraisable(PyObject *t, PyObject *v, PyObject *tb,
 
     PyErr_Restore(t, v, tb);
     if (s != NULL) {
+#if PY_VERSION_HEX >= 0x030D0000
+        PyErr_FormatUnraisable("Exception ignored %S", s);
+#else
         _PyErr_WriteUnraisableMsg(PyText_AS_UTF8(s), NULL);
+#endif
         Py_DECREF(s);
     }
     else

+ 2 - 0
contrib/python/cffi/py3/c/commontypes.c

@@ -172,6 +172,8 @@ static const char *common_simple_types[] = {
     EQ("WINSTA", "HANDLE"),
     EQ("WORD", "unsigned short"),
     EQ("WPARAM", "UINT_PTR"),
+    EQ("_Dcomplex", "_cffi_double_complex_t"),
+    EQ("_Fcomplex", "_cffi_float_complex_t"),
 #endif
 
     EQ("bool", "_Bool"),

+ 34 - 13
contrib/python/cffi/py3/c/lib_obj.c

@@ -30,6 +30,7 @@ inline static void MarkAsIntentionallyLeaked(const void* ptr) {
 struct CPyExtFunc_s {
     PyMethodDef md;
     void *direct_fn;
+    PyObject *direct_fn_cdata;
     int type_index;
     char doc[1];
 };
@@ -675,6 +676,31 @@ static LibObject *lib_internal_new(FFIObject *ffi, const char *module_name,
     return NULL;
 }
 
+static PyObject* try_extract_directfnptr(PyObject *x)
+{
+    /* returns: borrowed ref or NULL */
+    LibObject *lib;
+    PyObject *ct;
+    struct CPyExtFunc_s *exf = _cpyextfunc_get(x);
+    if (exf == NULL)
+        return NULL;       /* wrong type */
+    if (exf->direct_fn_cdata != NULL)
+        return exf->direct_fn_cdata;    /* common case: cached */
+
+    if (exf->direct_fn == NULL)
+        return x;          /* backward compatibility: no direct_fn */
+
+    lib = (LibObject *)PyCFunction_GET_SELF(x);
+    ct = _cpyextfunc_type(lib, exf);
+    if (ct == NULL)
+        return NULL;       /* error */
+
+    x = new_simple_cdata(exf->direct_fn, (CTypeDescrObject *)ct);
+    Py_DECREF(ct);
+    exf->direct_fn_cdata = x;  /* caches x, which becomes immortal like exf */
+    return x;
+}
+
 static PyObject *address_of_global_var(PyObject *args)
 {
     LibObject *lib;
@@ -696,20 +722,15 @@ static PyObject *address_of_global_var(PyObject *args)
         return cg_addressof_global_var((GlobSupportObject *)x);
     }
     else {
-        struct CPyExtFunc_s *exf = _cpyextfunc_get(x);
-        if (exf != NULL) {  /* an OP_CPYTHON_BLTN: '&func' returns a cdata */
-            PyObject *ct;
-            if (exf->direct_fn == NULL) {
-                Py_INCREF(x);    /* backward compatibility */
-                return x;
-            }
-            ct = _cpyextfunc_type(lib, exf);
-            if (ct == NULL)
-                return NULL;
-            x = new_simple_cdata(exf->direct_fn, (CTypeDescrObject *)ct);
-            Py_DECREF(ct);
-            return x;
+        PyObject *func_cdata = try_extract_directfnptr(x);
+        if (func_cdata != NULL) {
+            /* an OP_CPYTHON_BLTN: '&func' returns a cdata */
+            Py_INCREF(func_cdata);
+            return func_cdata;
         }
+        if (PyErr_Occurred())
+            return NULL;
+
         if (CData_Check(x) &&  /* a constant functionptr cdata: 'f == &f' */
                 (((CDataObject *)x)->c_type->ct_flags & CT_FUNCTIONPTR) != 0) {
             Py_INCREF(x);

+ 3 - 1
contrib/python/cffi/py3/c/misc_thread_common.h

@@ -331,7 +331,9 @@ PyAPI_DATA(void *volatile) _PyThreadState_Current;
 
 static PyThreadState *get_current_ts(void)
 {
-#if PY_VERSION_HEX >= 0x03060000
+#if PY_VERSION_HEX >= 0x030D0000
+    return PyThreadState_GetUnchecked();
+#elif PY_VERSION_HEX >= 0x03060000
     return _PyThreadState_UncheckedGet();
 #elif defined(_Py_atomic_load_relaxed)
     return (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);

+ 20 - 4
contrib/python/cffi/py3/c/misc_win32.h

@@ -167,14 +167,30 @@ static PyObject *b_getwinerror(PyObject *self, PyObject *args, PyObject *kwds)
 #define RTLD_GLOBAL 0
 #define RTLD_LOCAL  0
 
-static void *dlopen(const char *filename, int flag)
+static void *dlopen(const char *filename, int flags)
 {
-    return (void *)LoadLibraryA(filename);
+    if (flags == 0) {
+        for (const char *p = filename; *p != 0; p++)
+            if (*p == '\\' || *p == '/') {
+                flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
+                        LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
+                break;
+            }
+    }
+    return (void *)LoadLibraryExA(filename, NULL, flags);
 }
 
-static void *dlopenW(const wchar_t *filename)
+static void *dlopenWinW(const wchar_t *filename, int flags)
 {
-    return (void *)LoadLibraryW(filename);
+    if (flags == 0) {
+        for (const wchar_t *p = filename; *p != 0; p++)
+            if (*p == '\\' || *p == '/') {
+                flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
+                        LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
+                break;
+            }
+    }
+    return (void *)LoadLibraryExW(filename, NULL, flags);
 }
 
 static void *dlsym(void *handle, const char *symbol)

+ 2 - 0
contrib/python/cffi/py3/c/parse_c_type.c

@@ -535,6 +535,8 @@ int search_standard_typename(const char *p, size_t size)
 
     case 'i':
         if (size == 9 && !memcmp(p, "ptrdiff", 7)) return _CFFI_PRIM_PTRDIFF;
+        if (size == 21 && !memcmp(p, "_cffi_float_complex", 19)) return _CFFI_PRIM_FLOATCOMPLEX;
+        if (size == 22 && !memcmp(p, "_cffi_double_complex", 20)) return _CFFI_PRIM_DOUBLECOMPLEX;
         break;
 
     case 'l':

+ 2 - 2
contrib/python/cffi/py3/cffi/__init__.py

@@ -5,8 +5,8 @@ from .api import FFI
 from .error import CDefError, FFIError, VerificationError, VerificationMissing
 from .error import PkgConfigError
 
-__version__ = "1.16.0"
-__version_info__ = (1, 16, 0)
+__version__ = "1.17.0"
+__version_info__ = (1, 17, 0)
 
 # The verifier module file names are based on the CRC32 of a string that
 # contains the following version number.  It may be older than __version__

+ 4 - 0
contrib/python/cffi/py3/cffi/_cffi_include.h

@@ -101,11 +101,15 @@ extern "C" {
     typedef unsigned char _Bool;
 #  endif
 # endif
+# define _cffi_float_complex_t   _Fcomplex    /* include <complex.h> for it */
+# define _cffi_double_complex_t  _Dcomplex    /* include <complex.h> for it */
 #else
 # include <stdint.h>
 # if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux)
 #  include <alloca.h>
 # endif
+# define _cffi_float_complex_t   float _Complex
+# define _cffi_double_complex_t  double _Complex
 #endif
 
 #ifdef __GNUC__

Некоторые файлы не были показаны из-за большого количества измененных файлов