Commit b9e2852f authored by Kevin Modzelewski's avatar Kevin Modzelewski

dict.update and add _sysconfigdata

parent 516b6544
# TODO: we will have to figure out a better way of generating this file
build_time_vars = {}
...@@ -123,6 +123,12 @@ int main(int argc, char** argv) { ...@@ -123,6 +123,12 @@ int main(int argc, char** argv) {
llvm::sys::path::append(stdlib_dir, "2.7"); llvm::sys::path::append(stdlib_dir, "2.7");
appendToSysPath(stdlib_dir.c_str()); appendToSysPath(stdlib_dir.c_str());
// go from ./lib_python/2.7 to ./lib_pyston
llvm::sys::path::remove_filename(stdlib_dir);
llvm::sys::path::remove_filename(stdlib_dir);
llvm::sys::path::append(stdlib_dir, "lib_pyston");
appendToSysPath(stdlib_dir.c_str());
// end of argument parsing // end of argument parsing
_t.split("to run"); _t.split("to run");
......
...@@ -305,34 +305,42 @@ extern "C" Box* dictNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -305,34 +305,42 @@ extern "C" Box* dictNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
return new BoxedDict(); return new BoxedDict();
} }
extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { void dictMerge(BoxedDict* self, Box* other) {
int args_sz = args->elts.size(); if (other->cls == dict_cls) {
int kwargs_sz = kwargs->d.size(); for (const auto& p : static_cast<BoxedDict*>(other)->d)
self->d[p.first] = p.second;
return;
}
// CPython accepts a single positional and keyword arguments, in any combination static const std::string keys_str("keys");
if (args_sz > 1) Box* keys = callattr(other, &keys_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = true }),
raiseExcHelper(TypeError, "dict expected at most 1 arguments, got %d", args_sz); ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
assert(keys);
// handle positional argument first as iterable for (Box* k : keys->pyElements()) {
if (args_sz == 1) { self->d[k] = getitem(other, k);
}
}
void dictMergeFromSeq2(BoxedDict* self, Box* other) {
int idx = 0; int idx = 0;
// raises if not iterable // raises if not iterable
for (const auto& element : args->elts[0]->pyElements()) { for (const auto& element : other->pyElements()) {
// should this check subclasses? anyway to check if something is iterable... // should this check subclasses? anyway to check if something is iterable...
if (element->cls == list_cls) { if (element->cls == list_cls) {
BoxedList* list = static_cast<BoxedList*>(element); BoxedList* list = static_cast<BoxedList*>(element);
if (list->size != 2) if (list->size != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
idx, list->size); list->size);
self->d[list->elts->elts[0]] = list->elts->elts[1]; self->d[list->elts->elts[0]] = list->elts->elts[1];
} else if (element->cls == tuple_cls) { } else if (element->cls == tuple_cls) {
BoxedTuple* tuple = static_cast<BoxedTuple*>(element); BoxedTuple* tuple = static_cast<BoxedTuple*>(element);
if (tuple->elts.size() != 2) if (tuple->elts.size() != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
idx, tuple->elts.size()); tuple->elts.size());
self->d[tuple->elts[0]] = tuple->elts[1]; self->d[tuple->elts[0]] = tuple->elts[1];
} else } else
...@@ -340,7 +348,38 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -340,7 +348,38 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
idx++; idx++;
} }
}
Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
assert(args->cls == tuple_cls);
assert(kwargs);
assert(kwargs->cls == dict_cls);
RELEASE_ASSERT(args->elts.size() <= 1, ""); // should throw a TypeError
if (args->elts.size()) {
Box* arg = args->elts[0];
if (getattrInternal(arg, "keys", NULL)) {
dictMerge(self, arg);
} else {
dictMergeFromSeq2(self, arg);
} }
}
if (kwargs->d.size())
dictMerge(self, kwargs);
return None;
}
extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
int args_sz = args->elts.size();
int kwargs_sz = kwargs->d.size();
// CPython accepts a single positional and keyword arguments, in any combination
if (args_sz > 1)
raiseExcHelper(TypeError, "dict expected at most 1 arguments, got %d", args_sz);
dictUpdate(self, args, kwargs);
// handle keyword arguments by merging (possibly over positional entries per CPy) // handle keyword arguments by merging (possibly over positional entries per CPy)
assert(kwargs->cls == dict_cls); assert(kwargs->cls == dict_cls);
...@@ -396,6 +435,8 @@ void setupDict() { ...@@ -396,6 +435,8 @@ void setupDict() {
dict_cls->giveAttr("__iter__", dict_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1))); new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1)));
dict_cls->giveAttr("update", new BoxedFunction(boxRTFunction((void*)dictUpdate, NONE, 1, 0, true, true)));
dict_cls->giveAttr("clear", new BoxedFunction(boxRTFunction((void*)dictClear, NONE, 1))); dict_cls->giveAttr("clear", new BoxedFunction(boxRTFunction((void*)dictClear, NONE, 1)));
dict_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)dictCopy, DICT, 1))); dict_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)dictCopy, DICT, 1)));
......
...@@ -1841,6 +1841,10 @@ extern "C" void dump(void* p) { ...@@ -1841,6 +1841,10 @@ extern "C" void dump(void* p) {
printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n); printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n);
} }
if (isSubclass(b->cls, list_cls)) {
printf("%ld elements\n", static_cast<BoxedList*>(b)->size);
}
return; return;
} }
......
...@@ -163,3 +163,34 @@ try: ...@@ -163,3 +163,34 @@ try:
assert 0 assert 0
except KeyError, e: except KeyError, e:
print 'ok' print 'ok'
d = {}
d.update({1:2, 3:4})
print sorted(d.items())
print sorted(dict(d).items())
class CustomMapping(object):
def __init__(self):
self.n = 0
def keys(self):
print "keys()"
return [1, 3, 7]
def __getitem__(self, key):
print key
self.n += 1
return self.n
print sorted(dict(CustomMapping()).items())
cm = CustomMapping()
def custom_keys():
print "custom_keys()"
return [2, 4, 2]
cm.keys = custom_keys
print sorted(dict(cm).items())
d = {}
d.update({'c':3}, a=1, b=2)
print sorted(d.items())
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