def test_misc_non_mutating(self): ''' Misc non-mutating dict behaviors. - Superdict instances generally behave like normal dicts. ''' sd = Superdict(a = 11, b = 22) # __contains__ self.assertTrue('a' in sd) self.assertFalse('z' in sd) self.assertFalse('pop' in sd) # __len__ aEq(len(sd), 2) # keys, values, items aEq(set(sd.keys()), set('ab')) aEq(set(sd.values()), set([11,22])) aEq(set(sd.items()), set([('a', 11), ('b', 22)])) # copy d = sd.copy() self.assertIs(type(d), dict) aEq(d, dict(sd)) # equality aEq(sd, dict(a = 11, b = 22))
def test_clear(self): ''' clear(). ''' # Create dict. sd = Superdict(a=11, b=22) sd.clear() # Nothing remains. with aRaz(AERR): sd.a with aRaz(AERR): sd.b with aRaz(KERR): sd['a'] with aRaz(KERR): sd['b']
def test_popitem(self): ''' popitem(). ''' # Create dict. pairs = [('a', 11), ('b', 22)] sd = Superdict(pairs) # Pop everything. s = set(sd.popitem() for _ in range(len(sd))) aEq(s, set(pairs)) # Nothing remains. with aRaz(AERR): sd.a with aRaz(AERR): sd.b with aRaz(KERR): sd['a'] with aRaz(KERR): sd['b']
def test_unicode(self): ''' Unicode - Overridden attributes are treated like normal ones. - But other protected attributes remain protected. - And normal attributes behave normally. ''' # Non-ascii keys and vals work fine. u = u'\xf8' sd = Superdict(a = 1, b = 2) sd[u] = 12 sd.x = u # Non-ascii keys work fine exception messages. sd = StrictSuperdict('ab', a = 1, b = 2) with aRaz(AERR): sd[u] = 12
def test_protected_attribute_setting(self): ''' Protected attribute setting. - Protected attributes should stay protected. - Protection should work for attr setting or key setting. ''' sd = Superdict() v = 1234 # Setting via attribute. sd.update = v aEq(sd['update'], v) self.assertNotEqual(sd['update'], sd.update) self.assertIsInstance(sd.update, types.MethodType) # Setting via key. sd['pop'] = v aEq(sd['pop'], v) self.assertNotEqual(sd['pop'], sd.pop) self.assertIsInstance(sd.pop, types.MethodType)
def test_get(self): ''' get(). - The normal get() behavior applies to all types of superdicts. ''' # Regular. sd = Superdict(a = 11, b = 22) aEq(sd.get('a'), 11) aEq(sd.get('z'), None) aEq(sd.get('update'), None) # Strict. sd = StrictSuperdict('ab', a = 11, b = 22) aEq(sd.get('a'), 11) aEq(sd.get('z'), None) aEq(sd.get('update'), None) # Relaxed. sd = RelaxedSuperdict('pop'.split(), a = 11, b = 22, pop = 333) aEq(sd.get('a'), 11) aEq(sd.get('z'), None) aEq(sd.get('update'), None) aEq(sd.get('pop'), 333)
def test_basic_attribute_access(self): ''' Basic attribute access. - Can set values via attr or key. - Set values are store in both the attr and the key. ''' sd = Superdict(a = 1, b = 2) # Basics. sd.b = 22 sd['c'] = 33 aEq(sd.a, 1) aEq(sd.c, 33) aEq(sd['a'], 1) aEq(sd['c'], 33) aEq(sd, dict(a = 1, b = 22, c = 33)) # Set attributes are stored both as attributes on the Superdict and as # keys in the underlying dict. ks = set('abc') for k in ks: self.assertIn(k, sd.__dict__) dict_ks = super(Superdict, sd).keys() aEq(set(dict_ks), ks)
def test_update(self): ''' update(). - Since the constructor relies on update(), this behavior is well covered. ''' sd = Superdict(a=11, b=22) # Basic attributes. sd.update(c = 33, d = 44) aEq(sd.c, 33) aEq(sd.d, 44) aEq(sd['c'], 33) # Protected attributes. sd.update([('pop', 99), ('setdefault', 88)]) aEq(sd['pop'], 99) self.assertIsInstance(sd.pop, types.MethodType) # Wrong N args. with aRaz(TERR): sd.update([1,2,3], [4,5])
def test_setdefault(self): ''' setdefault(). ''' sd = Superdict(a=11, b=22) # Basic attributes. a = sd.setdefault('a', 999) c = sd.setdefault('c', 888) aEq(sd.a, 11) aEq(a, 11) aEq(sd.c, 888) aEq(c, 888) # Protected attributes. p = sd.setdefault('pop', 999) aEq(sd['pop'], 999) aEq(p, 999) self.assertIsInstance(sd.pop, types.MethodType) # Wrong N args. with aRaz(TERR): sd.setdefault() with aRaz(TERR): sd.setdefault(1,2,3)
def test_pop(self): ''' pop(). - The normal pop() behavior applies to all types of superdicts. - Calls to pop() should remove the attr and the key. ''' # Superdict: sd = Superdict(a = 11, b = 22) # - regular attribute. aEq(sd.pop('a'), 11) aEq(sd.get('a'), None) aEq(getattr(sd, 'a', None), None) aEq(sd.pop('z', 777), 777) # - protected attribute. sd.pop = 33 aEq(sd.pop('pop'), 33) aEq(sd.get('pop'), None) self.assertIsInstance(getattr(sd, 'pop', None), types.MethodType) # - attributes that do not exist. aEq(sd.pop('update', 1234), 1234) with aRaz(KERR): sd.pop('update') with aRaz(KERR): sd.pop('z') # - wrong N of args. with aRaz(TERR): sd.pop() with aRaz(TERR): sd.pop('z', 1234, 567) # StrictSuperdict: sd = StrictSuperdict('ab', a = 11, b = 22) # - regular attribute. aEq(sd.pop('a'), 11) aEq(sd.pop('a', 99), 99) # - non-approved attribute. with aRaz(KERR): sd.pop('update') with aRaz(KERR): sd.pop('z') # RelaxedSuperdict: overridden = 'get setdefault'.split() sd = RelaxedSuperdict(overridden, a = 11, b = 22) # - regular attribute. aEq(sd.pop('a'), 11) aEq(sd.pop('a', 99), 99) # - overridden attribute. sd.setdefault = 1234 aEq(sd.pop('setdefault'), 1234)