summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-01-17 19:58:28 (GMT)
committerGitHub <noreply@github.com>2024-01-17 19:58:28 (GMT)
commit2b032590222fd633e9d696faae7cb04dae5170bd (patch)
tree67b9acb570fea8cc71dc966ec4420a0316c8413f
parent5dcb15da881173bf2b1e4d4336752a4fd1da4f2a (diff)
downloadcpython-2b032590222fd633e9d696faae7cb04dae5170bd.zip
cpython-2b032590222fd633e9d696faae7cb04dae5170bd.tar.gz
cpython-2b032590222fd633e9d696faae7cb04dae5170bd.tar.bz2
[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 <37596668+Sh3idan@users.noreply.github.com>
-rw-r--r--Lib/ctypes/_endian.py4
-rw-r--r--Lib/ctypes/test/test_byteswap.py19
-rw-r--r--Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst2
3 files changed, 23 insertions, 2 deletions
diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
index 34dee64..6f674b2 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 caefb77..44d32ff 100644
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -352,5 +352,24 @@ class Test(unittest.TestCase):
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 0000000..7ca21af
--- /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.