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

gh-121249: Support _Complex types in the struct module #121613

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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
gh-121249: Support _Complex types in the struct module
  • Loading branch information
skirpichev committed Jul 11, 2024
commit c60f4a404b43e835f85c8ed7e51f63f1d9f36bf5
19 changes: 19 additions & 0 deletions 19 Doc/library/struct.rst
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,26 @@ platform-dependent.
| ``P`` | :c:expr:`void \*` | integer | | \(5) |
+--------+--------------------------+--------------------+----------------+------------+

Additionally, if IEC 60559 compatible complex arithmetic (Annex G) is
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
supported, the following format characters are available:
skirpichev marked this conversation as resolved.
Show resolved Hide resolved

+--------+--------------------------+--------------------+----------------+------------+
| Format | C Type | Python type | Standard size | Notes |
+========+==========================+====================+================+============+
| ``E`` | :c:expr:`float complex` | complex | 8 | \(10) |
+--------+--------------------------+--------------------+----------------+------------+
| ``C`` | :c:expr:`double complex` | complex | 16 | \(10) |
+--------+--------------------------+--------------------+----------------+------------+

.. versionchanged:: 3.3
Added support for the ``'n'`` and ``'N'`` formats.

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

.. versionchanged:: 3.14
Added support for ``'E'`` and ``'C'`` formats.
skirpichev marked this conversation as resolved.
Show resolved Hide resolved


Notes:

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

(10)
For the ``'E'`` and ``'C'`` conversion codes, the packed representation uses
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
the IEEE 754 binary32 and binary64 format for components of the complex
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
number, regardless of the floating-point format used by the platform.

A format character may be preceded by an integral repeat count. For example,
the format string ``'4h'`` means exactly the same as ``'hhhh'``.

Expand Down
2 changes: 2 additions & 0 deletions 2 Lib/ctypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ class c_longdouble(_SimpleCData):
try:
class c_double_complex(_SimpleCData):
_type_ = "C"
_check_size(c_double_complex)
class c_float_complex(_SimpleCData):
_type_ = "E"
_check_size(c_float_complex)
class c_longdouble_complex(_SimpleCData):
_type_ = "F"
except AttributeError:
Expand Down
49 changes: 49 additions & 0 deletions 49 Lib/test/test_struct.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import abc
from itertools import combinations
import array
import gc
import math
Expand All @@ -17,6 +18,15 @@
integer_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'n', 'N'
byteorders = '', '@', '=', '<', '>', '!'

INF = float('inf')
NAN = float('nan')

try:
struct.pack('C', 1j)
have_c_complex = True
except struct.error:
have_c_complex = False

def iter_integer_formats(byteorders=byteorders):
for code in integer_codes:
for byteorder in byteorders:
Expand All @@ -34,6 +44,34 @@ def bigendian_to_native(value):
return string_reverse(value)

class StructTest(unittest.TestCase):
# from Lib/test/test_complex.py
def assertFloatsAreIdentical(self, x, y):
"""assert that floats x and y are identical, in the sense that:
(1) both x and y are nans, or
(2) both x and y are infinities, with the same sign, or
(3) both x and y are zeros, with the same sign, or
(4) x and y are both finite and nonzero, and x == y

"""
msg = 'floats {!r} and {!r} are not identical'

if math.isnan(x) or math.isnan(y):
if math.isnan(x) and math.isnan(y):
return
elif x == y:
if x != 0.0:
return
# both zero; check that signs match
elif math.copysign(1.0, x) == math.copysign(1.0, y):
return
else:
msg += ': zeros have different signs'
self.fail(msg.format(x, y))

def assertComplexesAreIdentical(self, x, y):
self.assertFloatsAreIdentical(x.real, y.real)
self.assertFloatsAreIdentical(x.imag, y.imag)
skirpichev marked this conversation as resolved.
Show resolved Hide resolved

def test_isbigendian(self):
self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN)

Expand Down Expand Up @@ -774,6 +812,17 @@ def test_repr(self):
s = struct.Struct('=i2H')
self.assertEqual(repr(s), f'Struct({s.format!r})')

@unittest.skipUnless(have_c_complex, "requires C11 complex type")
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
def test_c_complex_round_trip(self):
values = [complex(*_) for _ in combinations([1, -1, 0.0, -0.0, 2,
-3, INF, -INF, NAN], 2)]
for z in values:
for f in ['E', 'C', '>E', '>C', '<E', '<C']:
with self.subTest(z=z, format=f):
round_trip = struct.unpack(f, struct.pack(f, z))[0]
self.assertComplexesAreIdentical(z, round_trip)


class UnpackIteratorTest(unittest.TestCase):
"""
Tests for iterative unpacking (struct.Struct.iter_unpack).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Support :c:expr:`float complex` and :c:expr:`double complex`
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
C types in the :mod:`struct` if compiler has C11 complex
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
arithmetic. Patch by Sergey B Kirpichev.
Loading
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.