diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2024-01-17 19:58:28 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-17 19:58:28 (GMT) |
commit | 2b032590222fd633e9d696faae7cb04dae5170bd (patch) | |
tree | 67b9acb570fea8cc71dc966ec4420a0316c8413f | |
parent | 5dcb15da881173bf2b1e4d4336752a4fd1da4f2a (diff) | |
download | cpython-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.py | 4 | ||||
-rw-r--r-- | Lib/ctypes/test/test_byteswap.py | 19 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst | 2 |
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. |