@@ -299,7 +299,7 @@ def test_oldargs1_2_kw(self):
299
299
300
300
@cpython_only
301
301
class TestCallingConventions (unittest .TestCase ):
302
- """Test calling using the various C calling conventions (METH_*)
302
+ """Test calling using various C calling conventions (METH_*) from Python
303
303
304
304
Subclasses test several kinds of functions (module-level, methods,
305
305
class methods static methods) using these attributes:
@@ -503,14 +503,15 @@ def static_method():
503
503
504
504
PYTHON_INSTANCE = PythonClass ()
505
505
506
-
507
- IGNORE_RESULT = object ()
508
-
506
+ NULL_OR_EMPTY = object ()
509
507
510
508
@cpython_only
511
509
class FastCallTests (unittest .TestCase ):
510
+ """Test calling using various callables from C
511
+ """
512
+
512
513
# Test calls with positional arguments
513
- CALLS_POSARGS = (
514
+ CALLS_POSARGS = [
514
515
# (func, args: tuple, result)
515
516
516
517
# Python function with 2 arguments
@@ -529,31 +530,11 @@ class FastCallTests(unittest.TestCase):
529
530
(PYTHON_INSTANCE .class_method , (), "classmethod" ),
530
531
(PYTHON_INSTANCE .static_method , (), "staticmethod" ),
531
532
532
- # C function: METH_NOARGS
533
- (globals , (), IGNORE_RESULT ),
534
-
535
- # C function: METH_O
536
- (id , ("hello" ,), IGNORE_RESULT ),
537
-
538
- # C function: METH_VARARGS
539
- (dir , (1 ,), IGNORE_RESULT ),
540
-
541
- # C function: METH_VARARGS | METH_KEYWORDS
542
- (min , (5 , 9 ), 5 ),
543
-
544
- # C function: METH_FASTCALL
545
- (divmod , (1000 , 33 ), (30 , 10 )),
546
-
547
- # C type static method: METH_FASTCALL | METH_CLASS
548
- (int .from_bytes , (b'\x01 \x00 ' , 'little' ), 1 ),
549
-
550
- # bpo-30524: Test that calling a C type static method with no argument
551
- # doesn't crash (ignore the result): METH_FASTCALL | METH_CLASS
552
- (datetime .datetime .now , (), IGNORE_RESULT ),
553
- )
533
+ # C callables are added later
534
+ ]
554
535
555
536
# Test calls with positional and keyword arguments
556
- CALLS_KWARGS = (
537
+ CALLS_KWARGS = [
557
538
# (func, args: tuple, kwargs: dict, result)
558
539
559
540
# Python function with 2 arguments
@@ -564,17 +545,51 @@ class FastCallTests(unittest.TestCase):
564
545
(PYTHON_INSTANCE .method , (1 ,), {'arg2' : 2 }, [1 , 2 ]),
565
546
(PYTHON_INSTANCE .method , (), {'arg1' : 1 , 'arg2' : 2 }, [1 , 2 ]),
566
547
567
- # C function: METH_VARARGS | METH_KEYWORDS
568
- (max , ([],), {'default' : 9 }, 9 ),
569
-
570
- # C type static method: METH_FASTCALL | METH_CLASS
571
- (int .from_bytes , (b'\x01 \x00 ' ,), {'byteorder' : 'little' }, 1 ),
572
- (int .from_bytes , (), {'bytes' : b'\x01 \x00 ' , 'byteorder' : 'little' }, 1 ),
573
- )
548
+ # C callables are added later
549
+ ]
550
+
551
+ # Add all the calling conventions and variants of C callables
552
+ _instance = _testcapi .MethInstance ()
553
+ for obj , expected_self in (
554
+ (_testcapi , _testcapi ), # module-level function
555
+ (_instance , _instance ), # bound method
556
+ (_testcapi .MethClass , _testcapi .MethClass ), # class method on class
557
+ (_testcapi .MethClass (), _testcapi .MethClass ), # class method on inst.
558
+ (_testcapi .MethStatic , None ), # static method
559
+ ):
560
+ CALLS_POSARGS .extend ([
561
+ (obj .meth_varargs , (1 , 2 ), (expected_self , (1 , 2 ))),
562
+ (obj .meth_varargs_keywords ,
563
+ (1 , 2 ), (expected_self , (1 , 2 ), NULL_OR_EMPTY )),
564
+ (obj .meth_fastcall , (1 , 2 ), (expected_self , (1 , 2 ))),
565
+ (obj .meth_fastcall , (), (expected_self , ())),
566
+ (obj .meth_fastcall_keywords ,
567
+ (1 , 2 ), (expected_self , (1 , 2 ), NULL_OR_EMPTY )),
568
+ (obj .meth_fastcall_keywords ,
569
+ (), (expected_self , (), NULL_OR_EMPTY )),
570
+ (obj .meth_noargs , (), expected_self ),
571
+ (obj .meth_o , (123 , ), (expected_self , 123 )),
572
+ ])
573
+
574
+ CALLS_KWARGS .extend ([
575
+ (obj .meth_varargs_keywords ,
576
+ (1 , 2 ), {'x' : 'y' }, (expected_self , (1 , 2 ), {'x' : 'y' })),
577
+ (obj .meth_varargs_keywords ,
578
+ (), {'x' : 'y' }, (expected_self , (), {'x' : 'y' })),
579
+ (obj .meth_varargs_keywords ,
580
+ (1 , 2 ), {}, (expected_self , (1 , 2 ), NULL_OR_EMPTY )),
581
+ (obj .meth_fastcall_keywords ,
582
+ (1 , 2 ), {'x' : 'y' }, (expected_self , (1 , 2 ), {'x' : 'y' })),
583
+ (obj .meth_fastcall_keywords ,
584
+ (), {'x' : 'y' }, (expected_self , (), {'x' : 'y' })),
585
+ (obj .meth_fastcall_keywords ,
586
+ (1 , 2 ), {}, (expected_self , (1 , 2 ), NULL_OR_EMPTY )),
587
+ ])
574
588
575
589
def check_result (self , result , expected ):
576
- if expected is IGNORE_RESULT :
577
- return
590
+ if isinstance (expected , tuple ) and expected [- 1 ] is NULL_OR_EMPTY :
591
+ if result [- 1 ] in ({}, None ):
592
+ expected = (* expected [:- 1 ], result [- 1 ])
578
593
self .assertEqual (result , expected )
579
594
580
595
def test_fastcall (self ):
@@ -599,19 +614,11 @@ def test_vectorcall_dict(self):
599
614
result = _testcapi .pyobject_fastcalldict (func , args , None )
600
615
self .check_result (result , expected )
601
616
602
- # kwargs={}
603
- result = _testcapi .pyobject_fastcalldict (func , args , {})
604
- self .check_result (result , expected )
605
-
606
617
if not args :
607
618
# args=NULL, nargs=0, kwargs=NULL
608
619
result = _testcapi .pyobject_fastcalldict (func , None , None )
609
620
self .check_result (result , expected )
610
621
611
- # args=NULL, nargs=0, kwargs={}
612
- result = _testcapi .pyobject_fastcalldict (func , None , {})
613
- self .check_result (result , expected )
614
-
615
622
for func , args , kwargs , expected in self .CALLS_KWARGS :
616
623
with self .subTest (func = func , args = args , kwargs = kwargs ):
617
624
result = _testcapi .pyobject_fastcalldict (func , args , kwargs )
0 commit comments