| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -260,24 +260,17 @@ platform-dependent. | |||
| 260 | 260 | +--------+--------------------------+--------------------+----------------+------------+ | |
| 261 | 261 | | ``d`` | :c:expr:`double` | float | 8 | \(4) | | |
| 262 | 262 | +--------+--------------------------+--------------------+----------------+------------+ | |
| 263 | + | ``F`` | :c:expr:`float complex` | complex | 8 | \(10) | | ||
| 264 | + +--------+--------------------------+--------------------+----------------+------------+ | ||
| 265 | + | ``D`` | :c:expr:`double complex` | complex | 16 | \(10) | | ||
| 266 | + +--------+--------------------------+--------------------+----------------+------------+ | ||
| 263 | 267 | | ``s`` | :c:expr:`char[]` | bytes | | \(9) | | |
| 264 | 268 | +--------+--------------------------+--------------------+----------------+------------+ | |
| 265 | 269 | | ``p`` | :c:expr:`char[]` | bytes | | \(8) | | |
| 266 | 270 | +--------+--------------------------+--------------------+----------------+------------+ | |
| 267 | 271 | | ``P`` | :c:expr:`void \*` | integer | | \(5) | | |
| 268 | 272 | +--------+--------------------------+--------------------+----------------+------------+ | |
| 269 | 273 | ||
| 270 | - Additionally, if IEC 60559 compatible complex arithmetic (Annex G of the | ||
| 271 | - C11 standard) is supported, the following format characters are available: | ||
| 272 | - | ||
| 273 | - +--------+--------------------------+--------------------+----------------+------------+ | ||
| 274 | - | Format | C Type | Python type | Standard size | Notes | | ||
| 275 | - +========+==========================+====================+================+============+ | ||
| 276 | - | ``F`` | :c:expr:`float complex` | complex | 8 | \(10) | | ||
| 277 | - +--------+--------------------------+--------------------+----------------+------------+ | ||
| 278 | - | ``D`` | :c:expr:`double complex` | complex | 16 | \(10) | | ||
| 279 | - +--------+--------------------------+--------------------+----------------+------------+ | ||
| 280 | - | ||
| 281 | 274 | .. versionchanged:: 3.3 | |
| 282 | 275 | Added support for the ``'n'`` and ``'N'`` formats. | |
| 283 | 276 | ||
@@ -367,6 +360,11 @@ Notes: | |||
| 367 | 360 | For the ``'E'`` and ``'C'`` format characters, the packed representation uses | |
| 368 | 361 | the IEEE 754 binary32 and binary64 format for components of the complex | |
| 369 | 362 | number, regardless of the floating-point format used by the platform. | |
| 363 | + Note that complex types (``F`` and ``D``) are available unconditionally, | ||
| 364 | + despite complex types being an optional feature in C. | ||
| 365 | + As specified in the C11 standard, each complex type is represented by a | ||
| 366 | + two-element C array containing, respectively, the real and imaginary parts. | ||
| 367 | + | ||
| 370 | 368 | ||
| 371 | 369 | A format character may be preceded by an integral repeat count. For example, | |
| 372 | 370 | the format string ``'4h'`` means exactly the same as ``'hhhh'``. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1313,8 +1313,8 @@ struct | |||
| 1313 | 1313 | ------ | |
| 1314 | 1314 | ||
| 1315 | 1315 | * Support the :c:expr:`float complex` and :c:expr:`double complex` C types in | |
| 1316 | - the :mod:`struct` module (formatting characters ``'F'`` and ``'D'``, | ||
| 1317 | - respectively) if the compiler has C11 complex arithmetic. | ||
| 1316 | + the :mod:`struct` module (formatting characters ``'F'`` and ``'D'`` | ||
| 1317 | + respectively). | ||
| 1318 | 1318 | (Contributed by Sergey B Kirpichev in :gh:`121249`.) | |
| 1319 | 1319 | ||
| 1320 | 1320 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,12 +22,6 @@ | |||
| 22 | 22 | INF = float('inf') | |
| 23 | 23 | NAN = float('nan') | |
| 24 | 24 | ||
| 25 | - try: | ||
| 26 | - struct.pack('D', 1j) | ||
| 27 | - have_c_complex = True | ||
| 28 | - except struct.error: | ||
| 29 | - have_c_complex = False | ||
| 30 | - | ||
| 31 | 25 | def iter_integer_formats(byteorders=byteorders): | |
| 32 | 26 | for code in integer_codes: | |
| 33 | 27 | for byteorder in byteorders: | |
@@ -796,7 +790,6 @@ def test_repr(self): | |||
| 796 | 790 | s = struct.Struct('=i2H') | |
| 797 | 791 | self.assertEqual(repr(s), f'Struct({s.format!r})') | |
| 798 | 792 | ||
| 799 | - @unittest.skipUnless(have_c_complex, "requires C11 complex type support") | ||
| 800 | 793 | def test_c_complex_round_trip(self): | |
| 801 | 794 | values = [complex(*_) for _ in combinations([1, -1, 0.0, -0.0, 2, | |
| 802 | 795 | -3, INF, -INF, NAN], 2)] | |
@@ -806,19 +799,6 @@ def test_c_complex_round_trip(self): | |||
| 806 | 799 | round_trip = struct.unpack(f, struct.pack(f, z))[0] | |
| 807 | 800 | self.assertComplexesAreIdentical(z, round_trip) | |
| 808 | 801 | ||
| 809 | - @unittest.skipIf(have_c_complex, "requires no C11 complex type support") | ||
| 810 | - def test_c_complex_error(self): | ||
| 811 | - msg1 = "'F' format not supported on this system" | ||
| 812 | - msg2 = "'D' format not supported on this system" | ||
| 813 | - with self.assertRaisesRegex(struct.error, msg1): | ||
| 814 | - struct.pack('F', 1j) | ||
| 815 | - with self.assertRaisesRegex(struct.error, msg1): | ||
| 816 | - struct.unpack('F', b'1') | ||
| 817 | - with self.assertRaisesRegex(struct.error, msg2): | ||
| 818 | - struct.pack('D', 1j) | ||
| 819 | - with self.assertRaisesRegex(struct.error, msg2): | ||
| 820 | - struct.unpack('D', b'1') | ||
| 821 | - | ||
| 822 | 802 | ||
| 823 | 803 | class UnpackIteratorTest(unittest.TestCase): | |
| 824 | 804 | """ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Always support the :c:expr:`float complex` and :c:expr:`double complex` C types in | ||
| 2 | + the :mod:`struct` module. Patch by Sergey B Kirpichev. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,9 +12,6 @@ | |||
| 12 | 12 | #include "pycore_long.h" // _PyLong_AsByteArray() | |
| 13 | 13 | #include "pycore_moduleobject.h" // _PyModule_GetState() | |
| 14 | 14 | ||
| 15 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 16 | - # include "_complex.h" // complex | ||
| 17 | - #endif | ||
| 18 | 15 | #include <stddef.h> // offsetof() | |
| 19 | 16 | ||
| 20 | 17 | /*[clinic input] | |
@@ -495,25 +492,23 @@ nu_double(_structmodulestate *state, const char *p, const formatdef *f) | |||
| 495 | 492 | return PyFloat_FromDouble(x); | |
| 496 | 493 | } | |
| 497 | 494 | ||
| 498 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 499 | 495 | static PyObject * | |
| 500 | 496 | nu_float_complex(_structmodulestate *state, const char *p, const formatdef *f) | |
| 501 | 497 | { | |
| 502 | - float complex x; | ||
| 498 | + float x[2]; | ||
| 503 | 499 | ||
| 504 | 500 | memcpy(&x, p, sizeof(x)); | |
| 505 | - return PyComplex_FromDoubles(creal(x), cimag(x)); | ||
| 501 | + return PyComplex_FromDoubles(x[0], x[1]); | ||
| 506 | 502 | } | |
| 507 | 503 | ||
| 508 | 504 | static PyObject * | |
| 509 | 505 | nu_double_complex(_structmodulestate *state, const char *p, const formatdef *f) | |
| 510 | 506 | { | |
| 511 | - double complex x; | ||
| 507 | + double x[2]; | ||
| 512 | 508 | ||
| 513 | 509 | memcpy(&x, p, sizeof(x)); | |
| 514 | - return PyComplex_FromDoubles(creal(x), cimag(x)); | ||
| 510 | + return PyComplex_FromDoubles(x[0], x[1]); | ||
| 515 | 511 | } | |
| 516 | - #endif | ||
| 517 | 512 | ||
| 518 | 513 | static PyObject * | |
| 519 | 514 | 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) | |||
| 788 | 783 | return 0; | |
| 789 | 784 | } | |
| 790 | 785 | ||
| 791 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 792 | 786 | static int | |
| 793 | 787 | np_float_complex(_structmodulestate *state, char *p, PyObject *v, | |
| 794 | 788 | const formatdef *f) | |
| 795 | 789 | { | |
| 796 | 790 | Py_complex c = PyComplex_AsCComplex(v); | |
| 797 | - float complex x = CMPLXF((float)c.real, (float)c.imag); | ||
| 791 | + float x[2] = {(float)c.real, (float)c.imag}; | ||
| 798 | 792 | ||
| 799 | 793 | if (c.real == -1 && PyErr_Occurred()) { | |
| 800 | 794 | PyErr_SetString(state->StructError, | |
@@ -810,7 +804,7 @@ np_double_complex(_structmodulestate *state, char *p, PyObject *v, | |||
| 810 | 804 | const formatdef *f) | |
| 811 | 805 | { | |
| 812 | 806 | Py_complex c = PyComplex_AsCComplex(v); | |
| 813 | - double complex x = CMPLX(c.real, c.imag); | ||
| 807 | + double x[2] = {c.real, c.imag}; | ||
| 814 | 808 | ||
| 815 | 809 | if (c.real == -1 && PyErr_Occurred()) { | |
| 816 | 810 | PyErr_SetString(state->StructError, | |
@@ -820,25 +814,6 @@ np_double_complex(_structmodulestate *state, char *p, PyObject *v, | |||
| 820 | 814 | memcpy(p, &x, sizeof(x)); | |
| 821 | 815 | return 0; | |
| 822 | 816 | } | |
| 823 | - #else | ||
| 824 | - static int | ||
| 825 | - np_complex_stub(_structmodulestate *state, char *p, PyObject *v, | ||
| 826 | - const formatdef *f) | ||
| 827 | - { | ||
| 828 | - PyErr_Format(state->StructError, | ||
| 829 | - "'%c' format not supported on this system", | ||
| 830 | - f->format); | ||
| 831 | - return -1; | ||
| 832 | - } | ||
| 833 | - static PyObject * | ||
| 834 | - nu_complex_stub(_structmodulestate *state, const char *p, const formatdef *f) | ||
| 835 | - { | ||
| 836 | - PyErr_Format(state->StructError, | ||
| 837 | - "'%c' format not supported on this system", | ||
| 838 | - f->format); | ||
| 839 | - return NULL; | ||
| 840 | - } | ||
| 841 | - #endif | ||
| 842 | 817 | ||
| 843 | 818 | static int | |
| 844 | 819 | np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
@@ -878,13 +853,8 @@ static const formatdef native_table[] = { | |||
| 878 | 853 | {'e', sizeof(short), _Alignof(short), nu_halffloat, np_halffloat}, | |
| 879 | 854 | {'f', sizeof(float), _Alignof(float), nu_float, np_float}, | |
| 880 | 855 | {'d', sizeof(double), _Alignof(double), nu_double, np_double}, | |
| 881 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 882 | - {'F', sizeof(float complex), _Alignof(float complex), nu_float_complex, np_float_complex}, | ||
| 883 | - {'D', sizeof(double complex), _Alignof(double complex), nu_double_complex, np_double_complex}, | ||
| 884 | - #else | ||
| 885 | - {'F', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| 886 | - {'D', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| 887 | - #endif | ||
| 856 | + {'F', 2*sizeof(float), _Alignof(float[2]), nu_float_complex, np_float_complex}, | ||
| 857 | + {'D', 2*sizeof(double), _Alignof(double[2]), nu_double_complex, np_double_complex}, | ||
| 888 | 858 | {'P', sizeof(void *), _Alignof(void *), nu_void_p, np_void_p}, | |
| 889 | 859 | {0} | |
| 890 | 860 | }; | |
@@ -985,7 +955,6 @@ bu_double(_structmodulestate *state, const char *p, const formatdef *f) | |||
| 985 | 955 | return unpack_double(p, 0); | |
| 986 | 956 | } | |
| 987 | 957 | ||
| 988 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 989 | 958 | static PyObject * | |
| 990 | 959 | bu_float_complex(_structmodulestate *state, const char *p, const formatdef *f) | |
| 991 | 960 | { | |
@@ -1015,7 +984,6 @@ bu_double_complex(_structmodulestate *state, const char *p, const formatdef *f) | |||
| 1015 | 984 | } | |
| 1016 | 985 | return PyComplex_FromDoubles(x, y); | |
| 1017 | 986 | } | |
| 1018 | - #endif | ||
| 1019 | 987 | ||
| 1020 | 988 | static PyObject * | |
| 1021 | 989 | 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) | |||
| 1156 | 1124 | return PyFloat_Pack8(x, p, 0); | |
| 1157 | 1125 | } | |
| 1158 | 1126 | ||
| 1159 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 1160 | 1127 | static int | |
| 1161 | 1128 | bp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
| 1162 | 1129 | { | |
@@ -1186,7 +1153,6 @@ bp_double_complex(_structmodulestate *state, char *p, PyObject *v, const formatd | |||
| 1186 | 1153 | } | |
| 1187 | 1154 | return PyFloat_Pack8(x.imag, p + 8, 0); | |
| 1188 | 1155 | } | |
| 1189 | - #endif | ||
| 1190 | 1156 | ||
| 1191 | 1157 | static int | |
| 1192 | 1158 | bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
@@ -1218,13 +1184,8 @@ static formatdef bigendian_table[] = { | |||
| 1218 | 1184 | {'e', 2, 0, bu_halffloat, bp_halffloat}, | |
| 1219 | 1185 | {'f', 4, 0, bu_float, bp_float}, | |
| 1220 | 1186 | {'d', 8, 0, bu_double, bp_double}, | |
| 1221 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 1222 | 1187 | {'F', 8, 0, bu_float_complex, bp_float_complex}, | |
| 1223 | 1188 | {'D', 16, 0, bu_double_complex, bp_double_complex}, | |
| 1224 | - #else | ||
| 1225 | - {'F', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| 1226 | - {'D', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| 1227 | - #endif | ||
| 1228 | 1189 | {0} | |
| 1229 | 1190 | }; | |
| 1230 | 1191 | ||
@@ -1324,7 +1285,6 @@ lu_double(_structmodulestate *state, const char *p, const formatdef *f) | |||
| 1324 | 1285 | return unpack_double(p, 1); | |
| 1325 | 1286 | } | |
| 1326 | 1287 | ||
| 1327 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 1328 | 1288 | static PyObject * | |
| 1329 | 1289 | lu_float_complex(_structmodulestate *state, const char *p, const formatdef *f) | |
| 1330 | 1290 | { | |
@@ -1354,7 +1314,6 @@ lu_double_complex(_structmodulestate *state, const char *p, const formatdef *f) | |||
| 1354 | 1314 | } | |
| 1355 | 1315 | return PyComplex_FromDoubles(x, y); | |
| 1356 | 1316 | } | |
| 1357 | - #endif | ||
| 1358 | 1317 | ||
| 1359 | 1318 | static int | |
| 1360 | 1319 | 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) | |||
| 1489 | 1448 | return PyFloat_Pack8(x, p, 1); | |
| 1490 | 1449 | } | |
| 1491 | 1450 | ||
| 1492 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 1493 | 1451 | static int | |
| 1494 | 1452 | lp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) | |
| 1495 | 1453 | { | |
@@ -1520,7 +1478,6 @@ lp_double_complex(_structmodulestate *state, char *p, PyObject *v, const formatd | |||
| 1520 | 1478 | } | |
| 1521 | 1479 | return PyFloat_Pack8(x.imag, p + 8, 1); | |
| 1522 | 1480 | } | |
| 1523 | - #endif | ||
| 1524 | 1481 | ||
| 1525 | 1482 | static formatdef lilendian_table[] = { | |
| 1526 | 1483 | {'x', 1, 0, NULL}, | |
@@ -1542,13 +1499,8 @@ static formatdef lilendian_table[] = { | |||
| 1542 | 1499 | {'e', 2, 0, lu_halffloat, lp_halffloat}, | |
| 1543 | 1500 | {'f', 4, 0, lu_float, lp_float}, | |
| 1544 | 1501 | {'d', 8, 0, lu_double, lp_double}, | |
| 1545 | - #ifdef Py_HAVE_C_COMPLEX | ||
| 1546 | 1502 | {'F', 8, 0, lu_float_complex, lp_float_complex}, | |
| 1547 | 1503 | {'D', 16, 0, lu_double_complex, lp_double_complex}, | |
| 1548 | - #else | ||
| 1549 | - {'F', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| 1550 | - {'D', 1, 0, nu_complex_stub, np_complex_stub}, | ||
| 1551 | - #endif | ||
| 1552 | 1504 | {0} | |
| 1553 | 1505 | }; | |
| 1554 | 1506 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments