mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
fix super()
This commit is contained in:
parent
c7935564c3
commit
72e88892e5
@ -7,7 +7,7 @@ class TValue[T]:
|
|||||||
@property
|
@property
|
||||||
def value(self) -> T: ...
|
def value(self) -> T: ...
|
||||||
|
|
||||||
TValue_int = TValue[int]
|
# TValue_int = TValue[int]
|
||||||
TValue_float = TValue[float]
|
# TValue_float = TValue[float]
|
||||||
TValue_vec2i = TValue[vec2i]
|
# TValue_vec2i = TValue[vec2i]
|
||||||
TValue_vec2 = TValue[vec2]
|
# TValue_vec2 = TValue[vec2]
|
||||||
|
@ -167,9 +167,6 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
|
|||||||
if(py_istype(self, tp_type)) {
|
if(py_istype(self, tp_type)) {
|
||||||
// T.__new__(...)
|
// T.__new__(...)
|
||||||
type = py_totype(self);
|
type = py_totype(self);
|
||||||
} else if(py_istype(self, tp_super)) {
|
|
||||||
// super().__new__(...)
|
|
||||||
type = *(py_Type*)py_touserdata(self);
|
|
||||||
} else {
|
} else {
|
||||||
// invalid usage of `__new__`
|
// invalid usage of `__new__`
|
||||||
return false;
|
return false;
|
||||||
|
@ -756,9 +756,8 @@ py_Type pk_nativefunc__register() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool super__new__(int argc, py_Ref argv) {
|
static bool super__new__(int argc, py_Ref argv) {
|
||||||
py_Type* class_arg = py_newobject(py_retval(), tp_super, 1, sizeof(py_Type));
|
py_Type class_arg = 0;
|
||||||
Frame* frame = pk_current_vm->top_frame;
|
Frame* frame = pk_current_vm->top_frame;
|
||||||
*class_arg = 0;
|
|
||||||
py_Ref self_arg = NULL;
|
py_Ref self_arg = NULL;
|
||||||
if(argc == 1) {
|
if(argc == 1) {
|
||||||
// super()
|
// super()
|
||||||
@ -768,27 +767,36 @@ static bool super__new__(int argc, py_Ref argv) {
|
|||||||
if(callable->type == tp_function) {
|
if(callable->type == tp_function) {
|
||||||
Function* func = py_touserdata(callable);
|
Function* func = py_touserdata(callable);
|
||||||
if(func->clazz != NULL) {
|
if(func->clazz != NULL) {
|
||||||
*class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
||||||
if(frame->co->nlocals > 0) self_arg = &frame->locals[0];
|
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");
|
||||||
|
if(self_arg->type == tp_type) {
|
||||||
|
// f(cls, ...)
|
||||||
|
class_arg = pk__type_info(class_arg)->base;
|
||||||
|
if(class_arg == 0) return RuntimeError("super(): base class is invalid");
|
||||||
|
py_assign(py_retval(), py_tpobject(class_arg));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else if(argc == 3) {
|
} else if(argc == 3) {
|
||||||
// super(type, obj)
|
// super(type[T], obj)
|
||||||
PY_CHECK_ARG_TYPE(1, tp_type);
|
PY_CHECK_ARG_TYPE(1, tp_type);
|
||||||
*class_arg = py_totype(py_arg(1));
|
class_arg = py_totype(py_arg(1));
|
||||||
self_arg = py_arg(2);
|
self_arg = py_arg(2);
|
||||||
if(!py_isinstance(self_arg, *class_arg)) {
|
if(!py_isinstance(self_arg, class_arg)) {
|
||||||
return TypeError("super(type, obj): obj must be an instance of type");
|
return TypeError("super(type, obj): obj must be an instance of type");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return TypeError("super() takes 0 or 2 arguments");
|
return TypeError("super() takes 0 or 2 arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
*class_arg = pk__type_info(*class_arg)->base;
|
class_arg = pk__type_info(class_arg)->base;
|
||||||
if(*class_arg == 0) return RuntimeError("super(): base class is invalid");
|
if(class_arg == 0) return RuntimeError("super(): base class is invalid");
|
||||||
|
|
||||||
|
py_Type* p_class_arg = py_newobject(py_retval(), tp_super, 1, sizeof(py_Type));
|
||||||
|
*p_class_arg = class_arg;
|
||||||
py_setslot(py_retval(), 0, self_arg);
|
py_setslot(py_retval(), 0, self_arg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -87,12 +87,6 @@ int py_next(py_Ref val) {
|
|||||||
bool py_getattr(py_Ref self, py_Name name) {
|
bool py_getattr(py_Ref self, py_Name name) {
|
||||||
// https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance
|
// https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance
|
||||||
py_Type type = self->type;
|
py_Type type = self->type;
|
||||||
// handle super() proxy (disabled)
|
|
||||||
// if(py_istype(self, tp_super)) {
|
|
||||||
// self = py_getslot(self, 0);
|
|
||||||
// type = *(py_Type*)py_touserdata(self);
|
|
||||||
// }
|
|
||||||
|
|
||||||
py_Ref cls_var = py_tpfindname(type, name);
|
py_Ref cls_var = py_tpfindname(type, name);
|
||||||
if(cls_var) {
|
if(cls_var) {
|
||||||
// handle descriptor
|
// handle descriptor
|
||||||
@ -183,12 +177,6 @@ bool py_getattr(py_Ref self, py_Name name) {
|
|||||||
|
|
||||||
bool py_setattr(py_Ref self, py_Name name, py_Ref val) {
|
bool py_setattr(py_Ref self, py_Name name, py_Ref val) {
|
||||||
py_Type type = self->type;
|
py_Type type = self->type;
|
||||||
// handle super() proxy (disabled)
|
|
||||||
// if(py_istype(self, tp_super)) {
|
|
||||||
// self = py_getslot(self, 0);
|
|
||||||
// type = *(py_Type*)py_touserdata(self);
|
|
||||||
// }
|
|
||||||
|
|
||||||
py_Ref cls_var = py_tpfindname(type, name);
|
py_Ref cls_var = py_tpfindname(type, name);
|
||||||
if(cls_var) {
|
if(cls_var) {
|
||||||
// handle descriptor
|
// handle descriptor
|
||||||
|
@ -78,6 +78,7 @@ class Z:
|
|||||||
|
|
||||||
class B(Z):
|
class B(Z):
|
||||||
def __new__(cls, x):
|
def __new__(cls, x):
|
||||||
|
assert super() is Z
|
||||||
return super().__new__(cls, x)
|
return super().__new__(cls, x)
|
||||||
|
|
||||||
assert Z(1) == (Z, 1)
|
assert Z(1) == (Z, 1)
|
||||||
@ -87,6 +88,7 @@ from pkpy import TValue
|
|||||||
|
|
||||||
class fixed(TValue[int]):
|
class fixed(TValue[int]):
|
||||||
def __new__(cls, value: str):
|
def __new__(cls, value: str):
|
||||||
|
assert super() is TValue[int]
|
||||||
return super().__new__(cls, int(value))
|
return super().__new__(cls, int(value))
|
||||||
|
|
||||||
assert fixed('123').value == 123
|
assert fixed('123').value == 123
|
||||||
|
Loading…
x
Reference in New Issue
Block a user