Commit 8f3fb564 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #250 from aisk/dictview

implement viewkeys viewvalues viewitems method on dict object
parents 7023b6fc 7ea200d7
......@@ -90,6 +90,33 @@ Box* dictKeys(BoxedDict* self) {
return rtn;
}
Box* dictViewKeys(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls)) {
raiseExcHelper(TypeError, "descriptor 'viewkeys' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
}
BoxedDictView* rtn = new BoxedDictView(self, dict_keys_cls);
return rtn;
}
Box* dictViewValues(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls)) {
raiseExcHelper(TypeError, "descriptor 'viewvalues' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
}
BoxedDictView* rtn = new BoxedDictView(self, dict_values_cls);
return rtn;
}
Box* dictViewItems(BoxedDict* self) {
if (!isSubclass(self->cls, dict_cls)) {
raiseExcHelper(TypeError, "descriptor 'viewitems' requires a 'dict' object but received a '%s'",
getTypeName(self)->c_str());
}
BoxedDictView* rtn = new BoxedDictView(self, dict_items_cls);
return rtn;
}
Box* dictLen(BoxedDict* self) {
assert(self->cls == dict_cls);
return boxInt(self->d.size());
......@@ -422,9 +449,23 @@ extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) {
v->visit(it->d);
}
BoxedClass* dict_keys_cls = NULL;
BoxedClass* dict_values_cls = NULL;
BoxedClass* dict_items_cls = NULL;
extern "C" void dictViewGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedDictView* view = static_cast<BoxedDictView*>(b);
v->visit(view->d);
}
void setupDict() {
dict_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_keys_cls = new BoxedHeapClass(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_values_cls = new BoxedHeapClass(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_items_cls = new BoxedHeapClass(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false);
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true)));
......@@ -458,6 +499,10 @@ void setupDict() {
dict_cls->giveAttr("popitem", new BoxedFunction(boxRTFunction((void*)dictPopitem, BOXED_TUPLE, 1)));
dict_cls->giveAttr("viewkeys", new BoxedFunction(boxRTFunction((void*)dictViewKeys, UNKNOWN, 1)));
dict_cls->giveAttr("viewvalues", new BoxedFunction(boxRTFunction((void*)dictViewValues, UNKNOWN, 1)));
dict_cls->giveAttr("viewitems", new BoxedFunction(boxRTFunction((void*)dictViewItems, UNKNOWN, 1)));
dict_cls->giveAttr("get", new BoxedFunction(boxRTFunction((void*)dictGet, UNKNOWN, 3, 1, false, false), { None }));
dict_cls->giveAttr("setdefault",
......@@ -482,6 +527,19 @@ void setupDict() {
dict_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)dictIterNext, UNKNOWN, 1)));
dict_iterator_cls->freeze();
dict_keys_cls->giveAttr("__name__", boxStrConstant("dictkeys"));
dict_keys_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictViewKeysIter, typeFromClass(dict_iterator_cls), 1)));
dict_keys_cls->freeze();
dict_values_cls->giveAttr("__name__", boxStrConstant("dictvalues"));
dict_values_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictViewValuesIter, typeFromClass(dict_iterator_cls), 1)));
dict_values_cls->freeze();
dict_items_cls->giveAttr("__name__", boxStrConstant("dictitems"));
dict_items_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictViewItemsIter, typeFromClass(dict_iterator_cls), 1)));
dict_items_cls->freeze();
}
void teardownDict() {
......
......@@ -21,6 +21,9 @@
namespace pyston {
extern BoxedClass* dict_iterator_cls;
extern BoxedClass* dict_keys_cls;
extern BoxedClass* dict_values_cls;
extern BoxedClass* dict_items_cls;
class BoxedDictIterator : public Box {
public:
enum IteratorType { KeyIterator, ValueIterator, ItemIterator };
......@@ -42,6 +45,16 @@ Box* dictIterIter(Box* self);
Box* dictIterHasnext(Box* self);
i1 dictIterHasnextUnboxed(Box* self);
Box* dictIterNext(Box* self);
class BoxedDictView : public Box {
public:
BoxedDict* d;
BoxedDictView(BoxedDict* d, BoxedClass* view_cls);
};
Box* dictViewKeysIter(Box* self);
Box* dictViewValuesIter(Box* self);
Box* dictViewItemsIter(Box* self);
}
#endif
......@@ -71,4 +71,25 @@ Box* dictIterNext(Box* s) {
++self->it;
return rtn;
}
BoxedDictView::BoxedDictView(BoxedDict* d, BoxedClass* view_cls) : Box(view_cls), d(d) {
}
Box* dictViewKeysIter(Box* s) {
assert(s->cls == dict_keys_cls);
BoxedDictView* self = static_cast<BoxedDictView*>(s);
return dictIterKeys(self->d);
}
Box* dictViewValuesIter(Box* s) {
assert(s->cls == dict_values_cls);
BoxedDictView* self = static_cast<BoxedDictView*>(s);
return dictIterValues(self->d);
}
Box* dictViewItemsIter(Box* s) {
assert(s->cls == dict_items_cls);
BoxedDictView* self = static_cast<BoxedDictView*>(s);
return dictIterItems(self->d);
}
}
......@@ -194,3 +194,22 @@ d = {}
d.update({'c':3}, a=1, b=2)
print sorted(d.items())
# viewkeys / viewvalues / viewitems
d = {}
keys = d.keys()
viewkeys = d.viewkeys()
print list(d.viewkeys())
print list(d.viewvalues())
print list(d.viewitems())
print 'keys of d: ', keys
print 'viewkeys of d: ', list(viewkeys)
d['a'] = 1
print list(d.viewkeys())
print list(d.viewvalues())
print list(d.viewitems())
print 'keys of d: ', keys
print 'viewkeys of d: ', list(viewkeys)
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