mirror of https://github.com/python/cpython
Close #4376: ctypes now supports nested structures in a endian different than
the parent structure. Patch by Vlad Riscutia.
This commit is contained in:
parent
cb4ae815b5
commit
6636121950
|
@ -7,14 +7,18 @@ def _other_endian(typ):
|
||||||
"""Return the type with the 'other' byte order. Simple types like
|
"""Return the type with the 'other' byte order. Simple types like
|
||||||
c_int and so on already have __ctype_be__ and __ctype_le__
|
c_int and so on already have __ctype_be__ and __ctype_le__
|
||||||
attributes which contain the types, for more complicated types
|
attributes which contain the types, for more complicated types
|
||||||
only arrays are supported.
|
arrays and structures are supported.
|
||||||
"""
|
"""
|
||||||
try:
|
# check _OTHER_ENDIAN attribute (present if typ is primitive type)
|
||||||
|
if hasattr(typ, _OTHER_ENDIAN):
|
||||||
return getattr(typ, _OTHER_ENDIAN)
|
return getattr(typ, _OTHER_ENDIAN)
|
||||||
except AttributeError:
|
# if typ is array
|
||||||
if type(typ) == _array_type:
|
if isinstance(typ, _array_type):
|
||||||
return _other_endian(typ._type_) * typ._length_
|
return _other_endian(typ._type_) * typ._length_
|
||||||
raise TypeError("This type does not support other endian: %s" % typ)
|
# if typ is structure
|
||||||
|
if issubclass(typ, Structure):
|
||||||
|
return typ
|
||||||
|
raise TypeError("This type does not support other endian: %s" % typ)
|
||||||
|
|
||||||
class _swapped_meta(type(Structure)):
|
class _swapped_meta(type(Structure)):
|
||||||
def __setattr__(self, attrname, value):
|
def __setattr__(self, attrname, value):
|
||||||
|
|
|
@ -185,18 +185,32 @@ class Test(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
|
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
|
||||||
|
|
||||||
def test_struct_struct(self):
|
def test_struct_struct(self):
|
||||||
# Nested structures with different byte order not (yet) supported
|
# nested structures with different byteorders
|
||||||
if sys.byteorder == "little":
|
|
||||||
base = BigEndianStructure
|
|
||||||
else:
|
|
||||||
base = LittleEndianStructure
|
|
||||||
|
|
||||||
class T(Structure):
|
# create nested structures with given byteorders and set memory to data
|
||||||
_fields_ = [("a", c_int),
|
def set_structures(endianness, nested_endianness, data):
|
||||||
("b", c_int)]
|
class NestedStructure(nested_endianness):
|
||||||
class S(base):
|
_fields_ = [("x", c_uint32),
|
||||||
pass
|
("y", c_uint32)]
|
||||||
self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
|
|
||||||
|
class TestStructure(endianness):
|
||||||
|
_fields_ = [("point", NestedStructure)]
|
||||||
|
|
||||||
|
self.assertEqual(len(data), sizeof(TestStructure))
|
||||||
|
return cast(data, POINTER(TestStructure))[0]
|
||||||
|
|
||||||
|
for nested, data in (
|
||||||
|
(BigEndianStructure, b'\0\0\0\1\0\0\0\2'),
|
||||||
|
(LittleEndianStructure, b'\1\0\0\0\2\0\0\0'),
|
||||||
|
):
|
||||||
|
for parent in (
|
||||||
|
BigEndianStructure,
|
||||||
|
LittleEndianStructure,
|
||||||
|
Structure,
|
||||||
|
):
|
||||||
|
s = set_structures(parent, nested, data)
|
||||||
|
self.assertEqual(s.point.x, 1)
|
||||||
|
self.assertEqual(s.point.y, 2)
|
||||||
|
|
||||||
def test_struct_fields_2(self):
|
def test_struct_fields_2(self):
|
||||||
# standard packing in struct uses no alignment.
|
# standard packing in struct uses no alignment.
|
||||||
|
|
|
@ -735,6 +735,7 @@ Jan Pieter Riegel
|
||||||
Armin Rigo
|
Armin Rigo
|
||||||
Nicholas Riley
|
Nicholas Riley
|
||||||
Jean-Claude Rimbault
|
Jean-Claude Rimbault
|
||||||
|
Vlad Riscutia
|
||||||
Juan M. Bello Rivas
|
Juan M. Bello Rivas
|
||||||
Davide Rizzo
|
Davide Rizzo
|
||||||
Anthony Roach
|
Anthony Roach
|
||||||
|
|
|
@ -27,6 +27,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #4376: ctypes now supports nested structures in a endian different than
|
||||||
|
the parent structure. Patch by Vlad Riscutia.
|
||||||
|
|
||||||
- Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a
|
- Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a
|
||||||
TextIOWrapper to a huge value, not TypeError.
|
TextIOWrapper to a huge value, not TypeError.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue