mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
fix a bug of super
This commit is contained in:
parent
34d09da688
commit
c7935564c3
@ -60,7 +60,7 @@ static bool stack_format_object(VM* self, c11_sv spec);
|
|||||||
case RES_RETURN: PUSH(&self->last_retval); break; \
|
case RES_RETURN: PUSH(&self->last_retval); break; \
|
||||||
case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME; \
|
case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME; \
|
||||||
case RES_ERROR: goto __ERROR; \
|
case RES_ERROR: goto __ERROR; \
|
||||||
default: c11__unreachable(); \
|
default: c11__unreachable(); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
@ -974,8 +974,13 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
case OP_STORE_CLASS_ATTR: {
|
case OP_STORE_CLASS_ATTR: {
|
||||||
assert(self->__curr_class);
|
assert(self->__curr_class);
|
||||||
py_Name name = byte.arg;
|
py_Name name = byte.arg;
|
||||||
if(py_istype(TOP(), tp_function)) {
|
// TOP() can be a function, classmethod or custom decorator
|
||||||
Function* ud = py_touserdata(TOP());
|
py_Ref actual_func = TOP();
|
||||||
|
if(actual_func->type == tp_classmethod) {
|
||||||
|
actual_func = py_getslot(actual_func, 0);
|
||||||
|
}
|
||||||
|
if(actual_func->type == tp_function) {
|
||||||
|
Function* ud = py_touserdata(actual_func);
|
||||||
ud->clazz = self->__curr_class->_obj;
|
ud->clazz = self->__curr_class->_obj;
|
||||||
}
|
}
|
||||||
py_setdict(self->__curr_class, name, TOP());
|
py_setdict(self->__curr_class, name, TOP());
|
||||||
|
@ -763,9 +763,15 @@ static bool super__new__(int argc, py_Ref argv) {
|
|||||||
if(argc == 1) {
|
if(argc == 1) {
|
||||||
// super()
|
// super()
|
||||||
if(frame->has_function) {
|
if(frame->has_function) {
|
||||||
Function* func = py_touserdata(frame->p0);
|
py_TValue* callable = frame->p0;
|
||||||
*class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
if(callable->type == tp_boundmethod) callable = py_getslot(frame->p0, 1);
|
||||||
if(frame->co->nlocals > 0) self_arg = &frame->locals[0];
|
if(callable->type == tp_function) {
|
||||||
|
Function* func = py_touserdata(callable);
|
||||||
|
if(func->clazz != NULL) {
|
||||||
|
*class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
||||||
|
if(frame->co->nlocals > 0) self_arg = &frame->locals[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(class_arg == 0 || self_arg == NULL) return RuntimeError("super(): no arguments");
|
if(class_arg == 0 || self_arg == NULL) return RuntimeError("super(): no arguments");
|
||||||
} else if(argc == 3) {
|
} else if(argc == 3) {
|
||||||
|
@ -154,3 +154,17 @@ assert B.static_method(123) == 123
|
|||||||
assert B.class_method('123') == 'B123'
|
assert B.class_method('123') == 'B123'
|
||||||
assert B().static_method(123) == 123
|
assert B().static_method(123) == 123
|
||||||
assert B().class_method('123') == 'B123'
|
assert B().class_method('123') == 'B123'
|
||||||
|
|
||||||
|
# test super() with classmethod
|
||||||
|
class BaseClass:
|
||||||
|
@classmethod
|
||||||
|
def f(cls):
|
||||||
|
return 'BaseClass'
|
||||||
|
|
||||||
|
class DerivedClass(BaseClass):
|
||||||
|
@classmethod
|
||||||
|
def f(cls):
|
||||||
|
return super().f()
|
||||||
|
|
||||||
|
|
||||||
|
assert DerivedClass.f() == 'BaseClass'
|
Loading…
x
Reference in New Issue
Block a user