[pypy-commit] pypy default: merge heads
antocuni
noreply at buildbot.pypy.org
Wed Aug 22 18:52:26 CEST 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r56811:773c11368fb7
Date: 2012-08-22 18:52 +0200
http://bitbucket.org/pypy/pypy/changeset/773c11368fb7/
Log: merge heads
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -301,10 +301,7 @@
if num_kwds:
# kwds_mapping maps target indexes in the scope (minus input_argcount)
# to positions in the keywords_w list
- cnt = (co_argcount - input_argcount)
- if cnt < 0:
- cnt = 0
- kwds_mapping = [0] * cnt
+ kwds_mapping = [0] * (co_argcount - input_argcount)
# initialize manually, for the JIT :-(
for i in range(len(kwds_mapping)):
kwds_mapping[i] = -1
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -20,6 +20,9 @@
UINT_MAX_32_BITS = r_uint(4294967295)
+unpackiterable_driver = jit.JitDriver(name = 'unpackiterable',
+ greens = ['tp'],
+ reds = ['items', 'w_iterator'])
class W_Root(object):
"""This is the abstract root class of all wrapped objects that live
@@ -224,6 +227,23 @@
def __spacebind__(self, space):
return self
+class W_InterpIterable(W_Root):
+ def __init__(self, space, w_iterable):
+ self.w_iter = space.iter(w_iterable)
+ self.space = space
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ space = self.space
+ try:
+ return space.next(self.w_iter)
+ except OperationError, e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ raise StopIteration
+
class InternalSpaceCache(Cache):
"""A generic cache for an object space. Arbitrary information can
be attached to the space by defining a function or class 'f' which
@@ -831,6 +851,9 @@
expected_length)
return lst_w[:] # make the resulting list resizable
+ def iteriterable(self, w_iterable):
+ return W_InterpIterable(self, w_iterable)
+
@jit.dont_look_inside
def _unpackiterable_unknown_length(self, w_iterator, w_iterable):
# Unpack a variable-size list of unknown length.
@@ -851,7 +874,11 @@
except MemoryError:
items = [] # it might have lied
#
+ tp = self.type(w_iterator)
while True:
+ unpackiterable_driver.jit_merge_point(tp=tp,
+ w_iterator=w_iterator,
+ items=items)
try:
w_item = self.next(w_iterator)
except OperationError, e:
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -14,6 +14,7 @@
from pypy.rlib.debug import fatalerror
from pypy.rlib.rstackovf import StackOverflow
from pypy.translator.simplify import get_functype
+from pypy.translator.backendopt import removenoops
from pypy.translator.unsimplify import call_final_function
from pypy.jit.metainterp import history, pyjitpl, gc, memmgr
@@ -260,6 +261,10 @@
graph = copygraph(graph)
[jmpp] = find_jit_merge_points([graph])
graph.startblock = support.split_before_jit_merge_point(*jmpp)
+ # XXX this is incredibly obscure, but this is sometiems necessary
+ # so we don't explode in checkgraph. for reasons unknown this
+ # is not contanied within simplify_graph
+ removenoops.remove_same_as(graph)
# a crash in the following checkgraph() means that you forgot
# to list some variable in greens=[] or reds=[] in JitDriver,
# or that a jit_merge_point() takes a constant as an argument.
diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -88,6 +88,13 @@
list(it)
assert repr(it) == "repeat('foobar', 0)"
+ def test_repeat_len(self):
+ import itertools
+
+ r = itertools.repeat('a', 15)
+ r.next()
+ raises(TypeError, "len(itertools.repeat('xkcd'))")
+
def test_takewhile(self):
import itertools
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -4,7 +4,7 @@
"""
from pypy.interpreter.baseobjspace import W_Root
-from pypy.objspace.std.dictmultiobject import IteratorImplementation
+from pypy.objspace.std.dictmultiobject import create_iterator_classes
from pypy.objspace.std.dictmultiobject import DictStrategy, _never_equal_to_string
from pypy.objspace.std.dictmultiobject import ObjectDictStrategy
from pypy.rlib import jit, rerased
@@ -124,9 +124,6 @@
w_res = self.getdictvalue_no_unwrapping(w_dict, key)
return unwrap_cell(w_res)
- def iter(self, w_dict):
- return ModuleDictIteratorImplementation(self.space, self, w_dict)
-
def w_keys(self, w_dict):
space = self.space
l = self.unerase(w_dict.dstorage).keys()
@@ -161,15 +158,15 @@
w_dict.strategy = strategy
w_dict.dstorage = strategy.erase(d_new)
-class ModuleDictIteratorImplementation(IteratorImplementation):
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(
- self, space, strategy, dictimplementation)
- dict_w = strategy.unerase(dictimplementation.dstorage)
- self.iterator = dict_w.iteritems()
+ def getiterkeys(self, w_dict):
+ return self.unerase(w_dict.dstorage).iterkeys()
+ def getitervalues(self, w_dict):
+ return self.unerase(w_dict.dstorage).itervalues()
+ def getiteritems(self, w_dict):
+ return self.unerase(w_dict.dstorage).iteritems()
+ def wrapkey(space, key):
+ return space.wrap(key)
+ def wrapvalue(space, value):
+ return unwrap_cell(value)
- def next_entry(self):
- for key, cell in self.iterator:
- return (self.space.wrap(key), unwrap_cell(cell))
- else:
- return None, None
+create_iterator_classes(ModuleDictStrategy)
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -7,8 +7,10 @@
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize
+from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize,\
+ newlist_hint
from pypy.rlib.debug import mark_dict_non_null
+from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib import rerased
from pypy.rlib import jit
@@ -110,7 +112,7 @@
dict_methods = "setitem setitem_str getitem \
getitem_str delitem length \
clear w_keys values \
- items iter setdefault \
+ items iterkeys itervalues iteritems setdefault \
popitem listview_str listview_int".split()
def make_method(method):
@@ -119,6 +121,9 @@
f.func_name = method
return f
+ def view_as_kwargs(self):
+ return self.strategy.view_as_kwargs(self)
+
for method in dict_methods:
setattr(W_DictMultiObject, method, make_method(method))
@@ -133,30 +138,30 @@
raise NotImplementedError
def w_keys(self, w_dict):
- iterator = self.iter(w_dict)
- result = []
+ iterator = self.iterkeys(w_dict)
+ result = newlist_hint(self.length(w_dict))
while 1:
- w_key, w_value = iterator.next()
+ w_key = iterator.next_key()
if w_key is not None:
result.append(w_key)
else:
return self.space.newlist(result)
def values(self, w_dict):
- iterator = self.iter(w_dict)
- result = []
+ iterator = self.itervalues(w_dict)
+ result = newlist_hint(self.length(w_dict))
while 1:
- w_key, w_value = iterator.next()
+ w_value = iterator.next_value()
if w_value is not None:
result.append(w_value)
else:
return result
def items(self, w_dict):
- iterator = self.iter(w_dict)
- result = []
+ iterator = self.iteritems(w_dict)
+ result = newlist_hint(self.length(w_dict))
while 1:
- w_key, w_value = iterator.next()
+ w_key, w_value = iterator.next_item()
if w_key is not None:
result.append(self.space.newtuple([w_key, w_value]))
else:
@@ -168,8 +173,8 @@
# will take longer and longer. But all interesting strategies
# provide a better one.
space = self.space
- iterator = self.iter(w_dict)
- w_key, w_value = iterator.next()
+ iterator = self.iteritems(w_dict)
+ w_key, w_value = iterator.next_item()
self.delitem(w_dict, w_key)
return (w_key, w_value)
@@ -268,9 +273,6 @@
def length(self, w_dict):
return 0
- def iter(self, w_dict):
- return EmptyIteratorImplementation(self.space, self, w_dict)
-
def clear(self, w_dict):
return
@@ -280,31 +282,32 @@
def view_as_kwargs(self, w_dict):
return ([], [])
-registerimplementation(W_DictMultiObject)
+ # ---------- iterator interface ----------------
-# DictImplementation lattice
-# XXX fix me
+ def getiterkeys(self, w_dict):
+ return iter([None])
+ getitervalues = getiterkeys
+ def getiteritems(self, w_dict):
+ return iter([(None, None)])
# Iterator Implementation base classes
-class IteratorImplementation(object):
- def __init__(self, space, strategy, implementation):
- self.space = space
- self.strategy = strategy
- self.dictimplementation = implementation
- self.len = implementation.length()
- self.pos = 0
-
+def _new_next(TP):
+ if TP == 'key' or TP == 'value':
+ EMPTY = None
+ else:
+ EMPTY = None, None
+
def next(self):
if self.dictimplementation is None:
- return None, None
+ return EMPTY
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()
+ result = getattr(self, 'next_' + TP + '_entry')()
self.pos += 1
if self.strategy is self.dictimplementation.strategy:
return result # common case
@@ -313,6 +316,8 @@
# length of the dict. The (key, value) pair in 'result'
# might be out-of-date. We try to explicitly look up
# the key in the dict.
+ if TP == 'key' or TP == 'value':
+ return result
w_key = result[0]
w_value = self.dictimplementation.getitem(w_key)
if w_value is None:
@@ -322,22 +327,96 @@
return (w_key, w_value)
# no more entries
self.dictimplementation = None
- return None, None
+ return EMPTY
+ return func_with_new_name(next, 'next_' + TP)
- def next_entry(self):
- """ Purely abstract method
- """
- raise NotImplementedError
+class BaseIteratorImplementation(object):
+ def __init__(self, space, strategy, implementation):
+ self.space = space
+ self.strategy = strategy
+ self.dictimplementation = implementation
+ self.len = implementation.length()
+ self.pos = 0
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 BaseKeyIterator(BaseIteratorImplementation):
+ next_key = _new_next('key')
+class BaseValueIterator(BaseIteratorImplementation):
+ next_value = _new_next('value')
+
+class BaseItemIterator(BaseIteratorImplementation):
+ next_item = _new_next('item')
+
+def create_iterator_classes(dictimpl, override_next_item=None):
+ if not hasattr(dictimpl, 'wrapkey'):
+ wrapkey = lambda space, key : key
+ else:
+ wrapkey = dictimpl.wrapkey.im_func
+ if not hasattr(dictimpl, 'wrapvalue'):
+ wrapvalue = lambda space, key : key
+ else:
+ wrapvalue = dictimpl.wrapvalue.im_func
+
+ class IterClassKeys(BaseKeyIterator):
+ def __init__(self, space, strategy, impl):
+ self.iterator = strategy.getiterkeys(impl)
+ BaseIteratorImplementation.__init__(self, space, strategy, impl)
+
+ def next_key_entry(self):
+ for key in self.iterator:
+ return wrapkey(self.space, key)
+ else:
+ return None
+
+ class IterClassValues(BaseValueIterator):
+ def __init__(self, space, strategy, impl):
+ self.iterator = strategy.getitervalues(impl)
+ BaseIteratorImplementation.__init__(self, space, strategy, impl)
+
+ def next_value_entry(self):
+ for value in self.iterator:
+ return wrapvalue(self.space, value)
+ else:
+ return None
+
+ class IterClassItems(BaseItemIterator):
+ def __init__(self, space, strategy, impl):
+ self.iterator = strategy.getiteritems(impl)
+ BaseIteratorImplementation.__init__(self, space, strategy, impl)
+
+ if override_next_item is not None:
+ next_item_entry = override_next_item
+ else:
+ def next_item_entry(self):
+ for key, value in self.iterator:
+ return (wrapkey(self.space, key),
+ wrapvalue(self.space, value))
+ else:
+ return None, None
+
+ def iterkeys(self, w_dict):
+ return IterClassKeys(self.space, self, w_dict)
+
+ def itervalues(self, w_dict):
+ return IterClassValues(self.space, self, w_dict)
+
+ def iteritems(self, w_dict):
+ return IterClassItems(self.space, self, w_dict)
+ dictimpl.iterkeys = iterkeys
+ dictimpl.itervalues = itervalues
+ dictimpl.iteritems = iteritems
+
+create_iterator_classes(EmptyDictStrategy)
+
+registerimplementation(W_DictMultiObject)
+
+# DictImplementation lattice
+# XXX fix me
# concrete subclasses of the above
@@ -444,6 +523,15 @@
w_dict.strategy = strategy
w_dict.dstorage = strategy.erase(d_new)
+ # --------------- iterator interface -----------------
+
+ def getiterkeys(self, w_dict):
+ return self.unerase(w_dict.dstorage).iterkeys()
+ def getitervalues(self, w_dict):
+ return self.unerase(w_dict.dstorage).itervalues()
+ def getiteritems(self, w_dict):
+ return self.unerase(w_dict.dstorage).iteritems()
+
class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
erase, unerase = rerased.new_erasing_pair("object")
@@ -467,12 +555,10 @@
def _never_equal_to(self, w_lookup_type):
return False
- def iter(self, w_dict):
- return ObjectIteratorImplementation(self.space, self, w_dict)
-
def w_keys(self, w_dict):
return self.space.newlist(self.unerase(w_dict.dstorage).keys())
+create_iterator_classes(ObjectDictStrategy)
class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
@@ -517,12 +603,12 @@
def listview_str(self, w_dict):
return self.unerase(w_dict.dstorage).keys()
- def iter(self, w_dict):
- return StrIteratorImplementation(self.space, self, w_dict)
-
def w_keys(self, w_dict):
return self.space.newlist_str(self.listview_str(w_dict))
+ def wrapkey(space, key):
+ return space.wrap(key)
+
@jit.look_inside_iff(lambda self, w_dict:
w_dict_unrolling_heuristic(w_dict))
def view_as_kwargs(self, w_dict):
@@ -536,37 +622,8 @@
i += 1
return keys, values
-class _WrappedIteratorMixin(object):
- _mixin_ = True
+create_iterator_classes(StringDictStrategy)
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(self, space, strategy, dictimplementation)
- self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
-
- def next_entry(self):
- # note that this 'for' loop only runs once, at most
- for key, w_value in self.iterator:
- return self.space.wrap(key), w_value
- else:
- return None, None
-
-class _UnwrappedIteratorMixin:
- _mixin_ = True
-
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(self, space, strategy, dictimplementation)
- self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
-
- def next_entry(self):
- # note that this 'for' loop only runs once, at most
- for w_key, w_value in self.iterator:
- return w_key, w_value
- else:
- return None, None
-
-
-class StrIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
- pass
class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
erase, unerase = rerased.new_erasing_pair("int")
@@ -594,19 +651,15 @@
space.is_w(w_lookup_type, space.w_unicode)
)
- def iter(self, w_dict):
- return IntIteratorImplementation(self.space, self, w_dict)
-
def listview_int(self, w_dict):
return self.unerase(w_dict.dstorage).keys()
+ def wrapkey(space, key):
+ return space.wrap(key)
+
# XXX there is no space.newlist_int yet to implement w_keys more efficiently
-class IntIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
- pass
-
-class ObjectIteratorImplementation(_UnwrappedIteratorMixin, IteratorImplementation):
- pass
+create_iterator_classes(IntDictStrategy)
init_signature = Signature(['seq_or_map'], None, 'kwargs')
init_defaults = [None]
@@ -632,9 +685,9 @@
w_dict.setitem(w_key, w_value)
def update1_dict_dict(space, w_dict, w_data):
- iterator = w_data.iter()
+ iterator = w_data.iteritems()
while 1:
- w_key, w_value = iterator.next()
+ w_key, w_value = iterator.next_item()
if w_key is None:
break
w_dict.setitem(w_key, w_value)
@@ -684,7 +737,7 @@
dict_has_key__DictMulti_ANY = contains__DictMulti_ANY
def iter__DictMulti(space, w_dict):
- return W_DictMultiIterObject(space, w_dict.iter(), KEYSITER)
+ return W_DictMultiIterKeysObject(space, w_dict.iterkeys())
def eq__DictMulti_DictMulti(space, w_left, w_right):
if space.is_w(w_left, w_right):
@@ -692,9 +745,9 @@
if w_left.length() != w_right.length():
return space.w_False
- iteratorimplementation = w_left.iter()
+ iteratorimplementation = w_left.iteritems()
while 1:
- w_key, w_val = iteratorimplementation.next()
+ w_key, w_val = iteratorimplementation.next_item()
if w_key is None:
break
w_rightval = w_right.getitem(w_key)
@@ -709,9 +762,9 @@
returns the smallest key in acontent for which b's value is different or absent and this value """
w_smallest_diff_a_key = None
w_its_value = None
- iteratorimplementation = w_a.iter()
+ iteratorimplementation = w_a.iteritems()
while 1:
- w_key, w_val = iteratorimplementation.next()
+ w_key, w_val = iteratorimplementation.next_item()
if w_key is None:
break
if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)):
@@ -762,13 +815,13 @@
return space.newlist(w_self.values())
def dict_iteritems__DictMulti(space, w_self):
- return W_DictMultiIterObject(space, w_self.iter(), ITEMSITER)
+ return W_DictMultiIterItemsObject(space, w_self.iteritems())
def dict_iterkeys__DictMulti(space, w_self):
- return W_DictMultiIterObject(space, w_self.iter(), KEYSITER)
+ return W_DictMultiIterKeysObject(space, w_self.iterkeys())
def dict_itervalues__DictMulti(space, w_self):
- return W_DictMultiIterObject(space, w_self.iter(), VALUESITER)
+ return W_DictMultiIterValuesObject(space, w_self.itervalues())
def dict_viewitems__DictMulti(space, w_self):
return W_DictViewItemsObject(space, w_self)
@@ -821,38 +874,73 @@
# Iteration
-KEYSITER = 0
-ITEMSITER = 1
-VALUESITER = 2
-
-class W_DictMultiIterObject(W_Object):
+class W_DictMultiIterKeysObject(W_Object):
from pypy.objspace.std.dicttype import dictiter_typedef as typedef
- _immutable_fields_ = ["iteratorimplementation", "itertype"]
+ _immutable_fields_ = ["iteratorimplementation"]
- def __init__(w_self, space, iteratorimplementation, itertype):
+ ignore_for_isinstance_cache = True
+
+ def __init__(w_self, space, iteratorimplementation):
w_self.space = space
w_self.iteratorimplementation = iteratorimplementation
- w_self.itertype = itertype
-registerimplementation(W_DictMultiIterObject)
+registerimplementation(W_DictMultiIterKeysObject)
-def iter__DictMultiIterObject(space, w_dictiter):
+class W_DictMultiIterValuesObject(W_Object):
+ from pypy.objspace.std.dicttype import dictiter_typedef as typedef
+
+ _immutable_fields_ = ["iteratorimplementation"]
+
+ ignore_for_isinstance_cache = True
+
+ def __init__(w_self, space, iteratorimplementation):
+ w_self.space = space
+ w_self.iteratorimplementation = iteratorimplementation
+
+registerimplementation(W_DictMultiIterValuesObject)
+
+class W_DictMultiIterItemsObject(W_Object):
+ from pypy.objspace.std.dicttype import dictiter_typedef as typedef
+
+ _immutable_fields_ = ["iteratorimplementation"]
+
+ ignore_for_isinstance_cache = True
+
+ def __init__(w_self, space, iteratorimplementation):
+ w_self.space = space
+ w_self.iteratorimplementation = iteratorimplementation
+
+registerimplementation(W_DictMultiIterItemsObject)
+
+def iter__DictMultiIterKeysObject(space, w_dictiter):
return w_dictiter
-def next__DictMultiIterObject(space, w_dictiter):
+def next__DictMultiIterKeysObject(space, w_dictiter):
iteratorimplementation = w_dictiter.iteratorimplementation
- w_key, w_value = iteratorimplementation.next()
+ w_key = iteratorimplementation.next_key()
if w_key is not None:
- itertype = w_dictiter.itertype
- if itertype == KEYSITER:
- return w_key
- elif itertype == VALUESITER:
- return w_value
- elif itertype == ITEMSITER:
- return space.newtuple([w_key, w_value])
- else:
- assert 0, "should be unreachable"
+ return w_key
+ raise OperationError(space.w_StopIteration, space.w_None)
+
+def iter__DictMultiIterValuesObject(space, w_dictiter):
+ return w_dictiter
+
+def next__DictMultiIterValuesObject(space, w_dictiter):
+ iteratorimplementation = w_dictiter.iteratorimplementation
+ w_value = iteratorimplementation.next_value()
+ if w_value is not None:
+ return w_value
+ raise OperationError(space.w_StopIteration, space.w_None)
+
+def iter__DictMultiIterItemsObject(space, w_dictiter):
+ return w_dictiter
+
+def next__DictMultiIterItemsObject(space, w_dictiter):
+ iteratorimplementation = w_dictiter.iteratorimplementation
+ w_key, w_value = iteratorimplementation.next_item()
+ if w_key is not None:
+ return space.newtuple([w_key, w_value])
raise OperationError(space.w_StopIteration, space.w_None)
# ____________________________________________________________
@@ -887,7 +975,6 @@
def all_contained_in(space, w_dictview, w_otherview):
w_iter = space.iter(w_dictview)
- assert isinstance(w_iter, W_DictMultiIterObject)
while True:
try:
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -1,6 +1,6 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject, IteratorImplementation
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject, create_iterator_classes
from pypy.objspace.std.dictmultiobject import DictStrategy
from pypy.objspace.std.typeobject import unwrap_cell
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -81,9 +81,6 @@
def length(self, w_dict):
return len(self.unerase(w_dict.dstorage).dict_w)
- def iter(self, w_dict):
- return DictProxyIteratorImplementation(self.space, self, w_dict)
-
def keys(self, w_dict):
space = self.space
return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys())
@@ -106,15 +103,15 @@
w_type.dict_w.clear()
w_type.mutated(None)
-class DictProxyIteratorImplementation(IteratorImplementation):
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(
- self, space, strategy, dictimplementation)
- w_type = strategy.unerase(dictimplementation.dstorage)
- self.iterator = w_type.dict_w.iteritems()
+ def getiterkeys(self, w_dict):
+ return self.unerase(w_dict.dstorage).dict_w.iterkeys()
+ def getitervalues(self, w_dict):
+ return self.unerase(w_dict.dstorage).dict_w.itervalues()
+ def getiteritems(self, w_dict):
+ return self.unerase(w_dict.dstorage).dict_w.iteritems()
+ def wrapkey(space, key):
+ return space.wrap(key)
+ def wrapvalue(space, value):
+ return unwrap_cell(space, value)
- def next_entry(self):
- for key, w_value in self.iterator:
- return (self.space.wrap(key), unwrap_cell(self.space, w_value))
- else:
- return (None, None)
+create_iterator_classes(DictProxyStrategy)
diff --git a/pypy/objspace/std/identitydict.py b/pypy/objspace/std/identitydict.py
--- a/pypy/objspace/std/identitydict.py
+++ b/pypy/objspace/std/identitydict.py
@@ -5,8 +5,7 @@
from pypy.rlib.debug import mark_dict_non_null
from pypy.objspace.std.dictmultiobject import (AbstractTypedStrategy,
DictStrategy,
- IteratorImplementation,
- _UnwrappedIteratorMixin)
+ create_iterator_classes)
# this strategy is selected by EmptyDictStrategy.switch_to_correct_strategy
@@ -77,12 +76,7 @@
def _never_equal_to(self, w_lookup_type):
return False
- def iter(self, w_dict):
- return IdentityDictIteratorImplementation(self.space, self, w_dict)
-
def w_keys(self, w_dict):
return self.space.newlist(self.unerase(w_dict.dstorage).keys())
-
-class IdentityDictIteratorImplementation(_UnwrappedIteratorMixin, IteratorImplementation):
- pass
+create_iterator_classes(IdentityDictStrategy)
diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py
--- a/pypy/objspace/std/kwargsdict.py
+++ b/pypy/objspace/std/kwargsdict.py
@@ -3,8 +3,8 @@
from pypy.rlib import rerased, jit
from pypy.objspace.std.dictmultiobject import (DictStrategy,
+ create_iterator_classes,
EmptyDictStrategy,
- IteratorImplementation,
ObjectDictStrategy,
StringDictStrategy)
@@ -39,9 +39,6 @@
def _never_equal_to(self, w_lookup_type):
return False
- def iter(self, w_dict):
- return KwargsDictIterator(self.space, self, w_dict)
-
def w_keys(self, w_dict):
return self.space.newlist([self.space.wrap(key) for key in self.unerase(w_dict.dstorage)[0]])
@@ -157,19 +154,24 @@
keys, values_w = self.unerase(w_dict.dstorage)
return keys[:], values_w[:] # copy to make non-resizable
+ def getiterkeys(self, w_dict):
+ return iter(self.unerase(w_dict.dstorage)[0])
+ def getitervalues(self, w_dict):
+ return iter(self.unerase(w_dict.dstorage)[1])
+ def getiteritems(self, w_dict):
+ keys = self.unerase(w_dict.dstorage)[0]
+ return iter(range(len(keys)))
+ def wrapkey(space, key):
+ return space.wrap(key)
-class KwargsDictIterator(IteratorImplementation):
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(self, space, strategy, dictimplementation)
- keys, values_w = strategy.unerase(self.dictimplementation.dstorage)
- self.iterator = iter(range(len(keys)))
- # XXX this potentially leaks
- self.keys = keys
- self.values_w = values_w
+def next_item(self):
+ strategy = self.strategy
+ assert isinstance(strategy, KwargsDictStrategy)
+ for i in self.iterator:
+ keys, values_w = strategy.unerase(
+ self.dictimplementation.dstorage)
+ return self.space.wrap(keys[i]), values_w[i]
+ else:
+ return None, None
- def next_entry(self):
- # note that this 'for' loop only runs once, at most
- for i in self.iterator:
- return self.space.wrap(self.keys[i]), self.values_w[i]
- else:
- return None, None
+create_iterator_classes(KwargsDictStrategy, override_next_item=next_item)
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -5,7 +5,7 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.objspace.std.dictmultiobject import W_DictMultiObject, DictStrategy, ObjectDictStrategy
-from pypy.objspace.std.dictmultiobject import IteratorImplementation
+from pypy.objspace.std.dictmultiobject import BaseKeyIterator, BaseValueIterator, BaseItemIterator
from pypy.objspace.std.dictmultiobject import _never_equal_to_string
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.objspace.std.typeobject import TypeCell
@@ -676,9 +676,6 @@
res += 1
return res
- def iter(self, w_dict):
- return MapDictIteratorImplementation(self.space, self, w_dict)
-
def clear(self, w_dict):
w_obj = self.unerase(w_dict.dstorage)
new_obj = w_obj._get_mapdict_map().remove_dict_entries(w_obj)
@@ -696,32 +693,83 @@
# XXX could implement a more efficient w_keys based on space.newlist_str
+ def iterkeys(self, w_dict):
+ return MapDictIteratorKeys(self.space, self, w_dict)
+ def itervalues(self, w_dict):
+ return MapDictIteratorValues(self.space, self, w_dict)
+ def iteritems(self, w_dict):
+ return MapDictIteratorItems(self.space, self, w_dict)
+
+
def materialize_r_dict(space, obj, dict_w):
map = obj._get_mapdict_map()
new_obj = map.materialize_r_dict(space, obj, dict_w)
_become(obj, new_obj)
-class MapDictIteratorImplementation(IteratorImplementation):
- def __init__(self, space, strategy, dictimplementation):
- IteratorImplementation.__init__(
- self, space, strategy, dictimplementation)
- w_obj = strategy.unerase(dictimplementation.dstorage)
- self.w_obj = w_obj
- self.orig_map = self.curr_map = w_obj._get_mapdict_map()
+class MapDictIteratorKeys(BaseKeyIterator):
+ def __init__(self, space, strategy, dictimplementation):
+ BaseKeyIterator.__init__(
+ self, space, strategy, dictimplementation)
+ w_obj = strategy.unerase(dictimplementation.dstorage)
+ self.w_obj = w_obj
+ self.orig_map = self.curr_map = w_obj._get_mapdict_map()
- def next_entry(self):
- implementation = self.dictimplementation
- assert isinstance(implementation.strategy, MapDictStrategy)
- if self.orig_map is not self.w_obj._get_mapdict_map():
- return None, None
- if self.curr_map:
- curr_map = self.curr_map.search(DICT)
- if curr_map:
- self.curr_map = curr_map.back
- attr = curr_map.selector[0]
- w_attr = self.space.wrap(attr)
- return w_attr, self.w_obj.getdictvalue(self.space, attr)
- return None, None
+ def next_key_entry(self):
+ implementation = self.dictimplementation
+ assert isinstance(implementation.strategy, MapDictStrategy)
+ if self.orig_map is not self.w_obj._get_mapdict_map():
+ return None
+ if self.curr_map:
+ curr_map = self.curr_map.search(DICT)
+ if curr_map:
+ self.curr_map = curr_map.back
+ attr = curr_map.selector[0]
+ w_attr = self.space.wrap(attr)
+ return w_attr
+ return None
+
+class MapDictIteratorValues(BaseValueIterator):
+ def __init__(self, space, strategy, dictimplementation):
+ BaseValueIterator.__init__(
+ self, space, strategy, dictimplementation)
+ w_obj = strategy.unerase(dictimplementation.dstorage)
+ self.w_obj = w_obj
+ self.orig_map = self.curr_map = w_obj._get_mapdict_map()
+
+ def next_value_entry(self):
+ implementation = self.dictimplementation
+ assert isinstance(implementation.strategy, MapDictStrategy)
+ if self.orig_map is not self.w_obj._get_mapdict_map():
+ return None
+ if self.curr_map:
+ curr_map = self.curr_map.search(DICT)
+ if curr_map:
+ self.curr_map = curr_map.back
+ attr = curr_map.selector[0]
+ return self.w_obj.getdictvalue(self.space, attr)
+ return None
+
+class MapDictIteratorItems(BaseItemIterator):
+ def __init__(self, space, strategy, dictimplementation):
+ BaseItemIterator.__init__(
+ self, space, strategy, dictimplementation)
+ w_obj = strategy.unerase(dictimplementation.dstorage)
+ self.w_obj = w_obj
+ self.orig_map = self.curr_map = w_obj._get_mapdict_map()
+
+ def next_item_entry(self):
+ implementation = self.dictimplementation
+ assert isinstance(implementation.strategy, MapDictStrategy)
+ if self.orig_map is not self.w_obj._get_mapdict_map():
+ return None, None
+ if self.curr_map:
+ curr_map = self.curr_map.search(DICT)
+ if curr_map:
+ self.curr_map = curr_map.back
+ attr = curr_map.selector[0]
+ w_attr = self.space.wrap(attr)
+ return w_attr, self.w_obj.getdictvalue(self.space, attr)
+ return None, None
# ____________________________________________________________
# Magic caching
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -102,7 +102,9 @@
tupleobject.W_TupleObject: [],
listobject.W_ListObject: [],
dictmultiobject.W_DictMultiObject: [],
- dictmultiobject.W_DictMultiIterObject: [],
+ dictmultiobject.W_DictMultiIterKeysObject: [],
+ dictmultiobject.W_DictMultiIterValuesObject: [],
+ dictmultiobject.W_DictMultiIterItemsObject: [],
stringobject.W_StringObject: [],
bytearrayobject.W_BytearrayObject: [],
typeobject.W_TypeObject: [],
@@ -128,7 +130,9 @@
self.imported_but_not_registered = {
dictmultiobject.W_DictMultiObject: True, # XXXXXX
- dictmultiobject.W_DictMultiIterObject: True,
+ dictmultiobject.W_DictMultiIterKeysObject: True,
+ dictmultiobject.W_DictMultiIterValuesObject: True,
+ dictmultiobject.W_DictMultiIterItemsObject: True,
listobject.W_ListObject: True,
stringobject.W_StringObject: True,
tupleobject.W_TupleObject: True,
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -454,6 +454,8 @@
class E(dict):
pass
assert isinstance(D.fromkeys([1, 2]), E)
+ assert dict.fromkeys({"a": 2, "b": 3}) == {"a": None, "b": None}
+ assert dict.fromkeys({"a": 2, 1: 3}) == {"a": None, 1: None}
def test_str_uses_repr(self):
class D(dict):
@@ -1038,10 +1040,10 @@
def test_iter(self):
self.fill_impl()
- iteratorimplementation = self.impl.iter()
+ iteratorimplementation = self.impl.iteritems()
items = []
while 1:
- item = iteratorimplementation.next()
+ item = iteratorimplementation.next_item()
if item == (None, None):
break
items.append(item)
diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py
--- a/pypy/objspace/std/test/test_kwargsdict.py
+++ b/pypy/objspace/std/test/test_kwargsdict.py
@@ -141,3 +141,9 @@
d = f()
assert "EmptyKwargsDictStrategy" in self.get_strategy(d)
+ def test_iterator(self):
+ def f(**args):
+ return args
+
+ assert dict.fromkeys(f(a=2, b=3)) == {"a": None, "b": None}
+ assert sorted(f(a=2, b=3).itervalues()) == [2, 3]
diff --git a/pypy/rpython/lltypesystem/rbuilder.py b/pypy/rpython/lltypesystem/rbuilder.py
--- a/pypy/rpython/lltypesystem/rbuilder.py
+++ b/pypy/rpython/lltypesystem/rbuilder.py
@@ -59,7 +59,7 @@
@classmethod
def ll_new(cls, init_size):
- if init_size < 0 or init_size > MAX:
+ if init_size < 0:
init_size = MAX
ll_builder = lltype.malloc(cls.lowleveltype.TO)
ll_builder.allocated = init_size
More information about the pypy-commit
mailing list