1212from ctypes .util import find_library
1313from struct import calcsize
1414import _ctypes_test
15+ from collections import namedtuple
1516from 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