[pypy-svn] r17420 - in pypy/dist/pypy/rpython: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Sep 9 18:16:05 CEST 2005
Author: arigo
Date: Fri Sep 9 18:16:03 2005
New Revision: 17420
Added:
pypy/dist/pypy/rpython/test/test_objectmodel.py (contents, props changed)
Modified:
pypy/dist/pypy/rpython/objectmodel.py
Log:
An r_dict() class that will work a bit like a dict at interp-level, but
containing keys over which we have control for hashing and comparison,
via subclassing and overriding the key_eq() and key_hash() methods.
The idea is to use it to replace the dictobject.py table lookup algorithms
altogether, then annotate r_dict almost like regular dictionaries, in the same
way that we annotate r_int almost like regular ints.
Modified: pypy/dist/pypy/rpython/objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/objectmodel.py (original)
+++ pypy/dist/pypy/rpython/objectmodel.py Fri Sep 9 18:16:03 2005
@@ -29,3 +29,96 @@
assert not getattr(obj.__class__, "_alloc_flavor_", 'gc').startswith('gc'), "trying to free gc object"
obj.__dict__ = {}
obj.__class__ = FREED_OBJECT
+
+# ____________________________________________________________
+
+
+class r_dict(object):
+ """An RPython dict-like object.
+ Only provides the interface supported by RPython.
+ The methods key_eq() and key_hash() are used by the key comparison
+ algorithm and can be subclassed."""
+
+ def __init__(self):
+ self._dict = {}
+
+ def __getitem__(self, key):
+ return self._dict[_r_dictkey(self, key)]
+
+ def __setitem__(self, key, value):
+ self._dict[_r_dictkey(self, key)] = value
+
+ def __delitem__(self, key):
+ del self._dict[_r_dictkey(self, key)]
+
+ def __len__(self):
+ return len(self._dict)
+
+ def __iter__(self):
+ for dk in self._dict:
+ yield dk.key
+
+ def __contains__(self, key):
+ return _r_dictkey(self, key) in self._dict
+
+ def get(self, key, default):
+ return self._dict.get(_r_dictkey(self, key), default)
+
+ def copy(self):
+ result = self.__class__()
+ result.update(self)
+ return result
+
+ def update(self, other):
+ for key, value in other.items():
+ self[key] = value
+
+ def keys(self):
+ return [dk.key for dk in self._dict]
+
+ def values(self):
+ return self._dict.values()
+
+ def items(self):
+ return [(dk.key, value) for dk, value in self._dict.items()]
+
+ iterkeys = __iter__
+
+ def itervalues(self):
+ return self._dict.itervalues()
+
+ def iteritems(self):
+ for dk, value in self._dict.items():
+ yield dk.key, value
+
+ def clear(self):
+ self._dict.clear()
+
+ def key_eq(self, key1, key2):
+ "Called to compare two keys. Can be overridden in subclasses."
+ return key1 == key2
+
+ def key_hash(self, key):
+ "Called to compute the hash of a key. Can be overridden in subclasses."
+ return hash(key)
+
+ def __repr__(self):
+ "Representation for debugging purposes."
+ return 'r_dict(%r)' % (dict(self.items()),)
+
+
+class _r_dictkey(object):
+ __slots__ = ['dic', 'key']
+ def __init__(self, dic, key):
+ self.dic = dic
+ self.key = key
+ def __eq__(self, other):
+ if not isinstance(other, _r_dictkey):
+ return NotImplemented
+ return self.dic.key_eq(self.key, other.key)
+ def __ne__(self, other):
+ if not isinstance(other, _r_dictkey):
+ return NotImplemented
+ return not self.dic.key_eq(self.key, other.key)
+ def __hash__(self):
+ return self.dic.key_hash(self.key)
Added: pypy/dist/pypy/rpython/test/test_objectmodel.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_objectmodel.py Fri Sep 9 18:16:03 2005
@@ -0,0 +1,40 @@
+import py
+from pypy.rpython.objectmodel import *
+from pypy.rpython.test.test_llinterp import interpret
+
+
+def test_we_are_translated():
+ assert we_are_translated() == False
+
+ def fn():
+ return we_are_translated()
+ res = interpret(fn, [])
+ assert res is True
+
+def test_r_dict():
+ class StrangeDict(r_dict):
+ def key_eq(self, key1, key2):
+ return key1[0] == key2[0] # only the 1st character is relevant
+ def key_hash(self, key):
+ return ord(key[0])
+ d = StrangeDict()
+ d['hello'] = 42
+ assert d['hi there'] == 42
+ py.test.raises(KeyError, 'd["dumb"]')
+ assert len(d) == 1
+ assert 'oops' not in d
+ assert list(d) == ['hello']
+ assert d.get('hola', -1) == 42
+ assert d.get('salut', -1) == -1
+ d1 = d.copy()
+ del d['hu!']
+ assert len(d) == 0
+ assert d1.keys() == ['hello']
+ d.update(d1)
+ assert d.values() == [42]
+ assert d.items() == [('hello', 42)]
+ assert list(d.iterkeys()) == ['hello']
+ assert list(d.itervalues()) == [42]
+ assert list(d.iteritems()) == [('hello', 42)]
+ d.clear()
+ assert d.keys() == []
More information about the Pypy-commit
mailing list