Skip to content
Snippets Groups Projects
Commit 195de324 authored by Paul Sokolovsky's avatar Paul Sokolovsky
Browse files

objtype: Fix passing of class param to inherited classmethods.

This is getting more and more tangled, but that's old news.
parent 639863d3
No related branches found
No related tags found
No related merge requests found
...@@ -103,6 +103,7 @@ struct class_lookup_data { ...@@ -103,6 +103,7 @@ struct class_lookup_data {
qstr attr; qstr attr;
machine_uint_t meth_offset; machine_uint_t meth_offset;
mp_obj_t *dest; mp_obj_t *dest;
bool is_type;
}; };
STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_type_t *type) { STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_type_t *type) {
...@@ -128,18 +129,28 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_ ...@@ -128,18 +129,28 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(lookup->attr), MP_MAP_LOOKUP); mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(lookup->attr), MP_MAP_LOOKUP);
if (elem != NULL) { if (elem != NULL) {
lookup->dest[0] = elem->value; lookup->dest[0] = elem->value;
if (lookup->obj != MP_OBJ_NULL && is_native_type(type)) { if (lookup->is_type) {
// If we look up class method, we need to pass original type there,
// not type where we found a class method.
const mp_obj_type_t *org_type = (const mp_obj_type_t*)lookup->obj;
instance_convert_return_attr(NULL, org_type, elem->value, lookup->dest);
} else if (lookup->obj != MP_OBJ_NULL && !lookup->is_type && is_native_type(type)) {
instance_convert_return_attr(lookup->obj->subobj[0], type, elem->value, lookup->dest); instance_convert_return_attr(lookup->obj->subobj[0], type, elem->value, lookup->dest);
} else { } else {
instance_convert_return_attr(lookup->obj, type, elem->value, lookup->dest); instance_convert_return_attr(lookup->obj, type, elem->value, lookup->dest);
} }
#if DEBUG_PRINT
printf("mp_obj_class_lookup: Returning: ");
mp_obj_print(lookup->dest[0], PRINT_REPR); printf(" ");
mp_obj_print(lookup->dest[1], PRINT_REPR); printf("\n");
#endif
return; return;
} }
} }
// Try this for completeness, but all native methods should be statically defined // Try this for completeness, but all native methods should be statically defined
// in locals_dict, and would be handled by above. // in locals_dict, and would be handled by above.
if (lookup->obj != MP_OBJ_NULL && is_native_type(type)) { if (lookup->obj != MP_OBJ_NULL && !lookup->is_type && is_native_type(type)) {
mp_load_method_maybe(lookup->obj->subobj[0], lookup->attr, lookup->dest); mp_load_method_maybe(lookup->obj->subobj[0], lookup->attr, lookup->dest);
if (lookup->dest[0] != MP_OBJ_NULL) { if (lookup->dest[0] != MP_OBJ_NULL) {
return; return;
...@@ -672,10 +683,11 @@ STATIC void type_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { ...@@ -672,10 +683,11 @@ STATIC void type_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
} }
#endif #endif
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = NULL, .obj = self_in,
.attr = attr, .attr = attr,
.meth_offset = 0, .meth_offset = 0,
.dest = dest, .dest = dest,
.is_type = true,
}; };
mp_obj_class_lookup(&lookup, self); mp_obj_class_lookup(&lookup, self);
} }
......
# Calling an inherited classmethod
class Base:
@classmethod
def foo(cls):
print(cls.__name__)
class Sub(Base):
pass
Sub.foo()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment