GeezerVison is showing github.com — gh-125206: Bug in ctypes with old libffi is fixed (#125322) · python/cpython@aac89b5
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: Lib/test/test_ctypes/test_libc.py +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -23,7 +23,7 @@ def test_sqrt(self): | 23 | 23 | self.assertEqual(lib.my_sqrt(2.0), math.sqrt(2.0)) | 24 | 24 |
| 25 | 25 | @unittest.skipUnless(hasattr(ctypes, "c_double_complex"), | 26 | | - "requires C11 complex type") | | 26 | + "requires C11 complex type and libffi >= 3.3.0") | 27 | 27 | def test_csqrt(self): | 28 | 28 | lib.my_csqrt.argtypes = ctypes.c_double_complex, | 29 | 29 | lib.my_csqrt.restype = ctypes.c_double_complex | |
Collapse file Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +Workaround for old libffi versions is added. Module ctypes supports | | 2 | +:c:expr:`double complex` only with libffi >= 3.3.0. Patch by Mikhail Efimov. |
Collapse file Copy file name to clipboardExpand all lines: Modules/_ctypes/_ctypes.c +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -1747,7 +1747,7 @@ class _ctypes.c_void_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type" | 1747 | 1747 | [clinic start generated code]*/ | 1748 | 1748 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd4d9646c56f43a9]*/ | 1749 | 1749 |
| 1750 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 1750 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 1751 | 1751 | static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdCEFfuzZqQPXOv?g"; | 1752 | 1752 | #else | 1753 | 1753 | static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; | |
Collapse file Copy file name to clipboardExpand all lines: Modules/_ctypes/_ctypes_test.c +2-4Lines changed: 2 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 13 | 13 |
| 14 | 14 | #include <Python.h> | 15 | 15 |
| 16 | | -#include <ffi.h> // FFI_TARGET_HAS_COMPLEX_TYPE | 17 | | - | 18 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 16 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 19 | 17 | # include "../_complex.h" // csqrt() | 20 | 18 | # undef I // for _ctypes_test_generated.c.h | 21 | 19 | #endif | @@ -449,7 +447,7 @@ EXPORT(double) my_sqrt(double a) | 449 | 447 | return sqrt(a); | 450 | 448 | } | 451 | 449 |
| 452 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 450 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 453 | 451 | EXPORT(double complex) my_csqrt(double complex a) | 454 | 452 | { | 455 | 453 | return csqrt(a); | |
Collapse file Copy file name to clipboardExpand all lines: Modules/_ctypes/callproc.c +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -105,7 +105,7 @@ module _ctypes | 105 | 105 | #include "pycore_global_objects.h"// _Py_ID() | 106 | 106 | #include "pycore_traceback.h" // _PyTraceback_Add() | 107 | 107 |
| 108 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 108 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 109 | 109 | #include "../_complex.h" // complex | 110 | 110 | #endif | 111 | 111 |
| @@ -655,7 +655,7 @@ union result { | 655 | 655 | double d; | 656 | 656 | float f; | 657 | 657 | void *p; | 658 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 658 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 659 | 659 | double complex C; | 660 | 660 | float complex E; | 661 | 661 | long double complex F; | |
Collapse file Copy file name to clipboardExpand all lines: Modules/_ctypes/cfield.c +4-4Lines changed: 4 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 14 | 14 | #include <ffi.h> | 15 | 15 | #include "ctypes.h" | 16 | 16 |
| 17 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 17 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 18 | 18 | # include "../_complex.h" // complex | 19 | 19 | #endif | 20 | 20 |
| @@ -972,7 +972,7 @@ d_get(void *ptr, Py_ssize_t size) | 972 | 972 | return PyFloat_FromDouble(val); | 973 | 973 | } | 974 | 974 |
| 975 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 975 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 976 | 976 | static PyObject * | 977 | 977 | C_set(void *ptr, PyObject *value, Py_ssize_t size) | 978 | 978 | { | @@ -1545,7 +1545,7 @@ static struct fielddesc formattable[] = { | 1545 | 1545 | { 'B', B_set, B_get, NULL}, | 1546 | 1546 | { 'c', c_set, c_get, NULL}, | 1547 | 1547 | { 'd', d_set, d_get, NULL, d_set_sw, d_get_sw}, | 1548 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 1548 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 1549 | 1549 | { 'C', C_set, C_get, NULL}, | 1550 | 1550 | { 'E', E_set, E_get, NULL}, | 1551 | 1551 | { 'F', F_set, F_get, NULL}, | @@ -1600,7 +1600,7 @@ _ctypes_init_fielddesc(void) | 1600 | 1600 | case 'B': fd->pffi_type = &ffi_type_uchar; break; | 1601 | 1601 | case 'c': fd->pffi_type = &ffi_type_schar; break; | 1602 | 1602 | case 'd': fd->pffi_type = &ffi_type_double; break; | 1603 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 1603 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 1604 | 1604 | case 'C': fd->pffi_type = &ffi_type_complex_double; break; | 1605 | 1605 | case 'E': fd->pffi_type = &ffi_type_complex_float; break; | 1606 | 1606 | case 'F': fd->pffi_type = &ffi_type_complex_longdouble; break; | |
Collapse file Copy file name to clipboardExpand all lines: Modules/_ctypes/ctypes.h +2-4Lines changed: 2 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 2 | 2 | # include <alloca.h> | 3 | 3 | #endif | 4 | 4 |
| 5 | | -#include <ffi.h> // FFI_TARGET_HAS_COMPLEX_TYPE | 6 | | - | 7 | 5 | #include "pycore_moduleobject.h" // _PyModule_GetState() | 8 | 6 | #include "pycore_typeobject.h" // _PyType_GetModuleState() | 9 | 7 |
| 10 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 8 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 11 | 9 | # include "../_complex.h" // complex | 12 | 10 | #endif | 13 | 11 |
| @@ -388,7 +386,7 @@ struct tagPyCArgObject { | 388 | 386 | double d; | 389 | 387 | float f; | 390 | 388 | void *p; | 391 | | -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) | | 389 | +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) | 392 | 390 | double complex C; | 393 | 391 | float complex E; | 394 | 392 | long double complex F; | |
Collapse file Copy file name to clipboardExpand all lines: configure +64Lines changed: 64 additions & 0 deletions Collapse file Copy file name to clipboardExpand all lines: configure.ac +40Lines changed: 40 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -4089,6 +4089,46 @@ AS_VAR_IF([have_libffi], [yes], [ | 4089 | 4089 | ]) | 4090 | 4090 | ]) | 4091 | 4091 |
| | 4092 | +# Check for libffi with real complex double support. | | 4093 | +# This is a workaround, since FFI_TARGET_HAS_COMPLEX_TYPE was defined in libffi v3.2.1, | | 4094 | +# but real support was provided only in libffi v3.3.0. | | 4095 | +# See https://github.com/python/cpython/issues/125206 for more details. | | 4096 | +# | | 4097 | +AC_CACHE_CHECK([libffi has complex type support], [ac_cv_ffi_complex_double_supported], | | 4098 | +[ac_save_cc="$CC" | | 4099 | +CC="$CC -lffi" | | 4100 | +AC_RUN_IFELSE([AC_LANG_SOURCE([[ | | 4101 | +#include <complex.h> | | 4102 | +#include <ffi.h> | | 4103 | +int z_is_expected(double complex z) | | 4104 | +{ | | 4105 | + const double complex expected = CMPLX(1.25, -0.5); | | 4106 | + return z == expected; | | 4107 | +} | | 4108 | +int main(void) | | 4109 | +{ | | 4110 | + double complex z = 1.25 - 0.5 * I; | | 4111 | + ffi_type *args[1] = {&ffi_type_complex_double}; | | 4112 | + void *values[1] = {&z}; | | 4113 | + ffi_cif cif; | | 4114 | + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, | | 4115 | + &ffi_type_sint, args) != FFI_OK) | | 4116 | + { | | 4117 | + return 2; | | 4118 | + } | | 4119 | + ffi_arg rc; | | 4120 | + ffi_call(&cif, FFI_FN(z_is_expected), &rc, values); | | 4121 | + return !rc; | | 4122 | +} | | 4123 | +]])], [ac_cv_ffi_complex_double_supported=yes], | | 4124 | +[ac_cv_ffi_complex_double_supported=no], | | 4125 | +[ac_cv_ffi_complex_double_supported=no]) | | 4126 | +CC="$ac_save_cc"]) | | 4127 | +if test "$ac_cv_ffi_complex_double_supported" = "yes"; then | | 4128 | + AC_DEFINE([Py_FFI_SUPPORT_C_COMPLEX], [1], | | 4129 | + [Defined if _Complex C type can be used with libffi.]) | | 4130 | +fi | | 4131 | + | 4092 | 4132 | # Check for use of the system libmpdec library | 4093 | 4133 | AC_MSG_CHECKING([for --with-system-libmpdec]) | 4094 | 4134 | AC_ARG_WITH( | |
Collapse file Copy file name to clipboardExpand all lines: pyconfig.h.in +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1685 | 1685 | /* Defined if Python is built as a shared library. */ | 1686 | 1686 | #undef Py_ENABLE_SHARED | 1687 | 1687 |
| | 1688 | +/* Defined if _Complex C type can be used with libffi. */ | | 1689 | +#undef Py_FFI_SUPPORT_C_COMPLEX | | 1690 | + | 1688 | 1691 | /* Define if you want to disable the GIL */ | 1689 | 1692 | #undef Py_GIL_DISABLED | 1690 | 1693 |
| |
|