[pypy-commit] pypy set-strategies: implemented new iteratorimplementation (similar to dictmultiobject)
l.diekmann
noreply at buildbot.pypy.org
Thu Nov 10 13:50:15 CET 2011
Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r49185:6e5ed22d0735
Date: 2011-06-08 11:28 +0200
http://bitbucket.org/pypy/pypy/changeset/6e5ed22d0735/
Log: implemented new iteratorimplementation (similar to dictmultiobject)
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -149,6 +149,9 @@
def equals(self, w_other):
return self.strategy.equals(self, w_other)
+ def iter(self):
+ return self.strategy.iter(self)
+
class W_SetObject(W_BaseSetObject):
from pypy.objspace.std.settype import set_typedef as typedef
@@ -265,6 +268,9 @@
w_set.switch_to_object_strategy(self.space)
w_set.update(w_other)
+ def iter(self, w_set):
+ return EmptyIteratorImplementation(self.space, w_set)
+
class AbstractUnwrappedSetStrategy(object):
_mixin_ = True
@@ -555,6 +561,9 @@
def wrap(self, item):
return self.space.wrap(item)
+ def iter(self, w_set):
+ return IntegerIteratorImplementation(self.space, self, w_set)
+
class ObjectSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
cast_to_void_star, cast_from_void_star = rerased.new_erasing_pair("object")
cast_to_void_star = staticmethod(cast_to_void_star)
@@ -575,20 +584,79 @@
def wrap(self, item):
return item
+ def iter(self, w_set):
+ return RDictIteratorImplementation(self.space, self, w_set)
+
+class IteratorImplementation(object):
+ def __init__(self, space, implementation):
+ self.space = space
+ self.dictimplementation = implementation
+ self.len = implementation.length()
+ self.pos = 0
+
+ def next(self):
+ if self.dictimplementation is None:
+ return None, None
+ if self.len != self.dictimplementation.length():
+ self.len = -1 # Make this error state sticky
+ raise OperationError(self.space.w_RuntimeError,
+ self.space.wrap("dictionary changed size during iteration"))
+ # look for the next entry
+ if self.pos < self.len:
+ result = self.next_entry()
+ self.pos += 1
+ return result
+ # no more entries
+ self.dictimplementation = None
+ return None, None
+
+ def next_entry(self):
+ """ Purely abstract method
+ """
+ raise NotImplementedError
+
+ def length(self):
+ if self.dictimplementation is not None:
+ return self.len - self.pos
+ return 0
+
+class EmptyIteratorImplementation(IteratorImplementation):
+ def next(self):
+ return (None, None)
+
+class IntegerIteratorImplementation(IteratorImplementation):
+ #XXX same implementation in dictmultiobject on dictstrategy-branch
+ def __init__(self, space, strategy, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ d = strategy.cast_from_void_star(dictimplementation.sstorage)
+ self.iterator = d.iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_key, w_value in self.iterator:
+ return self.space.wrap(w_key), w_value
+ else:
+ return None, None
+
+class RDictIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, strategy, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ d = strategy.cast_from_void_star(dictimplementation.sstorage)
+ self.iterator = d.iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for item in self.iterator:
+ return item
+ else:
+ return None, None
+
class W_SetIterObject(W_Object):
from pypy.objspace.std.settype import setiter_typedef as typedef
- def __init__(w_self, setdata):
- w_self.content = content = setdata
- w_self.len = len(content)
- w_self.pos = 0
- w_self.iterator = iter(w_self.content)
-
- def next_entry(w_self):
- for w_key in w_self.iterator:
- return w_key
- else:
- return None
+ def __init__(w_self, space, iterimplementation):
+ w_self.space = space
+ w_self.iterimplementation = iterimplementation
registerimplementation(W_SetIterObject)
@@ -596,19 +664,10 @@
return w_setiter
def next__SetIterObject(space, w_setiter):
- content = w_setiter.content
- if content is not None:
- if w_setiter.len != len(content):
- w_setiter.len = -1 # Make this error state sticky
- raise OperationError(space.w_RuntimeError,
- space.wrap("Set changed size during iteration"))
- # look for the next entry
- w_result = w_setiter.next_entry()
- if w_result is not None:
- w_setiter.pos += 1
- return w_result
- # no more entries
- w_setiter.content = None
+ iterimplementation = w_setiter.iterimplementation
+ w_key, w_value = iterimplementation.next()
+ if w_key is not None:
+ return w_key
raise OperationError(space.w_StopIteration, space.w_None)
# XXX __length_hint__()
@@ -1086,7 +1145,8 @@
len__Frozenset = len__Set
def iter__Set(space, w_left):
- return W_SetIterObject(w_left.getkeys())
+ #return iter(w_left.getkeys())
+ return W_SetIterObject(space, w_left.iter())
iter__Frozenset = iter__Set
More information about the pypy-commit
mailing list