Skip to content

Commit 0b541f6

Browse files
authored
gh-105102: Fix nested unions in structures when the system byteorder is the opposite (GH-105106)
1 parent 33b47a2 commit 0b541f6

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

Lib/ctypes/_endian.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def _other_endian(typ):
1515
# if typ is array
1616
if isinstance(typ, _array_type):
1717
return _other_endian(typ._type_) * typ._length_
18-
# if typ is structure
19-
if issubclass(typ, Structure):
18+
# if typ is structure or union
19+
if issubclass(typ, (Structure, Union)):
2020
return typ
2121
raise TypeError("This type does not support other endian: %s" % typ)
2222

Lib/test/test_ctypes/test_byteswap.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,24 @@ class TestUnion(parent):
363363
self.assertEqual(s.point.x, 1)
364364
self.assertEqual(s.point.y, 2)
365365

366+
def test_build_struct_union_opposite_system_byteorder(self):
367+
# gh-105102
368+
if sys.byteorder == "little":
369+
_Structure = BigEndianStructure
370+
_Union = BigEndianUnion
371+
else:
372+
_Structure = LittleEndianStructure
373+
_Union = LittleEndianUnion
374+
375+
class S1(_Structure):
376+
_fields_ = [("a", c_byte), ("b", c_byte)]
377+
378+
class U1(_Union):
379+
_fields_ = [("s1", S1), ("ab", c_short)]
380+
381+
class S2(_Structure):
382+
_fields_ = [("u1", U1), ("c", c_byte)]
383+
366384

367385
if __name__ == "__main__":
368386
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Allow :class:`ctypes.Union` to be nested in :class:`ctypes.Structure` when
2+
the system endianness is the opposite of the classes.

0 commit comments

Comments
 (0)