summaryrefslogtreecommitdiffstatshomepage
path: root/py/runtime.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-01-11 19:22:29 +0000
committerDamien George <damien.p.george@gmail.com>2014-01-11 19:22:29 +0000
commiteae16445d5f6ca4bcd693422fc93ccf4fd7e215e (patch)
treec07206dcad354d366c1a42d6fa81d6a1868de2e1 /py/runtime.c
parentbcbeea0a477ed977a668e67f6f5402260d26ceb9 (diff)
downloadmicropython-eae16445d5f6ca4bcd693422fc93ccf4fd7e215e.tar.gz
micropython-eae16445d5f6ca4bcd693422fc93ccf4fd7e215e.zip
py: Implement staticmethod and classmethod (internally).
Still need to make built-ins by these names, and write tests.
Diffstat (limited to 'py/runtime.c')
-rw-r--r--py/runtime.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/py/runtime.c b/py/runtime.c
index 29571a44b8..409d1d8262 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -774,12 +774,25 @@ void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
dest[0] = base;
} else {
// generic method lookup
+ // this is a lookup in the object (ie not class or type)
const mp_method_t *meth = type->methods;
if (meth != NULL) {
for (; meth->name != NULL; meth++) {
if (strcmp(meth->name, qstr_str(attr)) == 0) {
- dest[1] = (mp_obj_t)meth->fun;
- dest[0] = base;
+ // check if the methods are functions, static or class methods
+ // see http://docs.python.org/3.3/howto/descriptor.html
+ if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_staticmethod)) {
+ // return just the function
+ dest[1] = ((mp_obj_staticmethod_t*)meth->fun)->fun;
+ } else if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_classmethod)) {
+ // return a bound method, with self being the type of this object
+ dest[1] = ((mp_obj_classmethod_t*)meth->fun)->fun;
+ dest[0] = mp_obj_get_type(base);
+ } else {
+ // return a bound method, with self being this object
+ dest[1] = (mp_obj_t)meth->fun;
+ dest[0] = base;
+ }
break;
}
}