@@ -26,6 +26,19 @@ def gen():
2626 yield 'c'
2727
2828
29+ class FrozenDictSubclass (frozendict ):
30+ pass
31+
32+
33+ DICT_TYPES = (dict , DictSubclass , OrderedDict )
34+ FROZENDICT_TYPES = (frozendict , FrozenDictSubclass )
35+ ANYDICT_TYPES = DICT_TYPES + FROZENDICT_TYPES
36+ MAPPING_TYPES = (UserDict ,)
37+ NOT_FROZENDICT_TYPES = DICT_TYPES + MAPPING_TYPES
38+ NOT_ANYDICT_TYPES = MAPPING_TYPES
39+ OTHER_TYPES = (lambda : [1 ], lambda : 42 , object ) # (list, int, object)
40+
41+
2942class CAPITest (unittest .TestCase ):
3043
3144 def test_dict_check (self ):
@@ -410,6 +423,7 @@ def test_dict_next(self):
410423 # CRASHES dict_next(NULL, 0)
411424
412425 def test_dict_update (self ):
426+ # Test PyDict_Update()
413427 update = _testlimitedcapi .dict_update
414428 for cls1 in dict , DictSubclass :
415429 for cls2 in dict , DictSubclass , UserDict :
@@ -420,11 +434,13 @@ def test_dict_update(self):
420434 self .assertRaises (AttributeError , update , {}, [])
421435 self .assertRaises (AttributeError , update , {}, 42 )
422436 self .assertRaises (SystemError , update , UserDict (), {})
437+ self .assertRaises (SystemError , update , frozendict (), {})
423438 self .assertRaises (SystemError , update , 42 , {})
424439 self .assertRaises (SystemError , update , {}, NULL )
425440 self .assertRaises (SystemError , update , NULL , {})
426441
427442 def test_dict_merge (self ):
443+ # Test PyDict_Merge()
428444 merge = _testlimitedcapi .dict_merge
429445 for cls1 in dict , DictSubclass :
430446 for cls2 in dict , DictSubclass , UserDict :
@@ -438,11 +454,13 @@ def test_dict_merge(self):
438454 self .assertRaises (AttributeError , merge , {}, [], 0 )
439455 self .assertRaises (AttributeError , merge , {}, 42 , 0 )
440456 self .assertRaises (SystemError , merge , UserDict (), {}, 0 )
457+ self .assertRaises (SystemError , merge , frozendict (), {}, 0 )
441458 self .assertRaises (SystemError , merge , 42 , {}, 0 )
442459 self .assertRaises (SystemError , merge , {}, NULL , 0 )
443460 self .assertRaises (SystemError , merge , NULL , {}, 0 )
444461
445462 def test_dict_mergefromseq2 (self ):
463+ # Test PyDict_MergeFromSeq2()
446464 mergefromseq2 = _testlimitedcapi .dict_mergefromseq2
447465 for cls1 in dict , DictSubclass :
448466 for cls2 in list , iter :
@@ -457,8 +475,8 @@ def test_dict_mergefromseq2(self):
457475 self .assertRaises (ValueError , mergefromseq2 , {}, [(1 , 2 , 3 )], 0 )
458476 self .assertRaises (TypeError , mergefromseq2 , {}, [1 ], 0 )
459477 self .assertRaises (TypeError , mergefromseq2 , {}, 42 , 0 )
460- # CRASHES mergefromseq2( UserDict(), [], 0)
461- # CRASHES mergefromseq2( 42, [], 0)
478+ self . assertRaises ( SystemError , mergefromseq2 , UserDict (), [], 0 )
479+ self . assertRaises ( SystemError , mergefromseq2 , 42 , [], 0 )
462480 # CRASHES mergefromseq2({}, NULL, 0)
463481 # CRASHES mergefromseq2(NULL, {}, 0)
464482
@@ -549,6 +567,61 @@ def test_dict_popstring(self):
549567 # CRASHES dict_popstring({}, NULL)
550568 # CRASHES dict_popstring({"a": 1}, NULL)
551569
570+ def test_frozendict_check (self ):
571+ # Test PyFrozenDict_Check()
572+ check = _testcapi .frozendict_check
573+ for dict_type in FROZENDICT_TYPES :
574+ self .assertTrue (check (dict_type (x = 1 )))
575+ for dict_type in NOT_FROZENDICT_TYPES + OTHER_TYPES :
576+ self .assertFalse (check (dict_type ()))
577+ # CRASHES check(NULL)
578+
579+ def test_frozendict_checkexact (self ):
580+ # Test PyFrozenDict_CheckExact()
581+ check = _testcapi .frozendict_checkexact
582+ for dict_type in FROZENDICT_TYPES :
583+ self .assertEqual (check (dict_type (x = 1 )), dict_type == frozendict )
584+ for dict_type in NOT_FROZENDICT_TYPES + OTHER_TYPES :
585+ self .assertFalse (check (dict_type ()))
586+ # CRASHES check(NULL)
587+
588+ def test_anydict_check (self ):
589+ # Test PyAnyDict_Check()
590+ check = _testcapi .anydict_check
591+ for dict_type in ANYDICT_TYPES :
592+ self .assertTrue (check (dict_type ({1 : 2 })))
593+ for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES :
594+ self .assertFalse (check (test_type ()))
595+ # CRASHES check(NULL)
596+
597+ def test_anydict_checkexact (self ):
598+ # Test PyAnyDict_CheckExact()
599+ check = _testcapi .anydict_checkexact
600+ for dict_type in ANYDICT_TYPES :
601+ self .assertEqual (check (dict_type (x = 1 )),
602+ dict_type in (dict , frozendict ))
603+ for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES :
604+ self .assertFalse (check (test_type ()))
605+ # CRASHES check(NULL)
606+
607+ def test_frozendict_new (self ):
608+ # Test PyFrozenDict_New()
609+ frozendict_new = _testcapi .frozendict_new
610+
611+ for dict_type in ANYDICT_TYPES :
612+ dct = frozendict_new (dict_type ({'x' : 1 }))
613+ self .assertEqual (dct , frozendict (x = 1 ))
614+ self .assertIs (type (dct ), frozendict )
615+
616+ dct = frozendict_new ([('x' , 1 ), ('y' , 2 )])
617+ self .assertEqual (dct , frozendict (x = 1 , y = 2 ))
618+ self .assertIs (type (dct ), frozendict )
619+
620+ # PyFrozenDict_New(NULL) creates an empty dictionary
621+ dct = frozendict_new (NULL )
622+ self .assertEqual (dct , frozendict ())
623+ self .assertIs (type (dct ), frozendict )
624+
552625
553626if __name__ == "__main__" :
554627 unittest .main ()
0 commit comments