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) {
llvm::sys::path::append(stdlib_dir, "2.7");
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
_t.split("to run");
......
......@@ -305,43 +305,82 @@ extern "C" Box* dictNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
return new BoxedDict();
}
extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
int args_sz = args->elts.size();
int kwargs_sz = kwargs->d.size();
void dictMerge(BoxedDict* self, Box* other) {
if (other->cls == dict_cls) {
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
if (args_sz > 1)
raiseExcHelper(TypeError, "dict expected at most 1 arguments, got %d", args_sz);
static const std::string keys_str("keys");
Box* keys = callattr(other, &keys_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = true }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
assert(keys);
// handle positional argument first as iterable
if (args_sz == 1) {
int idx = 0;
for (Box* k : keys->pyElements()) {
self->d[k] = getitem(other, k);
}
}
void dictMergeFromSeq2(BoxedDict* self, Box* other) {
int idx = 0;
// raises if not iterable
for (const auto& element : args->elts[0]->pyElements()) {
// raises if not iterable
for (const auto& element : other->pyElements()) {
// should this check subclasses? anyway to check if something is iterable...
if (element->cls == list_cls) {
BoxedList* list = static_cast<BoxedList*>(element);
if (list->size != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required",
idx, list->size);
// should this check subclasses? anyway to check if something is iterable...
if (element->cls == list_cls) {
BoxedList* list = static_cast<BoxedList*>(element);
if (list->size != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
list->size);
self->d[list->elts->elts[0]] = list->elts->elts[1];
} else if (element->cls == tuple_cls) {
BoxedTuple* tuple = static_cast<BoxedTuple*>(element);
if (tuple->elts.size() != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required",
idx, tuple->elts.size());
self->d[list->elts->elts[0]] = list->elts->elts[1];
} else if (element->cls == tuple_cls) {
BoxedTuple* tuple = static_cast<BoxedTuple*>(element);
if (tuple->elts.size() != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
tuple->elts.size());
self->d[tuple->elts[0]] = tuple->elts[1];
} else
raiseExcHelper(TypeError, "cannot convert dictionary update sequence element #%d to a sequence", idx);
self->d[tuple->elts[0]] = tuple->elts[1];
} else
raiseExcHelper(TypeError, "cannot convert dictionary update sequence element #%d to a sequence", idx);
idx++;
}
}
Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
assert(args->cls == tuple_cls);
assert(kwargs);
assert(kwargs->cls == dict_cls);
idx++;
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)
assert(kwargs->cls == dict_cls);
......@@ -396,6 +435,8 @@ void setupDict() {
dict_cls->giveAttr("__iter__",
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("copy", new BoxedFunction(boxRTFunction((void*)dictCopy, DICT, 1)));
......
......@@ -1841,6 +1841,10 @@ extern "C" void dump(void* p) {
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;
}
......
......@@ -163,3 +163,34 @@ try:
assert 0
except KeyError, e:
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