Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Add support for C99 complex type (_Complex) to the struct module #121249

Copy link
Copy link
Closed
@skirpichev

Description

@skirpichev
Issue body actions

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

nineteendo

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirC modules in the Modules dirtype-featureA feature request or enhancementA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.