99 c_long , c_ulong , c_longlong , c_ulonglong , c_float , c_double )
1010from struct import calcsize
1111import _ctypes_test
12+ from collections import namedtuple
1213from test import support
1314
1415# The following definition is meant to be used from time to time to assist
@@ -482,36 +483,53 @@ class X(Structure):
482483 def test_array_in_struct (self ):
483484 # See bpo-22273
484485
486+ # Load the shared library
487+ dll = CDLL (_ctypes_test .__file__ )
488+
485489 # These should mirror the structures in Modules/_ctypes/_ctypes_test.c
486490 class Test2 (Structure ):
487491 _fields_ = [
488492 ('data' , c_ubyte * 16 ),
489493 ]
490494
491- class Test3 (Structure ):
495+ class Test3AParent (Structure ):
496+ _fields_ = [
497+ ('data' , c_float * 2 ),
498+ ]
499+
500+ class Test3A (Test3AParent ):
501+ _fields_ = [
502+ ('more_data' , c_float * 2 ),
503+ ]
504+
505+ class Test3B (Structure ):
492506 _fields_ = [
493507 ('data' , c_double * 2 ),
494508 ]
495509
496- class Test3A (Structure ):
510+ class Test3C (Structure ):
497511 _fields_ = [
498- (' data' , c_float * 2 ),
512+ (" data" , c_double * 4 )
499513 ]
500514
501- class Test3B ( Test3A ):
515+ class Test3D ( Structure ):
502516 _fields_ = [
503- ('more_data' , c_float * 2 ),
517+ ("data" , c_double * 8 )
518+ ]
519+
520+ class Test3E (Structure ):
521+ _fields_ = [
522+ ("data" , c_double * 9 )
504523 ]
505524
506- # Load the shared library
507- dll = CDLL (_ctypes_test .__file__ )
508525
526+ # Tests for struct Test2
509527 s = Test2 ()
510528 expected = 0
511529 for i in range (16 ):
512530 s .data [i ] = i
513531 expected += i
514- func = dll ._testfunc_array_in_struct1
532+ func = dll ._testfunc_array_in_struct2
515533 func .restype = c_int
516534 func .argtypes = (Test2 ,)
517535 result = func (s )
@@ -520,29 +538,16 @@ class Test3B(Test3A):
520538 for i in range (16 ):
521539 self .assertEqual (s .data [i ], i )
522540
523- s = Test3 ()
524- s .data [0 ] = 3.14159
525- s .data [1 ] = 2.71828
526- expected = 3.14159 + 2.71828
527- func = dll ._testfunc_array_in_struct2
528- func .restype = c_double
529- func .argtypes = (Test3 ,)
530- result = func (s )
531- self .assertEqual (result , expected )
532- # check the passed-in struct hasn't changed
533- self .assertEqual (s .data [0 ], 3.14159 )
534- self .assertEqual (s .data [1 ], 2.71828 )
535-
536- s = Test3B ()
541+ # Tests for struct Test3A
542+ s = Test3A ()
537543 s .data [0 ] = 3.14159
538544 s .data [1 ] = 2.71828
539545 s .more_data [0 ] = - 3.0
540546 s .more_data [1 ] = - 2.0
541-
542- expected = 3.14159 + 2.71828 - 5.0
543- func = dll ._testfunc_array_in_struct2a
547+ expected = 3.14159 + 2.71828 - 3.0 - 2.0
548+ func = dll ._testfunc_array_in_struct3A
544549 func .restype = c_double
545- func .argtypes = (Test3B ,)
550+ func .argtypes = (Test3A ,)
546551 result = func (s )
547552 self .assertAlmostEqual (result , expected , places = 6 )
548553 # check the passed-in struct hasn't changed
@@ -551,129 +556,60 @@ class Test3B(Test3A):
551556 self .assertAlmostEqual (s .more_data [0 ], - 3.0 , places = 6 )
552557 self .assertAlmostEqual (s .more_data [1 ], - 2.0 , places = 6 )
553558
554- @unittest .skipIf (
555- 'ppc64le' in platform .uname ().machine ,
556- "gh-110190: currently fails on ppc64le" ,
557- )
558- def test_array_in_struct_registers (self ):
559- dll = CDLL (_ctypes_test .__file__ )
560-
561- class Test3C1 (Structure ):
562- _fields_ = [
563- ("data" , c_double * 4 )
564- ]
565-
566- class DataType4 (Array ):
567- _type_ = c_double
568- _length_ = 4
569-
570- class Test3C2 (Structure ):
571- _fields_ = [
572- ("data" , DataType4 )
573- ]
574-
575- class Test3C3 (Structure ):
576- _fields_ = [
577- ("x" , c_double ),
578- ("y" , c_double ),
579- ("z" , c_double ),
580- ("t" , c_double )
581- ]
582-
583- class Test3D1 (Structure ):
584- _fields_ = [
585- ("data" , c_double * 5 )
586- ]
587-
588- class DataType5 (Array ):
589- _type_ = c_double
590- _length_ = 5
591-
592- class Test3D2 (Structure ):
593- _fields_ = [
594- ("data" , DataType5 )
595- ]
596-
597- class Test3D3 (Structure ):
598- _fields_ = [
599- ("x" , c_double ),
600- ("y" , c_double ),
601- ("z" , c_double ),
602- ("t" , c_double ),
603- ("u" , c_double )
604- ]
605-
606- # Tests for struct Test3C
607- expected = (1.0 , 2.0 , 3.0 , 4.0 )
608- func = dll ._testfunc_array_in_struct_set_defaults_3C
609- func .restype = Test3C1
610- result = func ()
611- # check the default values have been set properly
612- self .assertEqual (
613- (result .data [0 ],
614- result .data [1 ],
615- result .data [2 ],
616- result .data [3 ]),
617- expected
559+ # Test3B, Test3C, Test3D, Test3E have the same logic with different
560+ # sizes hence putting them in a loop.
561+ StructCtype = namedtuple (
562+ "StructCtype" ,
563+ ["cls" , "cfunc1" , "cfunc2" , "items" ]
618564 )
619-
620- func = dll ._testfunc_array_in_struct_set_defaults_3C
621- func .restype = Test3C2
622- result = func ()
623- # check the default values have been set properly
624- self .assertEqual (
625- (result .data [0 ],
626- result .data [1 ],
627- result .data [2 ],
628- result .data [3 ]),
629- expected
630- )
631-
632- func = dll ._testfunc_array_in_struct_set_defaults_3C
633- func .restype = Test3C3
634- result = func ()
635- # check the default values have been set properly
636- self .assertEqual ((result .x , result .y , result .z , result .t ), expected )
637-
638- # Tests for struct Test3D
639- expected = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 )
640- func = dll ._testfunc_array_in_struct_set_defaults_3D
641- func .restype = Test3D1
642- result = func ()
643- # check the default values have been set properly
644- self .assertEqual (
645- (result .data [0 ],
646- result .data [1 ],
647- result .data [2 ],
648- result .data [3 ],
649- result .data [4 ]),
650- expected
651- )
652-
653- func = dll ._testfunc_array_in_struct_set_defaults_3D
654- func .restype = Test3D2
655- result = func ()
656- # check the default values have been set properly
657- self .assertEqual (
658- (result .data [0 ],
659- result .data [1 ],
660- result .data [2 ],
661- result .data [3 ],
662- result .data [4 ]),
663- expected
664- )
665-
666- func = dll ._testfunc_array_in_struct_set_defaults_3D
667- func .restype = Test3D3
668- result = func ()
669- # check the default values have been set properly
670- self .assertEqual (
671- (result .x ,
672- result .y ,
673- result .z ,
674- result .t ,
675- result .u ),
676- expected )
565+ structs_to_test = [
566+ StructCtype (
567+ Test3B ,
568+ dll ._testfunc_array_in_struct3B ,
569+ dll ._testfunc_array_in_struct3B_set_defaults ,
570+ 2 ),
571+ StructCtype (
572+ Test3C ,
573+ dll ._testfunc_array_in_struct3C ,
574+ dll ._testfunc_array_in_struct3C_set_defaults ,
575+ 4 ),
576+ StructCtype (
577+ Test3D ,
578+ dll ._testfunc_array_in_struct3D ,
579+ dll ._testfunc_array_in_struct3D_set_defaults ,
580+ 8 ),
581+ StructCtype (
582+ Test3E ,
583+ dll ._testfunc_array_in_struct3E ,
584+ dll ._testfunc_array_in_struct3E_set_defaults ,
585+ 9 ),
586+ ]
587+
588+ for sut in structs_to_test :
589+ s = sut .cls ()
590+
591+ # Test for cfunc1
592+ expected = 0
593+ for i in range (sut .items ):
594+ float_i = float (i )
595+ s .data [i ] = float_i
596+ expected += float_i
597+ func = sut .cfunc1
598+ func .restype = c_double
599+ func .argtypes = (sut .cls ,)
600+ result = func (s )
601+ self .assertEqual (result , expected )
602+ # check the passed-in struct hasn't changed
603+ for i in range (sut .items ):
604+ self .assertEqual (s .data [i ], float (i ))
605+
606+ # Test for cfunc2
607+ func = sut .cfunc2
608+ func .restype = sut .cls
609+ result = func ()
610+ # check if the default values have been set correctly
611+ for i in range (sut .items ):
612+ self .assertEqual (result .data [i ], float (i + 1 ))
677613
678614 def test_38368 (self ):
679615 class U (Union ):
0 commit comments