https://github.com/python/cpython/commit/2b032590222fd633e9d696faae7cb04dae5170bd
commit: 2b032590222fd633e9d696faae7cb04dae5170bd
branch: 3.11
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-01-17T19:58:28Z
summary:

[3.11] gh-105102: Fix nested unions in structures when the system byteorder is 
the opposite (GH-105106) (GH-114205)

(cherry picked from commit 0b541f64c472976b2fee1ec9919bc7b02a798242)

Co-authored-by: Sheidan <[email protected]>

files:
A Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
M Lib/ctypes/_endian.py
M Lib/ctypes/test/test_byteswap.py

diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
index 34dee64b1a65a6..6f674b21371c40 100644
--- a/Lib/ctypes/_endian.py
+++ b/Lib/ctypes/_endian.py
@@ -15,8 +15,8 @@ def _other_endian(typ):
     # if typ is array
     if isinstance(typ, _array_type):
         return _other_endian(typ._type_) * typ._length_
-    # if typ is structure
-    if issubclass(typ, Structure):
+    # if typ is structure or union
+    if issubclass(typ, (Structure, Union)):
         return typ
     raise TypeError("This type does not support other endian: %s" % typ)
 
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
index caefb774cc5375..44d32ff27ba923 100644
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -352,5 +352,24 @@ class TestUnion(parent):
                 self.assertEqual(s.point.x, 1)
                 self.assertEqual(s.point.y, 2)
 
+    def test_build_struct_union_opposite_system_byteorder(self):
+        # gh-105102
+        if sys.byteorder == "little":
+            _Structure = BigEndianStructure
+            _Union = BigEndianUnion
+        else:
+            _Structure = LittleEndianStructure
+            _Union = LittleEndianUnion
+
+        class S1(_Structure):
+            _fields_ = [("a", c_byte), ("b", c_byte)]
+
+        class U1(_Union):
+            _fields_ = [("s1", S1), ("ab", c_short)]
+
+        class S2(_Structure):
+            _fields_ = [("u1", U1), ("c", c_byte)]
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst 
b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
new file mode 100644
index 00000000000000..7ca21afefa3132
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
@@ -0,0 +1,2 @@
+Allow :class:`ctypes.Union` to be nested in :class:`ctypes.Structure` when
+the system endianness is the opposite of the classes.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to