summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ctypes/test/test_structures.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index cdf4a91..ab23206 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -576,6 +576,86 @@ class StructureTestCase(unittest.TestCase):
self.assertEqual(f2, [0x4567, 0x0123, 0xcdef, 0x89ab,
0x3210, 0x7654, 0xba98, 0xfedc])
+ def test_union_by_value(self):
+ # See bpo-16575
+
+ # These should mirror the structures in Modules/_ctypes/_ctypes_test.c
+
+ class Nested1(Structure):
+ _fields_ = [
+ ('an_int', c_int),
+ ('another_int', c_int),
+ ]
+
+ class Test4(Union):
+ _fields_ = [
+ ('a_long', c_long),
+ ('a_struct', Nested1),
+ ]
+
+ class Nested2(Structure):
+ _fields_ = [
+ ('an_int', c_int),
+ ('a_union', Test4),
+ ]
+
+ class Test5(Structure):
+ _fields_ = [
+ ('an_int', c_int),
+ ('nested', Nested2),
+ ('another_int', c_int),
+ ]
+
+ test4 = Test4()
+ dll = CDLL(_ctypes_test.__file__)
+ with self.assertRaises(TypeError) as ctx:
+ func = dll._testfunc_union_by_value1
+ func.restype = c_long
+ func.argtypes = (Test4,)
+ result = func(test4)
+ self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes '
+ 'a union by value, which is unsupported.')
+ test5 = Test5()
+ with self.assertRaises(TypeError) as ctx:
+ func = dll._testfunc_union_by_value2
+ func.restype = c_long
+ func.argtypes = (Test5,)
+ result = func(test5)
+ self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes '
+ 'a union by value, which is unsupported.')
+
+ # passing by reference should be OK
+ test4.a_long = 12345;
+ func = dll._testfunc_union_by_reference1
+ func.restype = c_long
+ func.argtypes = (POINTER(Test4),)
+ result = func(byref(test4))
+ self.assertEqual(result, 12345)
+ self.assertEqual(test4.a_long, 0)
+ self.assertEqual(test4.a_struct.an_int, 0)
+ self.assertEqual(test4.a_struct.another_int, 0)
+ test4.a_struct.an_int = 0x12340000
+ test4.a_struct.another_int = 0x5678
+ func = dll._testfunc_union_by_reference2
+ func.restype = c_long
+ func.argtypes = (POINTER(Test4),)
+ result = func(byref(test4))
+ self.assertEqual(result, 0x12345678)
+ self.assertEqual(test4.a_long, 0)
+ self.assertEqual(test4.a_struct.an_int, 0)
+ self.assertEqual(test4.a_struct.another_int, 0)
+ test5.an_int = 0x12000000
+ test5.nested.an_int = 0x345600
+ test5.another_int = 0x78
+ func = dll._testfunc_union_by_reference3
+ func.restype = c_long
+ func.argtypes = (POINTER(Test5),)
+ result = func(byref(test5))
+ self.assertEqual(result, 0x12345678)
+ self.assertEqual(test5.an_int, 0)
+ self.assertEqual(test5.nested.an_int, 0)
+ self.assertEqual(test5.another_int, 0)
+
class PointerMemberTestCase(unittest.TestCase):
def test(self):