Closed
Description
Feature or enhancement
Proposal:
The struct module has support for float
and double
types, so at least there should be also float _Complex
and double _Complex
. I'll work on a patch.
Initial version
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index d2e6a8bfc8..d941036719 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -208,6 +208,7 @@ class c_longdouble(_SimpleCData):
try:
class c_double_complex(_SimpleCData):
_type_ = "C"
+ _check_size(c_double_complex)
except AttributeError:
pass
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 6a68478dd4..caf4975413 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -12,6 +12,9 @@
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
+#ifdef Py_HAVE_C_COMPLEX
+# include "_complex.h" // complex
+#endif
#include <stddef.h> // offsetof()
/*[clinic input]
@@ -80,6 +83,9 @@ typedef struct { char c; int x; } st_int;
typedef struct { char c; long x; } st_long;
typedef struct { char c; float x; } st_float;
typedef struct { char c; double x; } st_double;
+#ifdef Py_HAVE_C_COMPLEX
+typedef struct { char c; double complex x; } st_double_complex;
+#endif
typedef struct { char c; void *x; } st_void_p;
typedef struct { char c; size_t x; } st_size_t;
typedef struct { char c; _Bool x; } st_bool;
@@ -89,6 +95,9 @@ typedef struct { char c; _Bool x; } st_bool;
#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
+#ifdef Py_HAVE_C_COMPLEX
+#define DOUBLE_COMPLEX_ALIGN (sizeof(st_double_complex) - sizeof(double complex))
+#endif
#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
@@ -518,6 +527,17 @@ nu_double(_structmodulestate *state, const char *p, const formatdef *f)
return PyFloat_FromDouble(x);
}
+#ifdef Py_HAVE_C_COMPLEX
+static PyObject *
+nu_double_complex(_structmodulestate *state, const char *p, const formatdef *f)
+{
+ double complex x;
+
+ memcpy(&x, p, sizeof(x));
+ return PyComplex_FromDoubles(creal(x), cimag(x));
+}
+#endif
+
static PyObject *
nu_void_p(_structmodulestate *state, const char *p, const formatdef *f)
{
@@ -791,6 +811,24 @@ np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
return 0;
}
+#ifdef Py_HAVE_C_COMPLEX
+static int
+np_double_complex(_structmodulestate *state, char *p, PyObject *v,
+ const formatdef *f)
+{
+ Py_complex c = PyComplex_AsCComplex(v);
+ double complex x = CMPLX(c.real, c.imag);
+
+ if (c.real == -1 && PyErr_Occurred()) {
+ PyErr_SetString(state->StructError,
+ "required argument is not a complex");
+ return -1;
+ }
+ memcpy(p, (char *)&x, sizeof(x));
+ return 0;
+}
+#endif
+
static int
np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
@@ -829,6 +867,9 @@ static const formatdef native_table[] = {
{'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
{'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
{'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
+#ifdef Py_HAVE_C_COMPLEX
+ {'C', sizeof(double complex), DOUBLE_COMPLEX_ALIGN, nu_double_complex, np_double_complex},
+#endif
{'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
{0}
};
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
- gh-121249: Support _Complex types in the struct module #121613
- gh-121249: Note struct module changes in What's New #131867
- gh-121249: adjust formatting codes for complex types in struct/ctypes modules #132827
- gh-121249: fix naming of struct tagPyCArgObject members #132863
- gh-121249: unconditionally support
complex
types instruct
#132864 - gh-121249: fix complex formatting codes in the struct docs (note 10) #133249