[pypy-svn] r26311 - in pypy/dist/pypy/rpython/ootypesystem: . test
antocuni at codespeak.net
antocuni at codespeak.net
Tue Apr 25 10:53:06 CEST 2006
Author: antocuni
Date: Tue Apr 25 10:52:59 2006
New Revision: 26311
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py
Log:
The Dict interface has been changed to support a more efficient
iteration.
The ll_get_items_iterator ADT method has been added: it returns a
DictItemsIterator that allow a pseudo-iteration over dict
items. Methods such as keys(), values(), items() and their iter*
correspondent will be implemented in term of it.
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Apr 25 10:52:59 2006
@@ -358,7 +358,8 @@
"ll_set": Meth([self.KEYTYPE_T, self.VALUETYPE_T], Void),
"ll_remove": Meth([self.KEYTYPE_T], Bool), # return False is key was not present
"ll_contains": Meth([self.KEYTYPE_T], Bool),
- "ll_keys": Meth([], List(self.KEYTYPE_T)),
+ "ll_keys": Meth([], List(self.KEYTYPE_T)), # deprecated
+ "ll_get_items_iterator": Meth([], DictItemsIterator(self.KEYTYPE_T, self.VALUETYPE_T)),
})
self._setup_methods(generic_types)
@@ -382,6 +383,54 @@
VALUETYPE = self._specialize_type(self._VALUETYPE, generic_types)
return self.__class__(KEYTYPE, VALUETYPE)
+class DictItemsIterator(BuiltinADTType):
+ SELFTYPE_T = object()
+ KEYTYPE_T = object()
+ VALUETYPE_T = object()
+
+ def __init__(self, KEYTYPE, VALUETYPE):
+ self._KEYTYPE = KEYTYPE
+ self._VALUETYPE = VALUETYPE
+ self._null = _null_dict_items_iterator(self)
+
+ generic_types = {
+ self.SELFTYPE_T: self,
+ self.KEYTYPE_T: KEYTYPE,
+ self.VALUETYPE_T: VALUETYPE
+ }
+
+ # some words about the interface of the iterator: we can't
+ # write the next() method directly in the backend because of
+ # two reasons:
+ # 1) tuples aren't BuiltinType, yet, so we can't make them
+ # generic; moreover, they are constructed on-the-fly, so the
+ # two-item tuple type that an hypotetic next() would return
+ # isn't available at this time.
+ # 2) StopIteration is generated at translation time too, so
+ # this would prevent backends to do a precompilation of
+ # support code.
+
+ self._GENERIC_METHODS = frozendict({
+ "ll_go_next": Meth([], Bool), # move forward; return False is there is no more data available
+ "ll_current_key": Meth([], self.KEYTYPE_T),
+ "ll_current_value": Meth([], self.VALUETYPE_T),
+ })
+
+ self._setup_methods(generic_types)
+
+ def __str__(self):
+ return '%s%s' % (self.__class__.__name__,
+ saferecursive(str, "(...)")((self._KEYTYPE, self._VALUETYPE)))
+
+ def _get_interp_class(self):
+ return _dict_items_iterator
+
+ def _specialize(self, generic_types):
+ KEYTYPE = self._specialize_type(self._KEYTYPE, generic_types)
+ VALUETYPE = self._specialize_type(self._VALUETYPE, generic_types)
+ return self.__class__(KEYTYPE, VALUETYPE)
+
+
class ForwardReference(OOType):
def become(self, real_instance):
if not isinstance(real_instance, (Instance, BuiltinADTType)):
@@ -753,11 +802,45 @@
keys._list = self._dict.keys()
return keys
-class _null_dict(_null_mixin(_dict), _dict):
+ def ll_get_items_iterator(self):
+ # NOT_RPYTHON
+ ITER = DictItemsIterator(self._TYPE._KEYTYPE, self._TYPE._VALUETYPE)
+ return _dict_items_iterator(ITER, self._dict)
+class _null_dict(_null_mixin(_dict), _dict):
def __init__(self, DICT):
self.__dict__["_TYPE"] = DICT
+
+class _dict_items_iterator(_builtin_type):
+ def __init__(self, ITER, d):
+ self._TYPE = ITER
+ self._items = d.items()
+ self._index = -1
+
+ def ll_go_next(self):
+ # NOT_RPYTHON
+ self._index += 1
+ if self._index >= len(self._items):
+ return False
+ else:
+ return True
+
+ def ll_current_key(self):
+ # NOT_RPYTHON
+ assert 0 <= self._index < len(self._items)
+ return self._items[self._index][0]
+
+ def ll_current_value(self):
+ # NOT_RPYTHON
+ assert 0 <= self._index < len(self._items)
+ return self._items[self._index][1]
+
+class _null_dict_items_iterator(_null_mixin(_dict_items_iterator), _dict_items_iterator):
+ def __init__(self, ITER):
+ self.__dict__["_TYPE"] = ITER
+
+
class _tuple(object):
def __init__(self, TYPE):
@@ -789,6 +872,7 @@
def __init__(self, TUPLE):
self.__dict__["_TYPE"] = TUPLE
+
def new(TYPE):
if isinstance(TYPE, Instance):
return make_instance(TYPE)
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py Tue Apr 25 10:52:59 2006
@@ -18,3 +18,15 @@
d = new(DT)
d.ll_set(42, 123.45)
assert d.ll_get(42) == 123.45
+
+def test_iteritems():
+ DT = Dict(Signed, Float)
+ d = new(DT)
+ d.ll_set(42, 43.0)
+ d.ll_set(52, 53.0)
+ it = d.ll_get_items_iterator()
+ items = []
+ while it.ll_go_next():
+ items.append((it.ll_current_key(), it.ll_current_value()))
+ items.sort()
+ assert items == [(42, 43.0), (52, 53.0)]
More information about the Pypy-commit
mailing list