Don't unnecessarily copy the key list

Conflicts:
	doc/contributors.rst
	test/test_son.py
This commit is contained in:
Don Mitchell 2014-06-04 13:56:13 -04:00 committed by A. Jesse Jiryu Davis
parent c18501c596
commit 01b499850c
3 changed files with 59 additions and 6 deletions

View File

@ -120,14 +120,20 @@ class SON(dict):
# efficient.
# second level definitions support higher levels
def __iter__(self):
for k in self.keys():
"""
Cannot remove nor add keys while iterating
"""
key_len = len(self.__keys)
for k in self.__keys:
if len(self.__keys) != key_len:
raise RuntimeError("son changed length during iteration")
yield k
def has_key(self, key):
return key in self.keys()
return key in self.__keys
def __contains__(self, key):
return key in self.keys()
return key in self.__keys
# third level takes advantage of second level definitions
def iteritems(self):
@ -149,8 +155,8 @@ class SON(dict):
return [(key, self[key]) for key in self]
def clear(self):
for key in self.keys():
del self[key]
self.__keys = []
super(SON, self).clear()
def setdefault(self, key, default=None):
try:
@ -214,7 +220,7 @@ class SON(dict):
return not self == other
def __len__(self):
return len(self.keys())
return len(self.__keys)
def to_dict(self):
"""Convert a SON document to a normal Python dictionary instance.

View File

@ -70,3 +70,4 @@ The following is a list of people who have contributed to
- Kyle Erf (3rf)
- Luke Lovett (lovett89)
- Jaroslav Semančík (girogiro)
- Don Mitchell (dmitchell)

View File

@ -155,6 +155,52 @@ class TestSON(unittest.TestCase):
self.assertEqual(reflexive_son.keys(), reflexive_son1.keys())
self.assertEqual(id(reflexive_son1), id(reflexive_son1["reflexive"]))
def test_iteration(self):
"""
Test __iter__
"""
# test success case
test_son = SON([(1, 100), (2, 200), (3, 300)])
for ele in test_son:
self.assertEqual(ele * 100, test_son[ele])
# test failure case
def break_iter():
for ele in test_son:
del test_son[ele]
self.assertRaises(RuntimeError, break_iter)
def test_contains_has(self):
"""
has_key and __contains__
"""
test_son = SON([(1, 100), (2, 200), (3, 300)])
self.assertIn(1, test_son)
self.assertTrue(2 in test_son, "in failed")
self.assertFalse(22 in test_son, "in succeeded when it shouldn't")
self.assertTrue(test_son.has_key(2), "has_key failed")
self.assertFalse(test_son.has_key(22), "has_key succeeded when it shouldn't")
def test_clears(self):
"""
Test clear()
"""
test_son = SON([(1, 100), (2, 200), (3, 300)])
test_son.clear()
self.assertNotIn(1, test_son)
self.assertEqual(0, len(test_son))
self.assertEqual(0, len(test_son.keys()))
self.assertEqual({}, test_son.to_dict())
def test_len(self):
"""
Test len
"""
test_son = SON()
self.assertEqual(0, len(test_son))
test_son = SON([(1, 100), (2, 200), (3, 300)])
self.assertEqual(3, len(test_son))
test_son.popitem()
self.assertEqual(2, len(test_son))
if __name__ == "__main__":
unittest.main()