Unverified implementation for __getattr__
This commit is contained in:
parent
6f51f7b841
commit
5568665ad6
2
object.h
2
object.h
@ -136,6 +136,8 @@ typedef struct KrkClass {
|
||||
KrkObj * _exit;
|
||||
KrkObj * _delitem;
|
||||
KrkObj * _iter;
|
||||
KrkObj * _getattr;
|
||||
KrkObj * _dir;
|
||||
} KrkClass;
|
||||
|
||||
typedef struct KrkInstance {
|
||||
|
24
test/testGetattrDir.krk
Normal file
24
test/testGetattrDir.krk
Normal file
@ -0,0 +1,24 @@
|
||||
class Foo():
|
||||
def __getattr__(name):
|
||||
if name in self._dict:
|
||||
return self._dict[name]
|
||||
else:
|
||||
raise AttributeError(name)
|
||||
def __init__():
|
||||
self._dict = {'foo': 1, 'bar': 42}
|
||||
|
||||
let f = Foo()
|
||||
print(f)
|
||||
print(dir(f))
|
||||
print(f.foo)
|
||||
|
||||
class Bar(object):
|
||||
def __dir__(self):
|
||||
let out = super().__dir__()
|
||||
out.append("butts")
|
||||
return out
|
||||
|
||||
let b = Bar()
|
||||
print(dir(b))
|
||||
try:
|
||||
b.butts
|
4
test/testGetattrDir.krk.expect
Normal file
4
test/testGetattrDir.krk.expect
Normal file
@ -0,0 +1,4 @@
|
||||
<instance of Foo at 0x55e8a79995b0>
|
||||
['__class__', '__str__', '__init__', '__dir__', '__repr__', '__getattr__', '_dict']
|
||||
1
|
||||
['__class__', '__str__', '__dir__', '__repr__', 'butts']
|
25
vm.c
25
vm.c
@ -303,6 +303,8 @@ void krk_finalizeClass(KrkClass * _class) {
|
||||
{&_class->_exit, METHOD_EXIT},
|
||||
{&_class->_delitem, METHOD_DELITEM},
|
||||
{&_class->_iter, METHOD_ITER},
|
||||
{&_class->_getattr, METHOD_GETATTR},
|
||||
{&_class->_dir, METHOD_DIR},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
@ -2682,6 +2684,19 @@ static KrkValue _len(int argc, KrkValue argv[]) {
|
||||
return krk_callSimple(OBJECT_VAL(type->_len), 1, 0);
|
||||
}
|
||||
|
||||
static KrkValue _dir(int argc, KrkValue argv[]) {
|
||||
if (argc != 1) {
|
||||
krk_runtimeError(vm.exceptions.argumentError, "dir() takes exactly one argument");
|
||||
return NONE_VAL();
|
||||
}
|
||||
KrkClass * type = AS_CLASS(krk_typeOf(1,&argv[0]));
|
||||
if (!type->_dir) {
|
||||
return krk_dirObject(argc,argv); /* Fallback */
|
||||
}
|
||||
krk_push(argv[0]);
|
||||
return krk_callSimple(OBJECT_VAL(type->_dir), 1, 0);
|
||||
}
|
||||
|
||||
static KrkValue _repr(int argc, KrkValue argv[]) {
|
||||
if (argc != 1) {
|
||||
krk_runtimeError(vm.exceptions.argumentError, "repr() takes exactly one argument");
|
||||
@ -3105,6 +3120,8 @@ void krk_initVM(int flags) {
|
||||
vm.specialMethodNames[METHOD_EXIT] = OBJECT_VAL(S("__exit__"));
|
||||
vm.specialMethodNames[METHOD_DELITEM] = OBJECT_VAL(S("__delitem__")); /* delitem */
|
||||
vm.specialMethodNames[METHOD_ITER] = OBJECT_VAL(S("__iter__"));
|
||||
vm.specialMethodNames[METHOD_GETATTR] = OBJECT_VAL(S("__getattr__"));
|
||||
vm.specialMethodNames[METHOD_DIR] = OBJECT_VAL(S("__dir__"));
|
||||
|
||||
/* Create built-in class `object` */
|
||||
vm.objectClass = krk_newClass(S("object"));
|
||||
@ -3276,7 +3293,7 @@ void krk_initVM(int flags) {
|
||||
BUILTIN_FUNCTION("dictOf", krk_dict_of); /* Equivalent to dict() */
|
||||
BUILTIN_FUNCTION("isinstance", krk_isinstance);
|
||||
BUILTIN_FUNCTION("globals", krk_globals);
|
||||
BUILTIN_FUNCTION("dir", krk_dirObject);
|
||||
BUILTIN_FUNCTION("dir", _dir);
|
||||
BUILTIN_FUNCTION("len", _len);
|
||||
BUILTIN_FUNCTION("repr", _repr);
|
||||
BUILTIN_FUNCTION("print", _print);
|
||||
@ -3709,6 +3726,12 @@ static int valueGetProperty(KrkString * name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (objectClass->_getattr) {
|
||||
krk_push(OBJECT_VAL(name));
|
||||
krk_push(krk_callSimple(OBJECT_VAL(objectClass->_getattr), 2, 0));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user