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

Commit 7487db4

Browse filesBrowse files
skirpichevZeroIntensitypicnixzvstinner
authored
gh-121249: Support _Complex types in the struct module (#121613)
Co-authored-by: Peter Bierma <zintensitydev@gmail.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent f55273b commit 7487db4
Copy full SHA for 7487db4

File tree

Expand file treeCollapse file tree

5 files changed

+321
-29
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+321
-29
lines changed

‎Doc/library/struct.rst

Copy file name to clipboardExpand all lines: Doc/library/struct.rst
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,26 @@ platform-dependent.
267267
| ``P`` | :c:expr:`void \*` | integer | | \(5) |
268268
+--------+--------------------------+--------------------+----------------+------------+
269269

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+
| ``E`` | :c:expr:`float complex` | complex | 8 | \(10) |
277+
+--------+--------------------------+--------------------+----------------+------------+
278+
| ``C`` | :c:expr:`double complex` | complex | 16 | \(10) |
279+
+--------+--------------------------+--------------------+----------------+------------+
280+
270281
.. versionchanged:: 3.3
271282
Added support for the ``'n'`` and ``'N'`` formats.
272283

273284
.. versionchanged:: 3.6
274285
Added support for the ``'e'`` format.
275286

287+
.. versionchanged:: 3.14
288+
Added support for the ``'E'`` and ``'C'`` formats.
289+
276290

277291
Notes:
278292

@@ -349,6 +363,11 @@ Notes:
349363
of bytes. As a special case, ``'0s'`` means a single, empty string (while
350364
``'0c'`` means 0 characters).
351365

366+
(10)
367+
For the ``'E'`` and ``'C'`` format characters, the packed representation uses
368+
the IEEE 754 binary32 and binary64 format for components of the complex
369+
number, regardless of the floating-point format used by the platform.
370+
352371
A format character may be preceded by an integral repeat count. For example,
353372
the format string ``'4h'`` means exactly the same as ``'hhhh'``.
354373

‎Lib/ctypes/__init__.py

Copy file name to clipboardExpand all lines: Lib/ctypes/__init__.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,10 @@ class c_longdouble(_SimpleCData):
208208
try:
209209
class c_double_complex(_SimpleCData):
210210
_type_ = "C"
211+
_check_size(c_double_complex)
211212
class c_float_complex(_SimpleCData):
212213
_type_ = "E"
214+
_check_size(c_float_complex)
213215
class c_longdouble_complex(_SimpleCData):
214216
_type_ = "F"
215217
except AttributeError:

‎Lib/test/test_struct.py

Copy file name to clipboardExpand all lines: Lib/test/test_struct.py
+36-1Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections import abc
2+
from itertools import combinations
23
import array
34
import gc
45
import math
@@ -11,12 +12,22 @@
1112
from test import support
1213
from test.support import import_helper, suppress_immortalization
1314
from test.support.script_helper import assert_python_ok
15+
from test.support.testcase import ComplexesAreIdenticalMixin
1416

1517
ISBIGENDIAN = sys.byteorder == "big"
1618

1719
integer_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'n', 'N'
1820
byteorders = '', '@', '=', '<', '>', '!'
1921

22+
INF = float('inf')
23+
NAN = float('nan')
24+
25+
try:
26+
struct.pack('C', 1j)
27+
have_c_complex = True
28+
except struct.error:
29+
have_c_complex = False
30+
2031
def iter_integer_formats(byteorders=byteorders):
2132
for code in integer_codes:
2233
for byteorder in byteorders:
@@ -33,7 +44,7 @@ def bigendian_to_native(value):
3344
else:
3445
return string_reverse(value)
3546

36-
class StructTest(unittest.TestCase):
47+
class StructTest(ComplexesAreIdenticalMixin, unittest.TestCase):
3748
def test_isbigendian(self):
3849
self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN)
3950

@@ -783,6 +794,30 @@ def test_repr(self):
783794
s = struct.Struct('=i2H')
784795
self.assertEqual(repr(s), f'Struct({s.format!r})')
785796

797+
@unittest.skipUnless(have_c_complex, "requires C11 complex type support")
798+
def test_c_complex_round_trip(self):
799+
values = [complex(*_) for _ in combinations([1, -1, 0.0, -0.0, 2,
800+
-3, INF, -INF, NAN], 2)]
801+
for z in values:
802+
for f in ['E', 'C', '>E', '>C', '<E', '<C']:
803+
with self.subTest(z=z, format=f):
804+
round_trip = struct.unpack(f, struct.pack(f, z))[0]
805+
self.assertComplexesAreIdentical(z, round_trip)
806+
807+
@unittest.skipIf(have_c_complex, "requires no C11 complex type support")
808+
def test_c_complex_error(self):
809+
msg1 = "'E' format not supported on this system"
810+
msg2 = "'C' format not supported on this system"
811+
with self.assertRaisesRegex(struct.error, msg1):
812+
struct.pack('E', 1j)
813+
with self.assertRaisesRegex(struct.error, msg1):
814+
struct.unpack('E', b'1')
815+
with self.assertRaisesRegex(struct.error, msg2):
816+
struct.pack('C', 1j)
817+
with self.assertRaisesRegex(struct.error, msg2):
818+
struct.unpack('C', b'1')
819+
820+
786821
class UnpackIteratorTest(unittest.TestCase):
787822
"""
788823
Tests for iterative unpacking (struct.Struct.iter_unpack).
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Support the :c:expr:`float complex` and :c:expr:`double complex`
2+
C types in the :mod:`struct` module if the compiler has C11 complex
3+
arithmetic. Patch by Sergey B Kirpichev.

0 commit comments

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