Skip to content

Commit 06a0a9b

Browse files
diegorussomgorny
authored andcommitted
[3.11] pythongh-110190: Fix ctypes structs with array on PPCLE64 (pythonGH-112959) (python#113167)
Fix the same issue of PR python#112604 on PPC64LE platform Refactor tests to make easier to add more platfroms if needed. (cherry picked from commit 6644ca4) Change-Id: I1ada30808c0d593a43eca3fa7a628c26bc276310 Signed-off-by: Michał Górny <[email protected]>
1 parent 1800d7b commit 06a0a9b

File tree

3 files changed

+208
-207
lines changed

3 files changed

+208
-207
lines changed

Lib/ctypes/test/test_structures.py

Lines changed: 84 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ctypes.util import find_library
1313
from struct import calcsize
1414
import _ctypes_test
15+
from collections import namedtuple
1516
from test import support
1617

1718
# The following definition is meant to be used from time to time to assist
@@ -554,36 +555,53 @@ class Vector(Mid):
554555
def test_array_in_struct(self):
555556
# See bpo-22273
556557

558+
# Load the shared library
559+
dll = CDLL(_ctypes_test.__file__)
560+
557561
# These should mirror the structures in Modules/_ctypes/_ctypes_test.c
558562
class Test2(Structure):
559563
_fields_ = [
560564
('data', c_ubyte * 16),
561565
]
562566

563-
class Test3(Structure):
567+
class Test3AParent(Structure):
568+
_fields_ = [
569+
('data', c_float * 2),
570+
]
571+
572+
class Test3A(Test3AParent):
573+
_fields_ = [
574+
('more_data', c_float * 2),
575+
]
576+
577+
class Test3B(Structure):
564578
_fields_ = [
565579
('data', c_double * 2),
566580
]
567581

568-
class Test3A(Structure):
582+
class Test3C(Structure):
569583
_fields_ = [
570-
('data', c_float * 2),
584+
("data", c_double * 4)
571585
]
572586

573-
class Test3B(Test3A):
587+
class Test3D(Structure):
574588
_fields_ = [
575-
('more_data', c_float * 2),
589+
("data", c_double * 8)
590+
]
591+
592+
class Test3E(Structure):
593+
_fields_ = [
594+
("data", c_double * 9)
576595
]
577596

578-
# Load the shared library
579-
dll = CDLL(_ctypes_test.__file__)
580597

598+
# Tests for struct Test2
581599
s = Test2()
582600
expected = 0
583601
for i in range(16):
584602
s.data[i] = i
585603
expected += i
586-
func = dll._testfunc_array_in_struct1
604+
func = dll._testfunc_array_in_struct2
587605
func.restype = c_int
588606
func.argtypes = (Test2,)
589607
result = func(s)
@@ -592,29 +610,16 @@ class Test3B(Test3A):
592610
for i in range(16):
593611
self.assertEqual(s.data[i], i)
594612

595-
s = Test3()
596-
s.data[0] = 3.14159
597-
s.data[1] = 2.71828
598-
expected = 3.14159 + 2.71828
599-
func = dll._testfunc_array_in_struct2
600-
func.restype = c_double
601-
func.argtypes = (Test3,)
602-
result = func(s)
603-
self.assertEqual(result, expected)
604-
# check the passed-in struct hasn't changed
605-
self.assertEqual(s.data[0], 3.14159)
606-
self.assertEqual(s.data[1], 2.71828)
607-
608-
s = Test3B()
613+
# Tests for struct Test3A
614+
s = Test3A()
609615
s.data[0] = 3.14159
610616
s.data[1] = 2.71828
611617
s.more_data[0] = -3.0
612618
s.more_data[1] = -2.0
613-
614-
expected = 3.14159 + 2.71828 - 5.0
615-
func = dll._testfunc_array_in_struct2a
619+
expected = 3.14159 + 2.71828 - 3.0 - 2.0
620+
func = dll._testfunc_array_in_struct3A
616621
func.restype = c_double
617-
func.argtypes = (Test3B,)
622+
func.argtypes = (Test3A,)
618623
result = func(s)
619624
self.assertAlmostEqual(result, expected, places=6)
620625
# check the passed-in struct hasn't changed
@@ -623,129 +628,60 @@ class Test3B(Test3A):
623628
self.assertAlmostEqual(s.more_data[0], -3.0, places=6)
624629
self.assertAlmostEqual(s.more_data[1], -2.0, places=6)
625630

626-
@unittest.skipIf(
627-
'ppc64le' in platform.uname().machine,
628-
"gh-110190: currently fails on ppc64le",
629-
)
630-
def test_array_in_struct_registers(self):
631-
dll = CDLL(_ctypes_test.__file__)
632-
633-
class Test3C1(Structure):
634-
_fields_ = [
635-
("data", c_double * 4)
636-
]
637-
638-
class DataType4(Array):
639-
_type_ = c_double
640-
_length_ = 4
641-
642-
class Test3C2(Structure):
643-
_fields_ = [
644-
("data", DataType4)
645-
]
646-
647-
class Test3C3(Structure):
648-
_fields_ = [
649-
("x", c_double),
650-
("y", c_double),
651-
("z", c_double),
652-
("t", c_double)
653-
]
654-
655-
class Test3D1(Structure):
656-
_fields_ = [
657-
("data", c_double * 5)
658-
]
659-
660-
class DataType5(Array):
661-
_type_ = c_double
662-
_length_ = 5
663-
664-
class Test3D2(Structure):
665-
_fields_ = [
666-
("data", DataType5)
667-
]
668-
669-
class Test3D3(Structure):
670-
_fields_ = [
671-
("x", c_double),
672-
("y", c_double),
673-
("z", c_double),
674-
("t", c_double),
675-
("u", c_double)
676-
]
677-
678-
# Tests for struct Test3C
679-
expected = (1.0, 2.0, 3.0, 4.0)
680-
func = dll._testfunc_array_in_struct_set_defaults_3C
681-
func.restype = Test3C1
682-
result = func()
683-
# check the default values have been set properly
684-
self.assertEqual(
685-
(result.data[0],
686-
result.data[1],
687-
result.data[2],
688-
result.data[3]),
689-
expected
631+
# Test3B, Test3C, Test3D, Test3E have the same logic with different
632+
# sizes hence putting them in a loop.
633+
StructCtype = namedtuple(
634+
"StructCtype",
635+
["cls", "cfunc1", "cfunc2", "items"]
690636
)
691-
692-
func = dll._testfunc_array_in_struct_set_defaults_3C
693-
func.restype = Test3C2
694-
result = func()
695-
# check the default values have been set properly
696-
self.assertEqual(
697-
(result.data[0],
698-
result.data[1],
699-
result.data[2],
700-
result.data[3]),
701-
expected
702-
)
703-
704-
func = dll._testfunc_array_in_struct_set_defaults_3C
705-
func.restype = Test3C3
706-
result = func()
707-
# check the default values have been set properly
708-
self.assertEqual((result.x, result.y, result.z, result.t), expected)
709-
710-
# Tests for struct Test3D
711-
expected = (1.0, 2.0, 3.0, 4.0, 5.0)
712-
func = dll._testfunc_array_in_struct_set_defaults_3D
713-
func.restype = Test3D1
714-
result = func()
715-
# check the default values have been set properly
716-
self.assertEqual(
717-
(result.data[0],
718-
result.data[1],
719-
result.data[2],
720-
result.data[3],
721-
result.data[4]),
722-
expected
723-
)
724-
725-
func = dll._testfunc_array_in_struct_set_defaults_3D
726-
func.restype = Test3D2
727-
result = func()
728-
# check the default values have been set properly
729-
self.assertEqual(
730-
(result.data[0],
731-
result.data[1],
732-
result.data[2],
733-
result.data[3],
734-
result.data[4]),
735-
expected
736-
)
737-
738-
func = dll._testfunc_array_in_struct_set_defaults_3D
739-
func.restype = Test3D3
740-
result = func()
741-
# check the default values have been set properly
742-
self.assertEqual(
743-
(result.x,
744-
result.y,
745-
result.z,
746-
result.t,
747-
result.u),
748-
expected)
637+
structs_to_test = [
638+
StructCtype(
639+
Test3B,
640+
dll._testfunc_array_in_struct3B,
641+
dll._testfunc_array_in_struct3B_set_defaults,
642+
2),
643+
StructCtype(
644+
Test3C,
645+
dll._testfunc_array_in_struct3C,
646+
dll._testfunc_array_in_struct3C_set_defaults,
647+
4),
648+
StructCtype(
649+
Test3D,
650+
dll._testfunc_array_in_struct3D,
651+
dll._testfunc_array_in_struct3D_set_defaults,
652+
8),
653+
StructCtype(
654+
Test3E,
655+
dll._testfunc_array_in_struct3E,
656+
dll._testfunc_array_in_struct3E_set_defaults,
657+
9),
658+
]
659+
660+
for sut in structs_to_test:
661+
s = sut.cls()
662+
663+
# Test for cfunc1
664+
expected = 0
665+
for i in range(sut.items):
666+
float_i = float(i)
667+
s.data[i] = float_i
668+
expected += float_i
669+
func = sut.cfunc1
670+
func.restype = c_double
671+
func.argtypes = (sut.cls,)
672+
result = func(s)
673+
self.assertEqual(result, expected)
674+
# check the passed-in struct hasn't changed
675+
for i in range(sut.items):
676+
self.assertEqual(s.data[i], float(i))
677+
678+
# Test for cfunc2
679+
func = sut.cfunc2
680+
func.restype = sut.cls
681+
result = func()
682+
# check if the default values have been set correctly
683+
for i in range(sut.items):
684+
self.assertEqual(result.data[i], float(i+1))
749685

750686
def test_38368(self):
751687
class U(Union):

0 commit comments

Comments
 (0)