@@ -416,6 +416,86 @@ class SubDict(dict):
416416self .assertTrue (_testcapi .mapping_has_key (dct2 ,'a' ))
417417self .assertFalse (_testcapi .mapping_has_key (dct2 ,'b' ))
418418
419+ def test_sequence_set_slice (self ):
420+ # Correct case:
421+ data = [1 ,2 ,3 ,4 ,5 ]
422+ data_copy = data .copy ()
423+
424+ _testcapi .sequence_set_slice (data ,1 ,3 , [8 ,9 ])
425+ data_copy [1 :3 ]= [8 ,9 ]
426+ self .assertEqual (data ,data_copy )
427+ self .assertEqual (data , [1 ,8 ,9 ,4 ,5 ])
428+
429+ # Custom class:
430+ class Custom :
431+ def __setitem__ (self ,index ,value ):
432+ self .index = index
433+ self .value = value
434+
435+ c = Custom ()
436+ _testcapi .sequence_set_slice (c ,0 ,5 ,'abc' )
437+ self .assertEqual (c .index ,slice (0 ,5 ))
438+ self .assertEqual (c .value ,'abc' )
439+
440+ # Immutable sequences must raise:
441+ bad_seq1 = (1 ,2 ,3 ,4 )
442+ with self .assertRaises (TypeError ):
443+ _testcapi .sequence_set_slice (bad_seq1 ,1 ,3 , (8 ,9 ))
444+ self .assertEqual (bad_seq1 , (1 ,2 ,3 ,4 ))
445+
446+ bad_seq2 = 'abcd'
447+ with self .assertRaises (TypeError ):
448+ _testcapi .sequence_set_slice (bad_seq2 ,1 ,3 ,'xy' )
449+ self .assertEqual (bad_seq2 ,'abcd' )
450+
451+ # Not a sequence:
452+ with self .assertRaises (TypeError ):
453+ _testcapi .sequence_set_slice (None ,1 ,3 ,'xy' )
454+
455+ mapping = {1 :'a' ,2 :'b' ,3 :'c' }
456+ with self .assertRaises (TypeError ):
457+ _testcapi .sequence_set_slice (mapping ,1 ,3 ,'xy' )
458+ self .assertEqual (mapping , {1 :'a' ,2 :'b' ,3 :'c' })
459+
460+ def test_sequence_del_slice (self ):
461+ # Correct case:
462+ data = [1 ,2 ,3 ,4 ,5 ]
463+ data_copy = data .copy ()
464+
465+ _testcapi .sequence_del_slice (data ,1 ,3 )
466+ del data_copy [1 :3 ]
467+ self .assertEqual (data ,data_copy )
468+ self .assertEqual (data , [1 ,4 ,5 ])
469+
470+ # Custom class:
471+ class Custom :
472+ def __delitem__ (self ,index ):
473+ self .index = index
474+
475+ c = Custom ()
476+ _testcapi .sequence_del_slice (c ,0 ,5 )
477+ self .assertEqual (c .index ,slice (0 ,5 ))
478+
479+ # Immutable sequences must raise:
480+ bad_seq1 = (1 ,2 ,3 ,4 )
481+ with self .assertRaises (TypeError ):
482+ _testcapi .sequence_del_slice (bad_seq1 ,1 ,3 )
483+ self .assertEqual (bad_seq1 , (1 ,2 ,3 ,4 ))
484+
485+ bad_seq2 = 'abcd'
486+ with self .assertRaises (TypeError ):
487+ _testcapi .sequence_del_slice (bad_seq2 ,1 ,3 )
488+ self .assertEqual (bad_seq2 ,'abcd' )
489+
490+ # Not a sequence:
491+ with self .assertRaises (TypeError ):
492+ _testcapi .sequence_del_slice (None ,1 ,3 )
493+
494+ mapping = {1 :'a' ,2 :'b' ,3 :'c' }
495+ with self .assertRaises (TypeError ):
496+ _testcapi .sequence_del_slice (mapping ,1 ,3 )
497+ self .assertEqual (mapping , {1 :'a' ,2 :'b' ,3 :'c' })
498+
419499@unittest .skipUnless (hasattr (_testcapi ,'negative_refcount' ),
420500'need _testcapi.negative_refcount' )
421501def test_negative_refcount (self ):
@@ -907,6 +987,21 @@ def method_example(self): ...
907987self .assertEqual (_testcapi .eval_get_func_name (sum ),"sum" )# c function
908988self .assertEqual (_testcapi .eval_get_func_name (A ),"type" )
909989
990+ def test_eval_get_func_desc (self ):
991+ def function_example (): ...
992+
993+ class A :
994+ def method_example (self ): ...
995+
996+ self .assertEqual (_testcapi .eval_get_func_desc (function_example ),
997+ "()" )
998+ self .assertEqual (_testcapi .eval_get_func_desc (A .method_example ),
999+ "()" )
1000+ self .assertEqual (_testcapi .eval_get_func_desc (A ().method_example ),
1001+ "()" )
1002+ self .assertEqual (_testcapi .eval_get_func_desc (sum ),"()" )# c function
1003+ self .assertEqual (_testcapi .eval_get_func_desc (A )," object" )
1004+
9101005def test_function_get_code (self ):
9111006import types
9121007
@@ -943,18 +1038,32 @@ def some():
9431038_testcapi .function_get_module (None )# not a function
9441039
9451040def test_function_get_defaults (self ):
946- def some (pos_only = 'p' ,zero = 0 ,optional = None ):
1041+ def some (
1042+ pos_only1 ,pos_only2 = 'p' ,
1043+ / ,
1044+ zero = 0 ,optional = None ,
1045+ * ,
1046+ kw1 ,
1047+ kw2 = True ,
1048+ ):
9471049pass
9481050
9491051defaults = _testcapi .function_get_defaults (some )
9501052self .assertEqual (defaults , ('p' ,0 ,None ))
9511053self .assertEqual (defaults ,some .__defaults__ )
9521054
9531055with self .assertRaises (SystemError ):
954- _testcapi .function_get_module (None )# not a function
1056+ _testcapi .function_get_defaults (None )# not a function
9551057
9561058def test_function_set_defaults (self ):
957- def some (pos_only = 'p' ,zero = 0 ,optional = None ):
1059+ def some (
1060+ pos_only1 ,pos_only2 = 'p' ,
1061+ / ,
1062+ zero = 0 ,optional = None ,
1063+ * ,
1064+ kw1 ,
1065+ kw2 = True ,
1066+ ):
9581067pass
9591068
9601069old_defaults = ('p' ,0 ,None )
@@ -966,11 +1075,22 @@ def some(pos_only='p', zero=0, optional=None):
9661075self .assertEqual (_testcapi .function_get_defaults (some ),old_defaults )
9671076self .assertEqual (some .__defaults__ ,old_defaults )
9681077
1078+ with self .assertRaises (SystemError ):
1079+ _testcapi .function_set_defaults (1 , ())# not a function
1080+ self .assertEqual (_testcapi .function_get_defaults (some ),old_defaults )
1081+ self .assertEqual (some .__defaults__ ,old_defaults )
1082+
9691083new_defaults = ('q' ,1 ,None )
9701084_testcapi .function_set_defaults (some ,new_defaults )
9711085self .assertEqual (_testcapi .function_get_defaults (some ),new_defaults )
9721086self .assertEqual (some .__defaults__ ,new_defaults )
9731087
1088+ # Empty tuple is fine:
1089+ new_defaults = ()
1090+ _testcapi .function_set_defaults (some ,new_defaults )
1091+ self .assertEqual (_testcapi .function_get_defaults (some ),new_defaults )
1092+ self .assertEqual (some .__defaults__ ,new_defaults )
1093+
9741094class tuplesub (tuple ): ...# tuple subclasses must work
9751095
9761096new_defaults = tuplesub (((1 ,2 ), ['a' ,'b' ],None ))
@@ -984,6 +1104,73 @@ class tuplesub(tuple): ... # tuple subclasses must work
9841104self .assertEqual (_testcapi .function_get_defaults (some ),None )
9851105self .assertEqual (some .__defaults__ ,None )
9861106
1107+ def test_function_get_kw_defaults (self ):
1108+ def some (
1109+ pos_only1 ,pos_only2 = 'p' ,
1110+ / ,
1111+ zero = 0 ,optional = None ,
1112+ * ,
1113+ kw1 ,
1114+ kw2 = True ,
1115+ ):
1116+ pass
1117+
1118+ defaults = _testcapi .function_get_kw_defaults (some )
1119+ self .assertEqual (defaults , {'kw2' :True })
1120+ self .assertEqual (defaults ,some .__kwdefaults__ )
1121+
1122+ with self .assertRaises (SystemError ):
1123+ _testcapi .function_get_kw_defaults (None )# not a function
1124+
1125+ def test_function_set_kw_defaults (self ):
1126+ def some (
1127+ pos_only1 ,pos_only2 = 'p' ,
1128+ / ,
1129+ zero = 0 ,optional = None ,
1130+ * ,
1131+ kw1 ,
1132+ kw2 = True ,
1133+ ):
1134+ pass
1135+
1136+ old_defaults = {'kw2' :True }
1137+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),old_defaults )
1138+ self .assertEqual (some .__kwdefaults__ ,old_defaults )
1139+
1140+ with self .assertRaises (SystemError ):
1141+ _testcapi .function_set_kw_defaults (some ,1 )# not dict or None
1142+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),old_defaults )
1143+ self .assertEqual (some .__kwdefaults__ ,old_defaults )
1144+
1145+ with self .assertRaises (SystemError ):
1146+ _testcapi .function_set_kw_defaults (1 , {})# not a function
1147+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),old_defaults )
1148+ self .assertEqual (some .__kwdefaults__ ,old_defaults )
1149+
1150+ new_defaults = {'kw2' : (1 ,2 ,3 )}
1151+ _testcapi .function_set_kw_defaults (some ,new_defaults )
1152+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),new_defaults )
1153+ self .assertEqual (some .__kwdefaults__ ,new_defaults )
1154+
1155+ # Empty dict is fine:
1156+ new_defaults = {}
1157+ _testcapi .function_set_kw_defaults (some ,new_defaults )
1158+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),new_defaults )
1159+ self .assertEqual (some .__kwdefaults__ ,new_defaults )
1160+
1161+ class dictsub (dict ): ...# dict subclasses must work
1162+
1163+ new_defaults = dictsub ({'kw2' :None })
1164+ _testcapi .function_set_kw_defaults (some ,new_defaults )
1165+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),new_defaults )
1166+ self .assertEqual (some .__kwdefaults__ ,new_defaults )
1167+
1168+ # `None` is special, it sets `kwdefaults` to `NULL`,
1169+ # it needs special handling in `_testcapi`:
1170+ _testcapi .function_set_kw_defaults (some ,None )
1171+ self .assertEqual (_testcapi .function_get_kw_defaults (some ),None )
1172+ self .assertEqual (some .__kwdefaults__ ,None )
1173+
9871174
9881175class TestPendingCalls (unittest .TestCase ):
9891176