cpython: 72e73fa03124 (original) (raw)
Mercurial > cpython
changeset 71311:72e73fa03124 3.2
Close #4376: ctypes now supports nested structures in a endian different than the parent structure. Patch by Vlad Riscutia. [#4376]
Victor Stinner victor.stinner@haypocalc.com | |
---|---|
date | Wed, 13 Jul 2011 21:43:18 +0200 |
parents | 2b97f5220940 |
children | 637210b9d054 d050c8c9a3b3 |
files | Lib/ctypes/_endian.py Lib/ctypes/test/test_byteswap.py Misc/ACKS Misc/NEWS |
diffstat | 4 files changed, 39 insertions(+), 17 deletions(-)[+] [-] Lib/ctypes/_endian.py 16 Lib/ctypes/test/test_byteswap.py 36 Misc/ACKS 1 Misc/NEWS 3 |
line wrap: on
line diff
--- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -7,14 +7,18 @@ def _other_endian(typ): """Return the type with the 'other' byte order. Simple types like c_int and so on already have ctype_be and ctype_le attributes which contain the types, for more complicated types
check _OTHER_ENDIAN attribute (present if typ is primitive type)
- if hasattr(typ, _OTHER_ENDIAN): return getattr(typ, _OTHER_ENDIAN)
- except AttributeError:
if type(typ) == _array_type:[](#l1.15)
return _other_endian(typ._type_) * typ._length_[](#l1.16)
raise TypeError("This type does not support other endian: %s" % typ)[](#l1.17)
if typ is array
- if isinstance(typ, _array_type):
return _other_endian(typ._type_) * typ._length_[](#l1.20)
if typ is structure
- if issubclass(typ, Structure):
return typ[](#l1.23)
- raise TypeError("This type does not support other endian: %s" % typ)
class _swapped_meta(type(Structure)): def setattr(self, attrname, value):
--- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/ctypes/test/test_byteswap.py @@ -185,18 +185,32 @@ class Test(unittest.TestCase): self.assertRaises(TypeError, setattr, T, "fields", [("x", typ)]) def test_struct_struct(self):
# Nested structures with different byte order not (yet) supported[](#l2.7)
if sys.byteorder == "little":[](#l2.8)
base = BigEndianStructure[](#l2.9)
else:[](#l2.10)
base = LittleEndianStructure[](#l2.11)
# nested structures with different byteorders[](#l2.12)
# create nested structures with given byteorders and set memory to data[](#l2.14)
def set_structures(endianness, nested_endianness, data):[](#l2.15)
class NestedStructure(nested_endianness):[](#l2.16)
_fields_ = [("x", c_uint32),[](#l2.17)
("y", c_uint32)][](#l2.18)
class TestStructure(endianness):[](#l2.20)
_fields_ = [("point", NestedStructure)][](#l2.21)
class T(Structure):[](#l2.23)
_fields_ = [("a", c_int),[](#l2.24)
("b", c_int)][](#l2.25)
class S(base):[](#l2.26)
pass[](#l2.27)
self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])[](#l2.28)
self.assertEqual(len(data), sizeof(TestStructure))[](#l2.29)
return cast(data, POINTER(TestStructure))[0][](#l2.30)
for nested, data in ([](#l2.32)
(BigEndianStructure, b'\0\0\0\1\0\0\0\2'),[](#l2.33)
(LittleEndianStructure, b'\1\0\0\0\2\0\0\0'),[](#l2.34)
):[](#l2.35)
for parent in ([](#l2.36)
BigEndianStructure,[](#l2.37)
LittleEndianStructure,[](#l2.38)
Structure,[](#l2.39)
):[](#l2.40)
s = set_structures(parent, nested, data)[](#l2.41)
self.assertEqual(s.point.x, 1)[](#l2.42)
self.assertEqual(s.point.y, 2)[](#l2.43)
def test_struct_fields_2(self): # standard packing in struct uses no alignment.
--- a/Misc/ACKS +++ b/Misc/ACKS @@ -735,6 +735,7 @@ Jan Pieter Riegel Armin Rigo Nicholas Riley Jean-Claude Rimbault +Vlad Riscutia Juan M. Bello Rivas Davide Rizzo Anthony Roach
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -27,6 +27,9 @@ Core and Builtins Library ------- +- Issue #4376: ctypes now supports nested structures in a endian different than