Commit 551d806b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Handle cases that dictiter.next is called directly

(pickle does this)

attrwrapper.iteritems also need to return an iterator (previously, a list)
since pickle calls next on those directly as well.
parent b7c66d3b
......@@ -60,6 +60,9 @@ Box* dictIterNext(Box* s) {
assert(s->cls == dict_iterator_cls);
BoxedDictIterator* self = static_cast<BoxedDictIterator*>(s);
if (self->it == self->itEnd)
raiseExcHelper(StopIteration, "");
Box* rtn = nullptr;
if (self->type == BoxedDictIterator::KeyIterator) {
rtn = self->it->first;
......
......@@ -1498,6 +1498,21 @@ public:
return rtn;
}
static Box* iterkeys(Box* _self) {
Box* r = AttrWrapper::keys(_self);
return getiter(r);
}
static Box* itervalues(Box* _self) {
Box* r = AttrWrapper::values(_self);
return getiter(r);
}
static Box* iteritems(Box* _self) {
Box* r = AttrWrapper::items(_self);
return getiter(r);
}
static Box* copy(Box* _self) {
RELEASE_ASSERT(_self->cls == attrwrapper_cls, "");
AttrWrapper* self = static_cast<AttrWrapper*>(_self);
......@@ -2496,10 +2511,10 @@ void setupRuntime() {
attrwrapper_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)AttrWrapper::keys, LIST, 1)));
attrwrapper_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)AttrWrapper::values, LIST, 1)));
attrwrapper_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)AttrWrapper::items, LIST, 1)));
// TODO: not quite right
attrwrapper_cls->giveAttr("iterkeys", attrwrapper_cls->getattr("keys"));
attrwrapper_cls->giveAttr("itervalues", attrwrapper_cls->getattr("values"));
attrwrapper_cls->giveAttr("iteritems", attrwrapper_cls->getattr("items"));
attrwrapper_cls->giveAttr("iterkeys", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iterkeys, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("itervalues",
new BoxedFunction(boxRTFunction((void*)AttrWrapper::itervalues, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("iteritems", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iteritems, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)AttrWrapper::copy, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::len, BOXED_INT, 1)));
attrwrapper_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iter, UNKNOWN, 1)));
......
......@@ -219,3 +219,14 @@ for i in xrange(6):
d1[i] = 5 - i
d2[5 - i] = i
print d1 == d2, d1 != d2
d = dict([(i, i**2) for i in xrange(10)])
i = d.iteritems()
l = []
while True:
try:
l.append(i.next())
except StopIteration:
break
print sorted(l)
......@@ -114,3 +114,12 @@ print sorted([d for d in dir(TestClass3()) if not d.startswith('_')])
c = C1()
c.__dict__.update([('a', 1), ('b', 2)])
print c.a, c.b
i = c.__dict__.iteritems()
l = []
while True:
try:
l.append(i.next())
except StopIteration:
break
print sorted(l)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment