[Python-checkins] cpython (2.7): Close #4376: ctypes now supports nested structures in a endian different than

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


http://hg.python.org/cpython/rev/a9d0fab19d5e
changeset: 71313:a9d0fab19d5e
branch: 2.7
parent: 71306:488c6b481652
user: Victor Stinner <victor.stinner at haypocalc.com>
date: Wed Jul 13 21:47:31 2011 +0200
summary:
 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
@@ -10,14 +10,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
@@ -685,6 +685,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
@@ -30,6 +30,9 @@
 Library
 -------
 
+- Issue #4376: ctypes now supports nested structures in a endian different than
+ the parent structure. Patch by Vlad Riscutia.
+
 - Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors
 if the process has only one pipe.
 
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

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