Commit b90aa69d authored by Vinzenz Feenstra's avatar Vinzenz Feenstra

Additional improvements to the dir implementation

- Added dir0 which would in theory return the local scope, but
  for just returns the content of the builtins module
- Added a unit test file for dir which won't print anything as the
  list sorting does not work as expected at the moment
  (missing full implementation) and the attributes are different
  as well (pyston has some CPython 2.7.5 does not have and vice versa)
- dir1 implements the lookup on a passed object
  - If the object has a __dir__ method, it will call it and return the result
    returned by this method
  - Otherwise all class and instance attributes and methods are returned
  - If the object has a __dict__ attribute, additional to the previous one
    it will return the keys from that one as well
Signed-off-by: default avatarVinzenz Feenstra <evilissimo@gmail.com>
parent 26b7e09d
......@@ -34,10 +34,37 @@ extern "C" Box* trap() {
return None;
}
extern "C" Box * dir(Box* x) {
BoxedList * result = new BoxedList();
if(x->cls->hasattrs) {
HCBox * hcb = static_cast<HCBox*>(x);
extern "C" Box * dir1(Box* obj) {
// TODO: Recursive class traversal for lookup of types and eliminating
// duplicates afterwards
BoxedList * result = nullptr;
if(obj->cls->hasattrs) {
// If __dir__ is present just call it and return what it returns
HCBox * hcb = static_cast<HCBox*>(obj);
Box * obj_dir = hcb->cls->getattr("__dir__", nullptr, nullptr);
if(obj_dir) {
return runtimeCall(obj_dir, 1, obj, nullptr, nullptr, nullptr);
}
// If __dict__ is present use its keys and add the reset below
Box * obj_dict = hcb->cls->getattr("__dict__", nullptr, nullptr);
if(obj_dict) {
result = new BoxedList();
assert(obj_dict->cls == dict_cls);
for(auto & kv : static_cast<BoxedDict*>(obj_dict)->d) {
listAppend(result, kv.first);
}
}
}
if(!result) {
result = new BoxedList();
}
for(auto const & kv : obj->cls->hcls->attr_offsets) {
listAppend(result, boxString(kv.first));
}
if(obj->cls->hasattrs) {
HCBox * hcb = static_cast<HCBox*>(obj);
for(auto const & kv : hcb->hcls->attr_offsets) {
listAppend(result, boxString(kv.first));
}
......@@ -45,6 +72,12 @@ extern "C" Box * dir(Box* x) {
return result;
}
extern "C" Box * dir0() {
// TODO: This should actually return the elements in the current local
// scope not the content of the builtins_module
return dir1(builtins_module);
}
extern "C" Box* abs_(Box* x) {
if (x->cls == int_cls) {
i64 n = static_cast<BoxedInt*>(x)->n;
......@@ -517,8 +550,9 @@ void setupBuiltins() {
builtins_module->giveAttr("map", new BoxedFunction(boxRTFunction((void*)map2, LIST, 2, false)));
builtins_module->giveAttr("zip", new BoxedFunction(boxRTFunction((void*)zip2, LIST, 2, false)));
builtins_module->giveAttr("dir", new BoxedFunction(boxRTFunction((void*)dir, LIST, 1, false)));
CLFunction * dir_clf = boxRTFunction((void*)dir0, LIST, 0, false);
addRTFunction(dir_clf, (void*)dir1, LIST, 1, false);
builtins_module->giveAttr("dir", new BoxedFunction(dir_clf));
builtins_module->giveAttr("object", object_cls);
builtins_module->giveAttr("str", str_cls);
builtins_module->giveAttr("int", int_cls);
......
import sys
__package__ = "Test"
__builtins__ = None
__doc__ = None
def fake():
# manually sorted: ['all', 'these', 'attributes', 'do', 'not', 'exist']
return ['all', 'attributes', 'do', 'exist', 'not', 'these']
class TestClass(object):
def __init__(self):
self.__dict__ = {n: n for n in fake()}
def __dir__(self):
return fake()
class TestClass2(object):
def __init__(self):
self.attribute1 = None
self.__dict__ = {'dictAttr': True}
def method1(self):
pass
# All attributes are different between CPython 2.7.5 and pyston
# CPython has more
dir(sys.modules[__name__])
dir(TestClass())
dir(TestClass2())
dir(str())
dir(list())
dir({})
dir(int())
# dir(long())
dir(dir)
dir(fake)
dir(None)
dir()
dir(TestClass)
dir(TestClass2)
dir(sys)
dir(dict)
dir(int)
dir(str)
dir(set)
tc = TestClass()
for f in dir(tc):
print tc.__dict__[f]
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