tests common to dict and userdict this base class can be used to check that an object conforms to the mapping protocol functions that can be useful to override to adapt to dictionary semantics return a dictionary of values which are invariant by storage in the object under test return 1 2 key1 value1 key2 1 2 3 def emptymappingself return a mapping object with the value contained in data dictionary x self emptymapping for key value in data items xkey value return x def initself args kw unittest testcase initself args kw self reference self reference copy a key value pair not in the mapping key value self reference popitem self other key value a key value pair in the mapping key value self reference popitem self inmapping key value self referencekey value def testreadself test for read only operations on mapping p self emptymapping p1 dictp workaround for singleton objects d self fullmappingself reference if d is p p p1 indexing for key value in self reference items self assertequaldkey value knownkey listself other keys0 self assertraiseskeyerror lambda dknownkey len self assertequallenp 0 self assertequallend lenself reference contains for k in self reference self assertink d for k in self other self assertnotink d cmp self assertequalp p self assertequald d self assertnotequalp d self assertnotequald p bool if p self failempty mapping must compare to false if not d self failfull mapping must compare to true keys items iterkeys def checkiterandlistiter lst ref self asserttruehasattriter next self asserttruehasattriter iter x listiter self asserttruesetxsetlstsetref checkiterandlistiterd keys listd keys self reference keys checkiterandlistiterd listd keys self reference keys checkiterandlistiterd values listd values self reference values checkiterandlistiterd items listd items self reference items get key value nextiterd items knownkey knownvalue nextiterself other items self assertequald getkey knownvalue value self assertequald getknownkey knownvalue knownvalue self assertnotinknownkey d def testwriteself test for write operations on mapping p self emptymapping indexing for key value in self reference items pkey value self assertequalpkey value for key in self reference keys del pkey self assertraiseskeyerror lambda pkey p self emptymapping update p updateself reference self assertequaldictp self reference items listp items p self emptymapping p updateitems self assertequaldictp self reference d self fullmappingself reference setdefault key value nextiterd items knownkey knownvalue nextiterself other items self assertequald setdefaultkey knownvalue value self assertequaldkey value self assertequald setdefaultknownkey knownvalue knownvalue self assertequaldknownkey knownvalue pop self assertequald popknownkey knownvalue self assertnotinknownkey d self assertraiseskeyerror d pop knownkey default 909 dknownkey knownvalue self assertequald popknownkey default knownvalue self assertnotinknownkey d self assertequald popknownkey default default popitem key value d popitem self assertnotinkey d self assertequalvalue self referencekey pself emptymapping self assertraiseskeyerror p popitem def testconstructorself self assertequalself emptymapping self emptymapping def testboolself self asserttruenot self emptymapping self asserttrueself reference self asserttrueboolself emptymapping is false self asserttrueboolself reference is true def testkeysself d self emptymapping self assertequallistd keys d self reference self assertinlistself inmapping keys0 d keys self assertnotinlistself other keys0 d keys self assertraisestypeerror d keys none def testvaluesself d self emptymapping self assertequallistd values self assertraisestypeerror d values none def testitemsself d self emptymapping self assertequallistd items self assertraisestypeerror d items none def testlenself d self emptymapping self assertequallend 0 def testgetitemself d self reference self assertequaldlistself inmapping keys0 listself inmapping values0 self assertraisestypeerror d getitem def testupdateself mapping argument d self emptymapping d updateself other self assertequallistd items listself other items no argument d self emptymapping d update self assertequald self emptymapping item sequence d self emptymapping d updateself other items self assertequallistd items listself other items iterator d self emptymapping d updateself other items self assertequallistd items listself other items fixme doesn t work with userdict self assertraisestypeerror attributeerror d update none self assertraisestypeerror attributeerror d update 42 outerself self class simpleuserdict def initself self d outerself reference def keysself return self d keys def getitemself i return self di d clear d updatesimpleuserdict i1 sortedd items i2 sortedself reference items self assertequali1 i2 class excexception pass d self emptymapping class failinguserdict def keysself raise exc self assertraisesexc d update failinguserdict d clear class failinguserdict def keysself class bogoniter def initself self i 1 def iterself return self def nextself if self i self i 0 return a raise exc return bogoniter def getitemself key return key self assertraisesexc d update failinguserdict class failinguserdict def keysself class bogoniter def initself self i ord a def iterself return self def nextself if self i ord z rtn chrself i self i 1 return rtn raise stopiteration return bogoniter def getitemself key raise exc self assertraisesexc d update failinguserdict d self emptymapping class badseqobject def iterself return self def nextself raise exc self assertraisesexc d update badseq self assertraisesvalueerror d update 1 2 3 no testfromkeys or testcopy as both os environ and selves don t support it def testgetself d self emptymapping self asserttrued getlistself other keys0 is none self assertequald getlistself other keys0 3 3 d self reference self asserttrued getlistself other keys0 is none self assertequald getlistself other keys0 3 3 self assertequald getlistself inmapping keys0 listself inmapping values0 self assertequald getlistself inmapping keys0 3 listself inmapping values0 self assertraisestypeerror d get self assertraisestypeerror d get none none none def testsetdefaultself d self emptymapping self assertraisestypeerror d setdefault def testpopitemself d self emptymapping self assertraiseskeyerror d popitem self assertraisestypeerror d popitem 42 def testpopself d self emptymapping k v listself inmapping items0 dk v self assertraiseskeyerror d pop listself other keys0 self assertequald popk v self assertequallend 0 self assertraiseskeyerror d pop k class testmappingprotocolbasictestmappingprotocol def testconstructorself basictestmappingprotocol testconstructorself self asserttrueself emptymapping is not self emptymapping self assertequalself type2testx1 y2 x 1 y 2 def testboolself basictestmappingprotocol testboolself self asserttruenot self emptymapping self asserttrueself fullmappingx y self asserttrueboolself emptymapping is false self asserttrueboolself fullmappingx y is true def testkeysself basictestmappingprotocol testkeysself d self emptymapping self assertequallistd keys d self fullmapping a 1 b 2 k d keys self assertin a k self assertin b k self assertnotin c k def testvaluesself basictestmappingprotocol testvaluesself d self fullmapping1 2 self assertequallistd values 2 def testitemsself basictestmappingprotocol testitemsself d self fullmapping1 2 self assertequallistd items 1 2 def testcontainsself d self emptymapping self assertnotin a d self asserttruenot a in d self asserttrue a not in d d self fullmapping a 1 b 2 self assertin a d self assertin b d self assertnotin c d self assertraisestypeerror d contains def testlenself basictestmappingprotocol testlenself d self fullmapping a 1 b 2 self assertequallend 2 def testgetitemself basictestmappingprotocol testgetitemself d self fullmapping a 1 b 2 self assertequald a 1 self assertequald b 2 d c 3 d a 4 self assertequald c 3 self assertequald a 4 del d b self assertequald a 4 c 3 self assertraisestypeerror d getitem def testclearself d self fullmapping1 1 2 2 3 3 d clear self assertequald self assertraisestypeerror d clear none def testupdateself basictestmappingprotocol testupdateself mapping argument d self emptymapping d update1 100 d update2 20 d update1 1 2 2 3 3 self assertequald 1 1 2 2 3 3 no argument d update self assertequald 1 1 2 2 3 3 keyword arguments d self emptymapping d updatex100 d updatey20 d updatex1 y2 z3 self assertequald x 1 y 2 z 3 item sequence d self emptymapping d updatex 100 y 20 self assertequald x 100 y 20 both item sequence and keyword arguments d self emptymapping d updatex 100 y 20 x1 y2 self assertequald x 1 y 2 iterator d self fullmapping1 3 2 4 d updateself fullmapping1 2 3 4 5 6 items self assertequald 1 2 2 4 3 4 5 6 class simpleuserdict def initself self d 1 1 2 2 3 3 def keysself return self d keys def getitemself i return self di d clear d updatesimpleuserdict self assertequald 1 1 2 2 3 3 def testfromkeysself self assertequalself type2test fromkeys abc a none b none c none d self emptymapping self asserttruenotd fromkeys abc is d self assertequald fromkeys abc a none b none c none self assertequald fromkeys4 5 0 4 0 5 0 self assertequald fromkeys def g yield 1 self assertequald fromkeysg 1 none self assertraisestypeerror fromkeys 3 class dictlikeself type2test pass self assertequaldictlike fromkeys a a none self assertequaldictlike fromkeys a a none self asserttruedictlike fromkeys a class is dictlike self asserttruedictlike fromkeys a class is dictlike self asserttruetypedictlike fromkeys a is dictlike class mydictself type2test def newcls return collections userdict ud mydict fromkeys ab self assertequalud a none b none self assertisinstanceud collections userdict self assertraisestypeerror dict fromkeys class excexception pass class baddict1self type2test def initself args kwargs raise exc self assertraisesexc baddict1 fromkeys 1 class badseqobject def iterself return self def nextself raise exc self assertraisesexc self type2test fromkeys badseq class baddict2self type2test def setitemself key value raise exc self assertraisesexc baddict2 fromkeys 1 def testcopyself d self fullmapping1 1 2 2 3 3 self assertequald copy 1 1 2 2 3 3 d self emptymapping self assertequald copy d self assertisinstanced copy d class self assertraisestypeerror d copy none def testgetself basictestmappingprotocol testgetself d self emptymapping self asserttrued get c is none self assertequald get c 3 3 d self fullmapping a 1 b 2 self asserttrued get c is none self assertequald get c 3 3 self assertequald get a 1 self assertequald get a 3 1 def testsetdefaultself basictestmappingprotocol testsetdefaultself d self emptymapping self asserttrued setdefault key0 is none d setdefault key0 self asserttrued setdefault key0 is none d setdefault key append3 self assertequald key 0 3 d setdefault key append4 self assertequallend key 2 def testpopitemself basictestmappingprotocol testpopitemself for copymode in 1 1 1 b has same structure as a 1 b is a copy for log2size in range12 size 2log2size a self emptymapping b self emptymapping for i in rangesize arepri i if copymode 0 brepri i if copymode 0 b a copy for i in rangesize ka va ta a popitem self assertequalva intka kb vb tb b popitem self assertequalvb intkb self asserttruenotcopymode 0 and ta tb self asserttruenot a self asserttruenot b def testpopself basictestmappingprotocol testpopself tests for pop with specified key d self emptymapping k v abc def self assertequald popk v v dk v self assertequald popk 1 v class testhashmappingprotocoltestmappingprotocol def testgetitemself testmappingprotocol testgetitemself class excexception pass class badeqobject def eqself other raise exc def hashself return 24 d self emptymapping dbadeq 42 self assertraiseskeyerror d getitem 23 class badhashobject fail false def hashself if self fail raise exc else return 42 d self emptymapping x badhash dx 42 x fail true self assertraisesexc d getitem x def testfromkeysself testmappingprotocol testfromkeysself class mydictself type2test def newcls return collections userdict ud mydict fromkeys ab self assertequalud a none b none self assertisinstanceud collections userdict def testpopself testmappingprotocol testpopself class excexception pass class badhashobject fail false def hashself if self fail raise exc else return 42 d self emptymapping x badhash dx 42 x fail true self assertraisesexc d pop x def testmutatingiterationself d self emptymapping d1 1 try count 0 for i in d di1 1 if count 1 self failchanging dict size during iteration doesn t raise error count 1 except runtimeerror pass def testreprself d self emptymapping self assertequalreprd d1 2 self assertequalreprd 1 2 d self emptymapping d1 d self assertequalreprd 1 class excexception pass class badreprobject def reprself raise exc d self fullmapping1 badrepr self assertraisesexc repr d def testreprdeepself d self emptymapping for i in rangepycrecursionlimit 1 d0 d d self emptymapping d1 d0 self assertraisesrecursionerror repr d def testeqself self assertequalself emptymapping self emptymapping self assertequalself fullmapping1 2 self fullmapping1 2 class excexception pass class badcmpobject def eqself other raise exc def hashself return 1 d1 self fullmappingbadcmp 1 d2 self fullmapping1 1 self assertraisesexc lambda badcmp1 self assertraisesexc lambda d1d2 def testsetdefaultself testmappingprotocol testsetdefaultself class excexception pass class badhashobject fail false def hashself if self fail raise exc else return 42 d self emptymapping x badhash dx 42 x fail true self assertraisesexc d setdefault x tests common to dict and userdict this base class can be used to check that an object conforms to the mapping protocol functions that can be useful to override to adapt to dictionary semantics which class is being tested overwrite in subclasses return a dictionary of values which are invariant by storage in the object under test return an empty mapping object return a mapping object with the value contained in data dictionary a key value pair not in the mapping a key value pair in the mapping test for read only operations on mapping workaround for singleton objects indexing len __contains__ cmp bool keys items iterkeys get test for write operations on mapping indexing update setdefault pop popitem mapping argument no argument item sequence iterator fixme doesn t work with userdict self assertraises typeerror attributeerror d update none no test_fromkeys or test_copy as both os environ and selves don t support it mapping argument no argument keyword arguments item sequence both item sequence and keyword arguments iterator 1 b has same structure as a 1 b is a copy tests for pop with specified key
import unittest
import collections
from test.support import Py_C_RECURSION_LIMIT


class BasicTestMappingProtocol(unittest.TestCase):
    
    

    
    
    type2test = None 

    def _reference(self):
        
        return {"1": "2", "key1":"value1", "key2":(1,2,3)}
    def _empty_mapping(self):
        
        return self.type2test()
    def _full_mapping(self, data):
        
        x = self._empty_mapping()
        for key, value in data.items():
            x[key] = value
        return x

    def __init__(self, *args, **kw):
        unittest.TestCase.__init__(self, *args, **kw)
        self.reference = self._reference().copy()

        
        key, value = self.reference.popitem()
        self.other = {key:value}

        
        key, value = self.reference.popitem()
        self.inmapping = {key:value}
        self.reference[key] = value

    def test_read(self):
        
        p = self._empty_mapping()
        p1 = dict(p) 
        d = self._full_mapping(self.reference)
        if d is p:
            p = p1
        
        for key, value in self.reference.items():
            self.assertEqual(d[key], value)
        knownkey = list(self.other.keys())[0]
        self.assertRaises(KeyError, lambda:d[knownkey])
        
        self.assertEqual(len(p), 0)
        self.assertEqual(len(d), len(self.reference))
        
        for k in self.reference:
            self.assertIn(k, d)
        for k in self.other:
            self.assertNotIn(k, d)
        
        self.assertEqual(p, p)
        self.assertEqual(d, d)
        self.assertNotEqual(p, d)
        self.assertNotEqual(d, p)
        
        if p: self.fail("Empty mapping must compare to False")
        if not d: self.fail("Full mapping must compare to True")
        
        def check_iterandlist(iter, lst, ref):
            self.assertTrue(hasattr(iter, '__next__'))
            self.assertTrue(hasattr(iter, '__iter__'))
            x = list(iter)
            self.assertTrue(set(x)==set(lst)==set(ref))
        check_iterandlist(iter(d.keys()), list(d.keys()),
                          self.reference.keys())
        check_iterandlist(iter(d), list(d.keys()), self.reference.keys())
        check_iterandlist(iter(d.values()), list(d.values()),
                          self.reference.values())
        check_iterandlist(iter(d.items()), list(d.items()),
                          self.reference.items())
        
        key, value = next(iter(d.items()))
        knownkey, knownvalue = next(iter(self.other.items()))
        self.assertEqual(d.get(key, knownvalue), value)
        self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
        self.assertNotIn(knownkey, d)

    def test_write(self):
        
        p = self._empty_mapping()
        
        for key, value in self.reference.items():
            p[key] = value
            self.assertEqual(p[key], value)
        for key in self.reference.keys():
            del p[key]
            self.assertRaises(KeyError, lambda:p[key])
        p = self._empty_mapping()
        
        p.update(self.reference)
        self.assertEqual(dict(p), self.reference)
        items = list(p.items())
        p = self._empty_mapping()
        p.update(items)
        self.assertEqual(dict(p), self.reference)
        d = self._full_mapping(self.reference)
        
        key, value = next(iter(d.items()))
        knownkey, knownvalue = next(iter(self.other.items()))
        self.assertEqual(d.setdefault(key, knownvalue), value)
        self.assertEqual(d[key], value)
        self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
        self.assertEqual(d[knownkey], knownvalue)
        
        self.assertEqual(d.pop(knownkey), knownvalue)
        self.assertNotIn(knownkey, d)
        self.assertRaises(KeyError, d.pop, knownkey)
        default = 909
        d[knownkey] = knownvalue
        self.assertEqual(d.pop(knownkey, default), knownvalue)
        self.assertNotIn(knownkey, d)
        self.assertEqual(d.pop(knownkey, default), default)
        
        key, value = d.popitem()
        self.assertNotIn(key, d)
        self.assertEqual(value, self.reference[key])
        p=self._empty_mapping()
        self.assertRaises(KeyError, p.popitem)

    def test_constructor(self):
        self.assertEqual(self._empty_mapping(), self._empty_mapping())

    def test_bool(self):
        self.assertTrue(not self._empty_mapping())
        self.assertTrue(self.reference)
        self.assertTrue(bool(self._empty_mapping()) is False)
        self.assertTrue(bool(self.reference) is True)

    def test_keys(self):
        d = self._empty_mapping()
        self.assertEqual(list(d.keys()), [])
        d = self.reference
        self.assertIn(list(self.inmapping.keys())[0], d.keys())
        self.assertNotIn(list(self.other.keys())[0], d.keys())
        self.assertRaises(TypeError, d.keys, None)

    def test_values(self):
        d = self._empty_mapping()
        self.assertEqual(list(d.values()), [])

        self.assertRaises(TypeError, d.values, None)

    def test_items(self):
        d = self._empty_mapping()
        self.assertEqual(list(d.items()), [])

        self.assertRaises(TypeError, d.items, None)

    def test_len(self):
        d = self._empty_mapping()
        self.assertEqual(len(d), 0)

    def test_getitem(self):
        d = self.reference
        self.assertEqual(d[list(self.inmapping.keys())[0]],
                         list(self.inmapping.values())[0])

        self.assertRaises(TypeError, d.__getitem__)

    def test_update(self):
        
        d = self._empty_mapping()
        d.update(self.other)
        self.assertEqual(list(d.items()), list(self.other.items()))

        
        d = self._empty_mapping()
        d.update()
        self.assertEqual(d, self._empty_mapping())

        
        d = self._empty_mapping()
        d.update(self.other.items())
        self.assertEqual(list(d.items()), list(self.other.items()))

        
        d = self._empty_mapping()
        d.update(self.other.items())
        self.assertEqual(list(d.items()), list(self.other.items()))

        
        
        self.assertRaises((TypeError, AttributeError), d.update, 42)

        outerself = self
        class SimpleUserDict:
            def __init__(self):
                self.d = outerself.reference
            def keys(self):
                return self.d.keys()
            def __getitem__(self, i):
                return self.d[i]
        d.clear()
        d.update(SimpleUserDict())
        i1 = sorted(d.items())
        i2 = sorted(self.reference.items())
        self.assertEqual(i1, i2)

        class Exc(Exception): pass

        d = self._empty_mapping()
        class FailingUserDict:
            def keys(self):
                raise Exc
        self.assertRaises(Exc, d.update, FailingUserDict())

        d.clear()

        class FailingUserDict:
            def keys(self):
                class BogonIter:
                    def __init__(self):
                        self.i = 1
                    def __iter__(self):
                        return self
                    def __next__(self):
                        if self.i:
                            self.i = 0
                            return 'a'
                        raise Exc
                return BogonIter()
            def __getitem__(self, key):
                return key
        self.assertRaises(Exc, d.update, FailingUserDict())

        class FailingUserDict:
            def keys(self):
                class BogonIter:
                    def __init__(self):
                        self.i = ord('a')
                    def __iter__(self):
                        return self
                    def __next__(self):
                        if self.i <= ord('z'):
                            rtn = chr(self.i)
                            self.i += 1
                            return rtn
                        raise StopIteration
                return BogonIter()
            def __getitem__(self, key):
                raise Exc
        self.assertRaises(Exc, d.update, FailingUserDict())

        d = self._empty_mapping()
        class badseq(object):
            def __iter__(self):
                return self
            def __next__(self):
                raise Exc()

        self.assertRaises(Exc, d.update, badseq())

        self.assertRaises(ValueError, d.update, [(1, 2, 3)])

    

    def test_get(self):
        d = self._empty_mapping()
        self.assertTrue(d.get(list(self.other.keys())[0]) is None)
        self.assertEqual(d.get(list(self.other.keys())[0], 3), 3)
        d = self.reference
        self.assertTrue(d.get(list(self.other.keys())[0]) is None)
        self.assertEqual(d.get(list(self.other.keys())[0], 3), 3)
        self.assertEqual(d.get(list(self.inmapping.keys())[0]),
                         list(self.inmapping.values())[0])
        self.assertEqual(d.get(list(self.inmapping.keys())[0], 3),
                         list(self.inmapping.values())[0])
        self.assertRaises(TypeError, d.get)
        self.assertRaises(TypeError, d.get, None, None, None)

    def test_setdefault(self):
        d = self._empty_mapping()
        self.assertRaises(TypeError, d.setdefault)

    def test_popitem(self):
        d = self._empty_mapping()
        self.assertRaises(KeyError, d.popitem)
        self.assertRaises(TypeError, d.popitem, 42)

    def test_pop(self):
        d = self._empty_mapping()
        k, v = list(self.inmapping.items())[0]
        d[k] = v
        self.assertRaises(KeyError, d.pop, list(self.other.keys())[0])

        self.assertEqual(d.pop(k), v)
        self.assertEqual(len(d), 0)

        self.assertRaises(KeyError, d.pop, k)


class TestMappingProtocol(BasicTestMappingProtocol):
    def test_constructor(self):
        BasicTestMappingProtocol.test_constructor(self)
        self.assertTrue(self._empty_mapping() is not self._empty_mapping())
        self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2})

    def test_bool(self):
        BasicTestMappingProtocol.test_bool(self)
        self.assertTrue(not self._empty_mapping())
        self.assertTrue(self._full_mapping({"x": "y"}))
        self.assertTrue(bool(self._empty_mapping()) is False)
        self.assertTrue(bool(self._full_mapping({"x": "y"})) is True)

    def test_keys(self):
        BasicTestMappingProtocol.test_keys(self)
        d = self._empty_mapping()
        self.assertEqual(list(d.keys()), [])
        d = self._full_mapping({'a': 1, 'b': 2})
        k = d.keys()
        self.assertIn('a', k)
        self.assertIn('b', k)
        self.assertNotIn('c', k)

    def test_values(self):
        BasicTestMappingProtocol.test_values(self)
        d = self._full_mapping({1:2})
        self.assertEqual(list(d.values()), [2])

    def test_items(self):
        BasicTestMappingProtocol.test_items(self)

        d = self._full_mapping({1:2})
        self.assertEqual(list(d.items()), [(1, 2)])

    def test_contains(self):
        d = self._empty_mapping()
        self.assertNotIn('a', d)
        self.assertTrue(not ('a' in d))
        self.assertTrue('a' not in d)
        d = self._full_mapping({'a': 1, 'b': 2})
        self.assertIn('a', d)
        self.assertIn('b', d)
        self.assertNotIn('c', d)

        self.assertRaises(TypeError, d.__contains__)

    def test_len(self):
        BasicTestMappingProtocol.test_len(self)
        d = self._full_mapping({'a': 1, 'b': 2})
        self.assertEqual(len(d), 2)

    def test_getitem(self):
        BasicTestMappingProtocol.test_getitem(self)
        d = self._full_mapping({'a': 1, 'b': 2})
        self.assertEqual(d['a'], 1)
        self.assertEqual(d['b'], 2)
        d['c'] = 3
        d['a'] = 4
        self.assertEqual(d['c'], 3)
        self.assertEqual(d['a'], 4)
        del d['b']
        self.assertEqual(d, {'a': 4, 'c': 3})

        self.assertRaises(TypeError, d.__getitem__)

    def test_clear(self):
        d = self._full_mapping({1:1, 2:2, 3:3})
        d.clear()
        self.assertEqual(d, {})

        self.assertRaises(TypeError, d.clear, None)

    def test_update(self):
        BasicTestMappingProtocol.test_update(self)
        
        d = self._empty_mapping()
        d.update({1:100})
        d.update({2:20})
        d.update({1:1, 2:2, 3:3})
        self.assertEqual(d, {1:1, 2:2, 3:3})

        
        d.update()
        self.assertEqual(d, {1:1, 2:2, 3:3})

        
        d = self._empty_mapping()
        d.update(x=100)
        d.update(y=20)
        d.update(x=1, y=2, z=3)
        self.assertEqual(d, {"x":1, "y":2, "z":3})

        
        d = self._empty_mapping()
        d.update([("x", 100), ("y", 20)])
        self.assertEqual(d, {"x":100, "y":20})

        
        d = self._empty_mapping()
        d.update([("x", 100), ("y", 20)], x=1, y=2)
        self.assertEqual(d, {"x":1, "y":2})

        
        d = self._full_mapping({1:3, 2:4})
        d.update(self._full_mapping({1:2, 3:4, 5:6}).items())
        self.assertEqual(d, {1:2, 2:4, 3:4, 5:6})

        class SimpleUserDict:
            def __init__(self):
                self.d = {1:1, 2:2, 3:3}
            def keys(self):
                return self.d.keys()
            def __getitem__(self, i):
                return self.d[i]
        d.clear()
        d.update(SimpleUserDict())
        self.assertEqual(d, {1:1, 2:2, 3:3})

    def test_fromkeys(self):
        self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
        d = self._empty_mapping()
        self.assertTrue(not(d.fromkeys('abc') is d))
        self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
        self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})
        self.assertEqual(d.fromkeys([]), {})
        def g():
            yield 1
        self.assertEqual(d.fromkeys(g()), {1:None})
        self.assertRaises(TypeError, {}.fromkeys, 3)
        class dictlike(self.type2test): pass
        self.assertEqual(dictlike.fromkeys('a'), {'a':None})
        self.assertEqual(dictlike().fromkeys('a'), {'a':None})
        self.assertTrue(dictlike.fromkeys('a').__class__ is dictlike)
        self.assertTrue(dictlike().fromkeys('a').__class__ is dictlike)
        self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)
        class mydict(self.type2test):
            def __new__(cls):
                return collections.UserDict()
        ud = mydict.fromkeys('ab')
        self.assertEqual(ud, {'a':None, 'b':None})
        self.assertIsInstance(ud, collections.UserDict)
        self.assertRaises(TypeError, dict.fromkeys)

        class Exc(Exception): pass

        class baddict1(self.type2test):
            def __init__(self, *args, **kwargs):
                raise Exc()

        self.assertRaises(Exc, baddict1.fromkeys, [1])

        class BadSeq(object):
            def __iter__(self):
                return self
            def __next__(self):
                raise Exc()

        self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())

        class baddict2(self.type2test):
            def __setitem__(self, key, value):
                raise Exc()

        self.assertRaises(Exc, baddict2.fromkeys, [1])

    def test_copy(self):
        d = self._full_mapping({1:1, 2:2, 3:3})
        self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
        d = self._empty_mapping()
        self.assertEqual(d.copy(), d)
        self.assertIsInstance(d.copy(), d.__class__)
        self.assertRaises(TypeError, d.copy, None)

    def test_get(self):
        BasicTestMappingProtocol.test_get(self)
        d = self._empty_mapping()
        self.assertTrue(d.get('c') is None)
        self.assertEqual(d.get('c', 3), 3)
        d = self._full_mapping({'a' : 1, 'b' : 2})
        self.assertTrue(d.get('c') is None)
        self.assertEqual(d.get('c', 3), 3)
        self.assertEqual(d.get('a'), 1)
        self.assertEqual(d.get('a', 3), 1)

    def test_setdefault(self):
        BasicTestMappingProtocol.test_setdefault(self)
        d = self._empty_mapping()
        self.assertTrue(d.setdefault('key0') is None)
        d.setdefault('key0', [])
        self.assertTrue(d.setdefault('key0') is None)
        d.setdefault('key', []).append(3)
        self.assertEqual(d['key'][0], 3)
        d.setdefault('key', []).append(4)
        self.assertEqual(len(d['key']), 2)

    def test_popitem(self):
        BasicTestMappingProtocol.test_popitem(self)
        for copymode in -1, +1:
            
            
            for log2size in range(12):
                size = 2**log2size
                a = self._empty_mapping()
                b = self._empty_mapping()
                for i in range(size):
                    a[repr(i)] = i
                    if copymode < 0:
                        b[repr(i)] = i
                if copymode > 0:
                    b = a.copy()
                for i in range(size):
                    ka, va = ta = a.popitem()
                    self.assertEqual(va, int(ka))
                    kb, vb = tb = b.popitem()
                    self.assertEqual(vb, int(kb))
                    self.assertTrue(not(copymode < 0 and ta != tb))
                self.assertTrue(not a)
                self.assertTrue(not b)

    def test_pop(self):
        BasicTestMappingProtocol.test_pop(self)

        
        d = self._empty_mapping()
        k, v = 'abc', 'def'

        self.assertEqual(d.pop(k, v), v)
        d[k] = v
        self.assertEqual(d.pop(k, 1), v)


class TestHashMappingProtocol(TestMappingProtocol):

    def test_getitem(self):
        TestMappingProtocol.test_getitem(self)
        class Exc(Exception): pass

        class BadEq(object):
            def __eq__(self, other):
                raise Exc()
            def __hash__(self):
                return 24

        d = self._empty_mapping()
        d[BadEq()] = 42
        self.assertRaises(KeyError, d.__getitem__, 23)

        class BadHash(object):
            fail = False
            def __hash__(self):
                if self.fail:
                    raise Exc()
                else:
                    return 42

        d = self._empty_mapping()
        x = BadHash()
        d[x] = 42
        x.fail = True
        self.assertRaises(Exc, d.__getitem__, x)

    def test_fromkeys(self):
        TestMappingProtocol.test_fromkeys(self)
        class mydict(self.type2test):
            def __new__(cls):
                return collections.UserDict()
        ud = mydict.fromkeys('ab')
        self.assertEqual(ud, {'a':None, 'b':None})
        self.assertIsInstance(ud, collections.UserDict)

    def test_pop(self):
        TestMappingProtocol.test_pop(self)

        class Exc(Exception): pass

        class BadHash(object):
            fail = False
            def __hash__(self):
                if self.fail:
                    raise Exc()
                else:
                    return 42

        d = self._empty_mapping()
        x = BadHash()
        d[x] = 42
        x.fail = True
        self.assertRaises(Exc, d.pop, x)

    def test_mutatingiteration(self):
        d = self._empty_mapping()
        d[1] = 1
        try:
            count = 0
            for i in d:
                d[i+1] = 1
                if count >= 1:
                    self.fail("changing dict size during iteration doesn't raise Error")
                count += 1
        except RuntimeError:
            pass

    def test_repr(self):
        d = self._empty_mapping()
        self.assertEqual(repr(d), '{}')
        d[1] = 2
        self.assertEqual(repr(d), '{1: 2}')
        d = self._empty_mapping()
        d[1] = d
        self.assertEqual(repr(d), '{1: {...}}')

        class Exc(Exception): pass

        class BadRepr(object):
            def __repr__(self):
                raise Exc()

        d = self._full_mapping({1: BadRepr()})
        self.assertRaises(Exc, repr, d)

    def test_repr_deep(self):
        d = self._empty_mapping()
        for i in range(Py_C_RECURSION_LIMIT + 1):
            d0 = d
            d = self._empty_mapping()
            d[1] = d0
        self.assertRaises(RecursionError, repr, d)

    def test_eq(self):
        self.assertEqual(self._empty_mapping(), self._empty_mapping())
        self.assertEqual(self._full_mapping({1: 2}),
                         self._full_mapping({1: 2}))

        class Exc(Exception): pass

        class BadCmp(object):
            def __eq__(self, other):
                raise Exc()
            def __hash__(self):
                return 1

        d1 = self._full_mapping({BadCmp(): 1})
        d2 = self._full_mapping({1: 1})
        self.assertRaises(Exc, lambda: BadCmp()==1)
        self.assertRaises(Exc, lambda: d1==d2)

    def test_setdefault(self):
        TestMappingProtocol.test_setdefault(self)

        class Exc(Exception): pass

        class BadHash(object):
            fail = False
            def __hash__(self):
                if self.fail:
                    raise Exc()
                else:
                    return 42

        d = self._empty_mapping()
        x = BadHash()
        d[x] = 42
        x.fail = True
        self.assertRaises(Exc, d.setdefault, x, [])