Skip to content

Commit 2b03259

Browse files
[3.11] gh-105102: Fix nested unions in structures when the system byteorder is the opposite (GH-105106) (GH-114205)
(cherry picked from commit 0b541f6) Co-authored-by: Sheidan <[email protected]>
1 parent 5dcb15d commit 2b03259

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-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/ctypes/test/test_byteswap.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,5 +352,24 @@ class TestUnion(parent):
352352
self.assertEqual(s.point.x, 1)
353353
self.assertEqual(s.point.y, 2)
354354

355+
def test_build_struct_union_opposite_system_byteorder(self):
356+
# gh-105102
357+
if sys.byteorder == "little":
358+
_Structure = BigEndianStructure
359+
_Union = BigEndianUnion
360+
else:
361+
_Structure = LittleEndianStructure
362+
_Union = LittleEndianUnion
363+
364+
class S1(_Structure):
365+
_fields_ = [("a", c_byte), ("b", c_byte)]
366+
367+
class U1(_Union):
368+
_fields_ = [("s1", S1), ("ab", c_short)]
369+
370+
class S2(_Structure):
371+
_fields_ = [("u1", U1), ("c", c_byte)]
372+
373+
355374
if __name__ == "__main__":
356375
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)