[Python-checkins] cpython (merge 3.2 -> default): (merge 3.2) Close #4376: ctypes now supports nested structures in a endian

victor.stinner python-checkins at python.org
Wed Jul 13 21:48:27 CEST 2011


http://hg.python.org/cpython/rev/637210b9d054
changeset: 71312:637210b9d054
parent: 71310:9648b63af5fa
parent: 71311:72e73fa03124
user: Victor Stinner <victor.stinner at haypocalc.com>
date: Wed Jul 13 21:45:16 2011 +0200
summary:
 (merge 3.2) Close #4376: ctypes now supports nested structures in a endian
different than the parent structure. Patch by Vlad Riscutia.
files:
 Lib/ctypes/_endian.py | 16 +++++---
 Lib/ctypes/test/test_byteswap.py | 36 +++++++++++++------
 Misc/ACKS | 1 +
 Misc/NEWS | 3 +
 4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
--- a/Lib/ctypes/_endian.py
+++ b/Lib/ctypes/_endian.py
@@ -7,14 +7,18 @@
 """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
- 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)
- except AttributeError:
- if type(typ) == _array_type:
- return _other_endian(typ._type_) * typ._length_
- raise TypeError("This type does not support other endian: %s" % 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):
+ return typ
+ raise TypeError("This type does not support other endian: %s" % typ)
 
 class _swapped_meta(type(Structure)):
 def __setattr__(self, attrname, value):
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -185,18 +185,32 @@
 self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
 
 def test_struct_struct(self):
- # Nested structures with different byte order not (yet) supported
- if sys.byteorder == "little":
- base = BigEndianStructure
- else:
- base = LittleEndianStructure
+ # nested structures with different byteorders
 
- class T(Structure):
- _fields_ = [("a", c_int),
- ("b", c_int)]
- class S(base):
- pass
- self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
+ # create nested structures with given byteorders and set memory to data
+ def set_structures(endianness, nested_endianness, data):
+ class NestedStructure(nested_endianness):
+ _fields_ = [("x", c_uint32),
+ ("y", c_uint32)]
+
+ 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):
 # standard packing in struct uses no alignment.
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -784,6 +784,7 @@
 Armin Rigo
 Nicholas Riley
 Jean-Claude Rimbault
+Vlad Riscutia
 Juan M. Bello Rivas
 Davide Rizzo
 Anthony Roach
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -225,6 +225,9 @@
 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
 TextIOWrapper to a huge value, not TypeError.
 
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /