-
-
Couldn't load subscription status.
- Fork 33.2k
gh-121249: unconditionally support complex types in struct
#132864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
89ca6a2
e287449
78ff902
9bbe78e
e340cdf
78ce03e
71415f0
0efae27
c37724f
38fa2a7
288ad10
70a3c6b
8346715
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Always support the :c:expr:`float complex` and :c:expr:`double complex` C types in | ||
| the :mod:`struct` module. Patch by Sergey B Kirpichev. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,9 +12,6 @@ | |
| #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] | ||
|
|
@@ -495,25 +492,23 @@ nu_double(_structmodulestate *state, const char *p, const formatdef *f) | |
| return PyFloat_FromDouble(x); | ||
| } | ||
|
|
||
| #ifdef Py_HAVE_C_COMPLEX | ||
| static PyObject * | ||
| nu_float_complex(_structmodulestate *state, const char *p, const formatdef *f) | ||
| { | ||
| float complex x; | ||
| float x[2]; | ||
|
|
||
| memcpy(&x, p, sizeof(x)); | ||
| return PyComplex_FromDoubles(creal(x), cimag(x)); | ||
| return PyComplex_FromDoubles(x[0], x[1]); | ||
| } | ||
|
|
||
| static PyObject * | ||
| nu_double_complex(_structmodulestate *state, const char *p, const formatdef *f) | ||
| { | ||
| double complex x; | ||
| double x[2]; | ||
|
|
||
| memcpy(&x, p, sizeof(x)); | ||
| return PyComplex_FromDoubles(creal(x), cimag(x)); | ||
| return PyComplex_FromDoubles(x[0], x[1]); | ||
| } | ||
| #endif | ||
|
|
||
| static PyObject * | ||
| nu_void_p(_structmodulestate *state, const char *p, const formatdef *f) | ||
|
|
@@ -788,13 +783,12 @@ np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
| return 0; | ||
| } | ||
|
|
||
| #ifdef Py_HAVE_C_COMPLEX | ||
| static int | ||
| np_float_complex(_structmodulestate *state, char *p, PyObject *v, | ||
| const formatdef *f) | ||
| { | ||
| Py_complex c = PyComplex_AsCComplex(v); | ||
| float complex x = CMPLXF((float)c.real, (float)c.imag); | ||
| float x[2] = {(float)c.real, (float)c.imag}; | ||
|
|
||
| if (c.real == -1 && PyErr_Occurred()) { | ||
| PyErr_SetString(state->StructError, | ||
|
|
@@ -810,7 +804,7 @@ 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); | ||
| double x[2] = {c.real, c.imag}; | ||
|
|
||
| if (c.real == -1 && PyErr_Occurred()) { | ||
| PyErr_SetString(state->StructError, | ||
|
|
@@ -820,25 +814,6 @@ np_double_complex(_structmodulestate *state, char *p, PyObject *v, | |
| memcpy(p, &x, sizeof(x)); | ||
| return 0; | ||
| } | ||
| #else | ||
| static int | ||
| np_complex_stub(_structmodulestate *state, char *p, PyObject *v, | ||
| const formatdef *f) | ||
| { | ||
| PyErr_Format(state->StructError, | ||
| "'%c' format not supported on this system", | ||
| f->format); | ||
| return -1; | ||
| } | ||
| static PyObject * | ||
| nu_complex_stub(_structmodulestate *state, const char *p, const formatdef *f) | ||
| { | ||
| PyErr_Format(state->StructError, | ||
| "'%c' format not supported on this system", | ||
| f->format); | ||
| return NULL; | ||
| } | ||
| #endif | ||
|
|
||
| static int | ||
| np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | ||
|
|
@@ -878,13 +853,8 @@ static const formatdef native_table[] = { | |
| {'e', sizeof(short), _Alignof(short), nu_halffloat, np_halffloat}, | ||
| {'f', sizeof(float), _Alignof(float), nu_float, np_float}, | ||
| {'d', sizeof(double), _Alignof(double), nu_double, np_double}, | ||
| #ifdef Py_HAVE_C_COMPLEX | ||
| {'F', sizeof(float complex), _Alignof(float complex), nu_float_complex, np_float_complex}, | ||
| {'D', sizeof(double complex), _Alignof(double complex), nu_double_complex, np_double_complex}, | ||
| #else | ||
| {'F', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| {'D', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| #endif | ||
| {'F', 2*sizeof(float), _Alignof(float[2]), nu_float_complex, np_float_complex}, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something we should actually care in the future but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK, C23 calls it an "Alternative Spelling". I wouldn't worry about it. |
||
| {'D', 2*sizeof(double), _Alignof(double[2]), nu_double_complex, np_double_complex}, | ||
| {'P', sizeof(void *), _Alignof(void *), nu_void_p, np_void_p}, | ||
| {0} | ||
| }; | ||
|
|
@@ -985,7 +955,6 @@ bu_double(_structmodulestate *state, const char *p, const formatdef *f) | |
| return unpack_double(p, 0); | ||
| } | ||
|
|
||
| #ifdef Py_HAVE_C_COMPLEX | ||
| static PyObject * | ||
| bu_float_complex(_structmodulestate *state, const char *p, const formatdef *f) | ||
| { | ||
|
|
@@ -1015,7 +984,6 @@ bu_double_complex(_structmodulestate *state, const char *p, const formatdef *f) | |
| } | ||
| return PyComplex_FromDoubles(x, y); | ||
| } | ||
| #endif | ||
|
|
||
| static PyObject * | ||
| bu_bool(_structmodulestate *state, const char *p, const formatdef *f) | ||
|
|
@@ -1156,7 +1124,6 @@ bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
| return PyFloat_Pack8(x, p, 0); | ||
| } | ||
|
|
||
| #ifdef Py_HAVE_C_COMPLEX | ||
| static int | ||
| bp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | ||
| { | ||
|
|
@@ -1186,7 +1153,6 @@ bp_double_complex(_structmodulestate *state, char *p, PyObject *v, const formatd | |
| } | ||
| return PyFloat_Pack8(x.imag, p + 8, 0); | ||
| } | ||
| #endif | ||
|
|
||
| static int | ||
| bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | ||
|
|
@@ -1218,13 +1184,8 @@ static formatdef bigendian_table[] = { | |
| {'e', 2, 0, bu_halffloat, bp_halffloat}, | ||
| {'f', 4, 0, bu_float, bp_float}, | ||
| {'d', 8, 0, bu_double, bp_double}, | ||
| #ifdef Py_HAVE_C_COMPLEX | ||
| {'F', 8, 0, bu_float_complex, bp_float_complex}, | ||
| {'D', 16, 0, bu_double_complex, bp_double_complex}, | ||
| #else | ||
| {'F', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| {'D', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| #endif | ||
| {0} | ||
| }; | ||
|
|
||
|
|
@@ -1324,7 +1285,6 @@ lu_double(_structmodulestate *state, const char *p, const formatdef *f) | |
| return unpack_double(p, 1); | ||
| } | ||
|
|
||
| #ifdef Py_HAVE_C_COMPLEX | ||
| static PyObject * | ||
| lu_float_complex(_structmodulestate *state, const char *p, const formatdef *f) | ||
| { | ||
|
|
@@ -1354,7 +1314,6 @@ lu_double_complex(_structmodulestate *state, const char *p, const formatdef *f) | |
| } | ||
| return PyComplex_FromDoubles(x, y); | ||
| } | ||
| #endif | ||
|
|
||
| static int | ||
| lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | ||
|
|
@@ -1489,7 +1448,6 @@ lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
| return PyFloat_Pack8(x, p, 1); | ||
| } | ||
|
|
||
| #ifdef Py_HAVE_C_COMPLEX | ||
| static int | ||
| lp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | ||
| { | ||
|
|
@@ -1520,7 +1478,6 @@ lp_double_complex(_structmodulestate *state, char *p, PyObject *v, const formatd | |
| } | ||
| return PyFloat_Pack8(x.imag, p + 8, 1); | ||
| } | ||
| #endif | ||
|
|
||
| static formatdef lilendian_table[] = { | ||
| {'x', 1, 0, NULL}, | ||
|
|
@@ -1542,13 +1499,8 @@ static formatdef lilendian_table[] = { | |
| {'e', 2, 0, lu_halffloat, lp_halffloat}, | ||
| {'f', 4, 0, lu_float, lp_float}, | ||
| {'d', 8, 0, lu_double, lp_double}, | ||
| #ifdef Py_HAVE_C_COMPLEX | ||
| {'F', 8, 0, lu_float_complex, lp_float_complex}, | ||
| {'D', 16, 0, lu_double_complex, lp_double_complex}, | ||
| #else | ||
| {'F', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| {'D', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| #endif | ||
| {0} | ||
| }; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.