From 20355d647e8625dcb0a18c717d41b6a863d78ba5 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 05:55:46 +0300 Subject: [PATCH 1/7] gh-61103: Support float and long double complex types in ctypes module This amends 6988ff02a5: memory allocation for stginfo->ffi_type_pointer.elements in PyCSimpleType_init() should be more generic (perhaps someday fmt->pffi_type->elements will be not a two-elements array). It should finally resolve #61103. --- Doc/library/ctypes.rst | 20 ++++++++ Lib/ctypes/__init__.py | 4 ++ Lib/test/test_ctypes/test_libc.py | 12 +++++ Lib/test/test_ctypes/test_numbers.py | 10 ++-- ...4-07-02-05-08-16.gh-issue-61103.TMxkuM.rst | 4 ++ Modules/_complex.h | 18 +++++++ Modules/_ctypes/_ctypes.c | 7 +-- Modules/_ctypes/_ctypes_test.c | 8 ++++ Modules/_ctypes/callproc.c | 2 + Modules/_ctypes/cfield.c | 48 +++++++++++++++++++ Modules/_ctypes/ctypes.h | 2 + 11 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index a56e0eef5d11b1..fa2518973805f1 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -274,6 +274,10 @@ complex types are available: +==================================+=================================+=================+ | :class:`c_double_complex` | :c:expr:`double complex` | complex | +----------------------------------+---------------------------------+-----------------+ +| :class:`c_float_complex` | :c:expr:`float complex` | complex | ++----------------------------------+---------------------------------+-----------------+ +| :class:`c_longdouble_complex` | :c:expr:`long double complex` | complex | ++----------------------------------+---------------------------------+-----------------+ All these types can be created by calling them with an optional initializer of @@ -2302,6 +2306,22 @@ These are the fundamental ctypes data types: .. versionadded:: 3.14 + .. class:: c_float_complex + + Represents the C :c:expr:`float complex` datatype, if available. The + constructor accepts an optional :class:`complex` initializer. + + .. versionadded:: 3.14 + + +.. class:: c_longdouble_complex + + Represents the C :c:expr:`long double complex` datatype, if available. The + constructor accepts an optional :class:`complex` initializer. + + .. versionadded:: 3.14 + + .. class:: c_int Represents the C :c:expr:`signed int` datatype. The constructor accepts an diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index d2e6a8bfc8c9d4..721522caeeac92 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -208,6 +208,10 @@ class c_longdouble(_SimpleCData): try: class c_double_complex(_SimpleCData): _type_ = "C" + class c_float_complex(_SimpleCData): + _type_ = "E" + class c_longdouble_complex(_SimpleCData): + _type_ = "F" except AttributeError: pass diff --git a/Lib/test/test_ctypes/test_libc.py b/Lib/test/test_ctypes/test_libc.py index dec0afff4b38fd..d65ac6d38e8b4b 100644 --- a/Lib/test/test_ctypes/test_libc.py +++ b/Lib/test/test_ctypes/test_libc.py @@ -32,6 +32,18 @@ def test_csqrt(self): 0.004999937502734214+1.0000124996093955j) self.assertAlmostEqual(lib.my_csqrt(-1-0.01j), 0.004999937502734214-1.0000124996093955j) + lib.my_csqrtf.argtypes = ctypes.c_float_complex, + lib.my_csqrtf.restype = ctypes.c_float_complex + self.assertAlmostEqual(lib.my_csqrtf(-1+0.01j), + 0.004999937502734214+1.0000124996093955j) + self.assertAlmostEqual(lib.my_csqrtf(-1-0.01j), + 0.004999937502734214-1.0000124996093955j) + lib.my_csqrtl.argtypes = ctypes.c_longdouble_complex, + lib.my_csqrtl.restype = ctypes.c_longdouble_complex + self.assertAlmostEqual(lib.my_csqrtl(-1+0.01j), + 0.004999937502734214+1.0000124996093955j) + self.assertAlmostEqual(lib.my_csqrtl(-1-0.01j), + 0.004999937502734214-1.0000124996093955j) def test_qsort(self): comparefunc = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_char)) diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index b3816f61a6e7aa..b18f05e70386e0 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -146,7 +146,8 @@ def test_floats(self): @unittest.skipUnless(hasattr(ctypes, "c_double_complex"), "requires C11 complex type") def test_complex(self): - for t in [ctypes.c_double_complex]: + for t in [ctypes.c_double_complex, ctypes.c_float_complex, + ctypes.c_longdouble_complex]: self.assertEqual(t(1).value, 1+0j) self.assertEqual(t(1.0).value, 1+0j) self.assertEqual(t(1+0.125j).value, 1+0.125j) @@ -162,9 +163,10 @@ def test_complex_round_trip(self): values = [complex(*_) for _ in combinations([1, -1, 0.0, -0.0, 2, -3, INF, -INF, NAN], 2)] for z in values: - with self.subTest(z=z): - z2 = ctypes.c_double_complex(z).value - self.assertComplexesAreIdentical(z, z2) + for t in [ctypes.c_double_complex, ctypes.c_float_complex, + ctypes.c_longdouble_complex]: + with self.subTest(z=z, t=t): + self.assertComplexesAreIdentical(z, t(z).value) def test_integers(self): f = FloatLike() diff --git a/Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst b/Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst new file mode 100644 index 00000000000000..a1f0d40f56e6a8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst @@ -0,0 +1,4 @@ +Support :c:expr:`float complex` and :c:expr:`long double complex` C types in +:mod:`ctypes` via :class:`~ctypes.c_float_complex` and +:class:`~ctypes.c_longdouble_complex` if compiler has C11 complex +arithmetic. Patch by Sergey B Kirpichev. diff --git a/Modules/_complex.h b/Modules/_complex.h index 1c1d1c8cae51b9..ce7d159542db42 100644 --- a/Modules/_complex.h +++ b/Modules/_complex.h @@ -21,6 +21,8 @@ #if !defined(CMPLX) # if defined(__clang__) && __has_builtin(__builtin_complex) # define CMPLX(x, y) __builtin_complex ((double) (x), (double) (y)) +# define CMPLXF(x, y) __builtin_complex ((float) (x), (float) (y)) +# define CMPLXL(x, y) __builtin_complex ((long double) (x), (long double) (y)) # else static inline double complex CMPLX(double real, double imag) @@ -30,5 +32,21 @@ CMPLX(double real, double imag) ((double *)(&z))[1] = imag; return z; } +static inline float complex +CMPLXF(float real, float imag) +{ + float complex z; + ((float *)(&z))[0] = real; + ((float *)(&z))[1] = imag; + return z; +} +static inline long double complex +CMPLXL(long double real, long double imag) +{ + long double complex z; + ((long double *)(&z))[0] = real; + ((long double *)(&z))[1] = imag; + return z; +} # endif #endif diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 3647361b13a52c..db58f33511c166 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1751,7 +1751,7 @@ class _ctypes.c_void_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd4d9646c56f43a9]*/ #if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) -static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdCfuzZqQPXOv?g"; +static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdCEFfuzZqQPXOv?g"; #else static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; #endif @@ -2234,12 +2234,13 @@ PyCSimpleType_init(PyObject *self, PyObject *args, PyObject *kwds) stginfo->ffi_type_pointer = *fmt->pffi_type; } else { + const size_t els_size = sizeof(fmt->pffi_type->elements); stginfo->ffi_type_pointer.size = fmt->pffi_type->size; stginfo->ffi_type_pointer.alignment = fmt->pffi_type->alignment; stginfo->ffi_type_pointer.type = fmt->pffi_type->type; - stginfo->ffi_type_pointer.elements = PyMem_Malloc(2 * sizeof(ffi_type)); + stginfo->ffi_type_pointer.elements = PyMem_Malloc(els_size); memcpy(stginfo->ffi_type_pointer.elements, - fmt->pffi_type->elements, 2 * sizeof(ffi_type)); + fmt->pffi_type->elements, els_size); } stginfo->align = fmt->pffi_type->alignment; stginfo->length = 0; diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index cbc8f8b0b453af..aa155f88ad26fa 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -454,6 +454,14 @@ EXPORT(double complex) my_csqrt(double complex a) { return csqrt(a); } +EXPORT(float complex) my_csqrtf(float complex a) +{ + return csqrtf(a); +} +EXPORT(long double complex) my_csqrtl(long double complex a) +{ + return csqrtl(a); +} #endif EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*)) diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index a83fa19af32402..fd89d9c67b3fc0 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -657,6 +657,8 @@ union result { void *p; #if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) double complex C; + float complex E; + long double complex F; #endif }; diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 40b72d83d16aeb..2c1fb9b862e12d 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1112,6 +1112,50 @@ C_get(void *ptr, Py_ssize_t size) memcpy(&x, ptr, sizeof(x)); return PyComplex_FromDoubles(creal(x), cimag(x)); } + +static PyObject * +E_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + Py_complex c = PyComplex_AsCComplex(value); + + if (c.real == -1 && PyErr_Occurred()) { + return NULL; + } + float complex x = CMPLXF((float)c.real, (float)c.imag); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +E_get(void *ptr, Py_ssize_t size) +{ + float complex x; + + memcpy(&x, ptr, sizeof(x)); + return PyComplex_FromDoubles(crealf(x), cimagf(x)); +} + +static PyObject * +F_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + Py_complex c = PyComplex_AsCComplex(value); + + if (c.real == -1 && PyErr_Occurred()) { + return NULL; + } + long double complex x = CMPLXL(c.real, c.imag); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +F_get(void *ptr, Py_ssize_t size) +{ + long double complex x; + + memcpy(&x, ptr, sizeof(x)); + return PyComplex_FromDoubles((double)creall(x), (double)cimagl(x)); +} #endif static PyObject * @@ -1621,6 +1665,8 @@ static struct fielddesc formattable[] = { { 'd', d_set, d_get, NULL, d_set_sw, d_get_sw}, #if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) { 'C', C_set, C_get, NULL}, + { 'E', E_set, E_get, NULL}, + { 'F', F_set, F_get, NULL}, #endif { 'g', g_set, g_get, NULL}, { 'f', f_set, f_get, NULL, f_set_sw, f_get_sw}, @@ -1674,6 +1720,8 @@ _ctypes_init_fielddesc(void) case 'd': fd->pffi_type = &ffi_type_double; break; #if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) case 'C': fd->pffi_type = &ffi_type_complex_double; break; + case 'E': fd->pffi_type = &ffi_type_complex_float; break; + case 'F': fd->pffi_type = &ffi_type_complex_longdouble; break; #endif case 'g': fd->pffi_type = &ffi_type_longdouble; break; case 'f': fd->pffi_type = &ffi_type_float; break; diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 5ba5eb3851a690..a794cfe86b5f42 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -401,6 +401,8 @@ struct tagPyCArgObject { void *p; #if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) double complex C; + float complex E; + long double complex F; #endif } value; PyObject *obj; From e2fe2f58e948b17850ee97904073af279f46fb96 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 06:24:44 +0300 Subject: [PATCH 2/7] + typo --- Doc/library/ctypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index fa2518973805f1..b1f780d597e31c 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2306,7 +2306,7 @@ These are the fundamental ctypes data types: .. versionadded:: 3.14 - .. class:: c_float_complex +.. class:: c_float_complex Represents the C :c:expr:`float complex` datatype, if available. The constructor accepts an optional :class:`complex` initializer. From a8f25eaa5116e7c88941582729305ee120df82c6 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 11:04:26 +0300 Subject: [PATCH 3/7] Apply suggestions from code review Co-authored-by: Victor Stinner --- Lib/test/test_ctypes/test_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index b18f05e70386e0..1dd3f2a234b1ee 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -165,7 +165,7 @@ def test_complex_round_trip(self): for z in values: for t in [ctypes.c_double_complex, ctypes.c_float_complex, ctypes.c_longdouble_complex]: - with self.subTest(z=z, t=t): + with self.subTest(z=z, type=t): self.assertComplexesAreIdentical(z, t(z).value) def test_integers(self): From 16bb4bd656b35d8c54fe0b1781e11e2713eec932 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 11:39:54 +0300 Subject: [PATCH 4/7] address review: mostly newlines) --- Lib/test/test_ctypes/test_libc.py | 2 ++ Lib/test/test_ctypes/test_numbers.py | 2 +- Modules/_complex.h | 2 ++ Modules/_ctypes/_ctypes_test.c | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ctypes/test_libc.py b/Lib/test/test_ctypes/test_libc.py index d65ac6d38e8b4b..cab3cc9f46003a 100644 --- a/Lib/test/test_ctypes/test_libc.py +++ b/Lib/test/test_ctypes/test_libc.py @@ -32,12 +32,14 @@ def test_csqrt(self): 0.004999937502734214+1.0000124996093955j) self.assertAlmostEqual(lib.my_csqrt(-1-0.01j), 0.004999937502734214-1.0000124996093955j) + lib.my_csqrtf.argtypes = ctypes.c_float_complex, lib.my_csqrtf.restype = ctypes.c_float_complex self.assertAlmostEqual(lib.my_csqrtf(-1+0.01j), 0.004999937502734214+1.0000124996093955j) self.assertAlmostEqual(lib.my_csqrtf(-1-0.01j), 0.004999937502734214-1.0000124996093955j) + lib.my_csqrtl.argtypes = ctypes.c_longdouble_complex, lib.my_csqrtl.restype = ctypes.c_longdouble_complex self.assertAlmostEqual(lib.my_csqrtl(-1+0.01j), diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index 1dd3f2a234b1ee..145f230d2e9665 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -166,7 +166,7 @@ def test_complex_round_trip(self): for t in [ctypes.c_double_complex, ctypes.c_float_complex, ctypes.c_longdouble_complex]: with self.subTest(z=z, type=t): - self.assertComplexesAreIdentical(z, t(z).value) + self.assertComplexesAreIdentical(z, type(z).value) def test_integers(self): f = FloatLike() diff --git a/Modules/_complex.h b/Modules/_complex.h index ce7d159542db42..28d4a32794b97c 100644 --- a/Modules/_complex.h +++ b/Modules/_complex.h @@ -32,6 +32,7 @@ CMPLX(double real, double imag) ((double *)(&z))[1] = imag; return z; } + static inline float complex CMPLXF(float real, float imag) { @@ -40,6 +41,7 @@ CMPLXF(float real, float imag) ((float *)(&z))[1] = imag; return z; } + static inline long double complex CMPLXL(long double real, long double imag) { diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index aa155f88ad26fa..b8e613fd669d1b 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -454,10 +454,12 @@ EXPORT(double complex) my_csqrt(double complex a) { return csqrt(a); } + EXPORT(float complex) my_csqrtf(float complex a) { return csqrtf(a); } + EXPORT(long double complex) my_csqrtl(long double complex a) { return csqrtl(a); From e9fe1326b091560c275c787c00d608ade29205fd Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 11:57:00 +0300 Subject: [PATCH 5/7] address review: news + typo --- Lib/test/test_ctypes/test_numbers.py | 2 +- .../Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst | 8 +++++--- .../Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst | 4 ---- 3 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index 145f230d2e9665..1dd3f2a234b1ee 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -166,7 +166,7 @@ def test_complex_round_trip(self): for t in [ctypes.c_double_complex, ctypes.c_float_complex, ctypes.c_longdouble_complex]: with self.subTest(z=z, type=t): - self.assertComplexesAreIdentical(z, type(z).value) + self.assertComplexesAreIdentical(z, t(z).value) def test_integers(self): f = FloatLike() diff --git a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst index 7b11d8c303c2f6..e27322fdb55dff 100644 --- a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst +++ b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst @@ -1,3 +1,5 @@ -Support :c:expr:`double complex` C type in :mod:`ctypes` via -:class:`~ctypes.c_double_complex` if compiler has C11 complex -arithmetic. Patch by Sergey B Kirpichev. +Support :c:expr:`float complex`, :c:expr:`double complex` and +:c:expr:`long double complex` C types in :mod:`ctypes` via :mod:`ctypes` +:class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` +:class:`~ctypes.c_longdouble_complex` if compiler has C11 complex arithmetic. +Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst b/Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst deleted file mode 100644 index a1f0d40f56e6a8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-02-05-08-16.gh-issue-61103.TMxkuM.rst +++ /dev/null @@ -1,4 +0,0 @@ -Support :c:expr:`float complex` and :c:expr:`long double complex` C types in -:mod:`ctypes` via :class:`~ctypes.c_float_complex` and -:class:`~ctypes.c_longdouble_complex` if compiler has C11 complex -arithmetic. Patch by Sergey B Kirpichev. From 0bb9ba3f6cc2ddc21475463b94d97bf8c350fb53 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 12:01:45 +0300 Subject: [PATCH 6/7] Update Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst --- .../Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst index e27322fdb55dff..70382cb4a279a8 100644 --- a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst +++ b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst @@ -1,5 +1,5 @@ Support :c:expr:`float complex`, :c:expr:`double complex` and -:c:expr:`long double complex` C types in :mod:`ctypes` via :mod:`ctypes` -:class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` +:c:expr:`long double complex` C types in :mod:`ctypes` as +:class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` and :class:`~ctypes.c_longdouble_complex` if compiler has C11 complex arithmetic. Patch by Sergey B Kirpichev. From 061c45bc75d74275cd20e75d47a28a176b76e85c Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 2 Jul 2024 13:55:36 +0300 Subject: [PATCH 7/7] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/library/ctypes.rst | 4 ++-- .../Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index b1f780d597e31c..e3d74d7dc0d91c 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -272,10 +272,10 @@ complex types are available: +----------------------------------+---------------------------------+-----------------+ | ctypes type | C type | Python type | +==================================+=================================+=================+ -| :class:`c_double_complex` | :c:expr:`double complex` | complex | -+----------------------------------+---------------------------------+-----------------+ | :class:`c_float_complex` | :c:expr:`float complex` | complex | +----------------------------------+---------------------------------+-----------------+ +| :class:`c_double_complex` | :c:expr:`double complex` | complex | ++----------------------------------+---------------------------------+-----------------+ | :class:`c_longdouble_complex` | :c:expr:`long double complex` | complex | +----------------------------------+---------------------------------+-----------------+ diff --git a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst index 70382cb4a279a8..890eb62010eb33 100644 --- a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst +++ b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst @@ -1,5 +1,5 @@ Support :c:expr:`float complex`, :c:expr:`double complex` and :c:expr:`long double complex` C types in :mod:`ctypes` as :class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` and -:class:`~ctypes.c_longdouble_complex` if compiler has C11 complex arithmetic. +:class:`~ctypes.c_longdouble_complex` if the compiler has C11 complex arithmetic. Patch by Sergey B Kirpichev.