[pypy-svn] r54356 - in pypy/branch/2.5-features/pypy/lib: . app_test
bgola at codespeak.net
bgola at codespeak.net
Sat May 3 00:38:23 CEST 2008
Author: bgola
Date: Sat May 3 00:38:21 2008
New Revision: 54356
Added:
pypy/branch/2.5-features/pypy/lib/app_test/test_defaultdict.py (contents, props changed)
Modified:
pypy/branch/2.5-features/pypy/lib/collections.py
Log:
defaultdict implementation in collections module
Added: pypy/branch/2.5-features/pypy/lib/app_test/test_defaultdict.py
==============================================================================
--- (empty file)
+++ pypy/branch/2.5-features/pypy/lib/app_test/test_defaultdict.py Sat May 3 00:38:21 2008
@@ -0,0 +1,110 @@
+# defaultdict Tests
+# from CPython2.5
+
+import copy
+
+# for passing the test on top of 2.3
+from py.builtin import reversed
+import pypy.lib.collections
+pypy.lib.collections.reversed = reversed
+
+from pypy.lib.collections import defaultdict
+
+def foobar():
+ return list
+
+class Test_defaultdict:
+
+ def test_basic(self):
+ d1 = defaultdict()
+ assert d1.default_factory is None
+ d1.default_factory = list
+ d1[12].append(42)
+ assert d1 == {12: [42]}
+ d1[12].append(24)
+ assert d1 == {12: [42, 24]}
+ d1[13]
+ d1[14]
+ assert d1 == {12: [42, 24], 13: [], 14: []}
+ assert d1[12] is not d1[13] is not d1[14]
+ d2 = defaultdict(list, foo=1, bar=2)
+ assert d2.default_factory == list
+ assert d2 == {"foo": 1, "bar": 2}
+ assert d2["foo"] == 1
+ assert d2["bar"] == 2
+ assert d2[42] == []
+ assert "foo" in d2
+ assert "foo" in d2.keys()
+ assert "bar" in d2
+ assert "bar" in d2.keys()
+ assert 42 in d2
+ assert 42 in d2.keys()
+ assert 12 not in d2
+ assert 12 not in d2.keys()
+ d2.default_factory = None
+ assert d2.default_factory == None
+ raises(KeyError, d2.__getitem__, 15)
+ raises(TypeError, defaultdict, 1)
+
+ def test_missing(self):
+ d1 = defaultdict()
+ raises(KeyError, d1.__missing__, 42)
+ d1.default_factory = list
+ assert d1.__missing__(42) == []
+
+ def test_repr(self):
+ d1 = defaultdict()
+ assert d1.default_factory == None
+ assert repr(d1) == "defaultdict(None, {})"
+ d1[11] = 41
+ assert repr(d1) == "defaultdict(None, {11: 41})"
+ d2 = defaultdict(int)
+ assert d2.default_factory == int
+ d2[12] = 42
+ assert repr(d2), "defaultdict(<type 'int'>, {12: 42})"
+ def foo(): return 43
+ d3 = defaultdict(foo)
+ assert d3.default_factory is foo
+ d3[13]
+ assert repr(d3), "defaultdict(%s, {13: 43})" % repr(foo)
+
+ def test_copy(self):
+ d1 = defaultdict()
+ d2 = d1.copy()
+ assert type(d2) == defaultdict
+ assert d2.default_factory == None
+ assert d2 == {}
+ d1.default_factory = list
+ d3 = d1.copy()
+ assert type(d3) == defaultdict
+ assert d3.default_factory == list
+ assert d3 == {}
+ d1[42]
+ d4 = d1.copy()
+ assert type(d4) == defaultdict
+ assert d4.default_factory == list
+ assert d4 == {42: []}
+ d4[12]
+ assert d4 == {42: [], 12: []}
+
+ def test_shallow_copy(self):
+ d1 = defaultdict(foobar, {1: 1})
+ d2 = copy.copy(d1)
+ assert d2.default_factory == foobar
+ assert d2 == d1
+ d1.default_factory = list
+ d2 = copy.copy(d1)
+ assert d2.default_factory == list
+ assert d2 == d1
+
+ def test_deep_copy(self):
+ d1 = defaultdict(foobar, {1: [1]})
+ d2 = copy.deepcopy(d1)
+ assert d2.default_factory == foobar
+ assert d2 == d1
+ assert d1[1] is not d2[1]
+ d1.default_factory = list
+ d2 = copy.deepcopy(d1)
+ assert d2.default_factory == list
+ assert d2 == d1
+
Modified: pypy/branch/2.5-features/pypy/lib/collections.py
==============================================================================
--- pypy/branch/2.5-features/pypy/lib/collections.py (original)
+++ pypy/branch/2.5-features/pypy/lib/collections.py Sat May 3 00:38:21 2008
@@ -308,4 +308,45 @@
def __len__(self):
return self.counter
-
+
+class defaultdict(dict):
+
+ def __init__(self, *args, **kwds):
+ self.default_factory = None
+ if 'default_factory' in kwds:
+ self.default_factory = kwds.pop('default_factory')
+ elif len(args) > 0 and callable(args[0]):
+ self.default_factory = args[0]
+ args = args[1:]
+ super(defaultdict, self).__init__(*args, **kwds)
+
+ def __missing__(self, key):
+ # from defaultdict docs
+ if self.default_factory is None:
+ raise KeyError((key,))
+ self[key] = value = self.default_factory()
+ return value
+
+ def __repr__(self):
+ return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__())
+
+ def copy(self):
+ return type(self)(self, default_factory=self.default_factory)
+
+ def __copy__(self):
+ return self.copy()
+
+ def __reduce__(self):
+ """
+ __reduce__ must return a 5-tuple as follows:
+
+ - factory function
+ - tuple of args for the factory function
+ - additional state (here None)
+ - sequence iterator (here None)
+ - dictionary iterator (yielding successive (key, value) pairs
+
+ This API is used by pickle.py and copy.py.
+ """
+ return (type(self), (self.default_factory,), None, None, self.iteritems())
+
More information about the pypy-svn
mailing list