add py_tpsetfinal

This commit is contained in:
blueloveTH 2025-07-17 11:24:39 +08:00
parent 85885f414f
commit 01f04b2e41
5 changed files with 21 additions and 14 deletions

View File

@ -14,7 +14,7 @@ typedef struct py_TypeInfo {
py_GlobalRef module; py_GlobalRef module;
bool is_python; // is it a python class? (not derived from c object) bool is_python; // is it a python class? (not derived from c object)
bool is_sealed; // can it be subclassed? bool is_final; // can it be subclassed?
bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN; bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN;
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val) PY_RAISE PY_RETURN; bool (*setattribute)(py_Ref self, py_Name name, py_Ref val) PY_RAISE PY_RETURN;
@ -35,7 +35,7 @@ py_Type pk_newtype(const char* name,
const py_GlobalRef module, const py_GlobalRef module,
void (*dtor)(void*), void (*dtor)(void*),
bool is_python, bool is_python,
bool is_sealed); bool is_final);
py_Type pk_newtypewithmode(py_Name name, py_Type pk_newtypewithmode(py_Name name,
@ -43,4 +43,4 @@ py_Type pk_newtypewithmode(py_Name name,
const py_GlobalRef module, const py_GlobalRef module,
void (*dtor)(void*), void (*dtor)(void*),
bool is_python, bool is_python,
bool is_sealed, enum py_CompileMode mode); bool is_final, enum py_CompileMode mode);

View File

@ -370,7 +370,8 @@ PK_API py_GlobalRef py_tpobject(py_Type type);
PK_API const char* py_tpname(py_Type type); PK_API const char* py_tpname(py_Type type);
/// Call a type to create a new instance. /// Call a type to create a new instance.
PK_API bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN; PK_API bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN;
/// Disable the type for subclassing.
PK_API void py_tpsetfinal(py_Type type);
/// Set attribute hooks for the given type. /// Set attribute hooks for the given type.
PK_API void py_tphookattributes(py_Type type, PK_API void py_tphookattributes(py_Type type,
bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN, bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN,

View File

@ -1041,7 +1041,7 @@ __NEXT_STEP:
POP(); POP();
py_TypeInfo* base_ti = pk_typeinfo(base); py_TypeInfo* base_ti = pk_typeinfo(base);
if(base_ti->is_sealed) { if(base_ti->is_final) {
TypeError("type '%t' is not an acceptable base type", base); TypeError("type '%t' is not an acceptable base type", base);
goto __ERROR; goto __ERROR;
} }

View File

@ -61,11 +61,11 @@ static void py_TypeInfo__common_init(py_Name name,
const py_GlobalRef module, const py_GlobalRef module,
void (*dtor)(void*), void (*dtor)(void*),
bool is_python, bool is_python,
bool is_sealed, bool is_final,
py_TypeInfo* self, py_TypeInfo* self,
py_TValue* typeobject) { py_TValue* typeobject) {
py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL; py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL;
if(base_ti && base_ti->is_sealed) { if(base_ti && base_ti->is_final) {
c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name)); c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
} }
@ -79,7 +79,7 @@ static void py_TypeInfo__common_init(py_Name name,
if(!dtor && base) dtor = base_ti->dtor; if(!dtor && base) dtor = base_ti->dtor;
self->is_python = is_python; self->is_python = is_python;
self->is_sealed = is_sealed; self->is_final = is_final;
self->getattribute = NULL; self->getattribute = NULL;
self->setattribute = NULL; self->setattribute = NULL;
@ -96,7 +96,7 @@ py_Type pk_newtype(const char* name,
const py_GlobalRef module, const py_GlobalRef module,
void (*dtor)(void*), void (*dtor)(void*),
bool is_python, bool is_python,
bool is_sealed) { bool is_final) {
py_Type index = pk_current_vm->types.length; py_Type index = pk_current_vm->types.length;
py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo)); py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo));
py_TypeInfo__common_init(py_name(name), py_TypeInfo__common_init(py_name(name),
@ -105,7 +105,7 @@ py_Type pk_newtype(const char* name,
module, module,
dtor, dtor,
is_python, is_python,
is_sealed, is_final,
self, self,
py_retval()); py_retval());
TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types); TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
@ -119,7 +119,7 @@ py_Type pk_newtypewithmode(py_Name name,
const py_GlobalRef module, const py_GlobalRef module,
void (*dtor)(void*), void (*dtor)(void*),
bool is_python, bool is_python,
bool is_sealed, bool is_final,
enum py_CompileMode mode) { enum py_CompileMode mode) {
if(mode == RELOAD_MODE && module != NULL) { if(mode == RELOAD_MODE && module != NULL) {
py_ItemRef old_class = py_getdict(module, name); py_ItemRef old_class = py_getdict(module, name);
@ -137,7 +137,7 @@ py_Type pk_newtypewithmode(py_Name name,
module, module,
dtor, dtor,
is_python, is_python,
is_sealed, is_final,
self, self,
&self->self); &self->self);
TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index); TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
@ -147,7 +147,7 @@ py_Type pk_newtypewithmode(py_Name name,
} }
} }
return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_sealed); return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_final);
} }
py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) { py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
@ -157,6 +157,12 @@ py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, vo
return type; return type;
} }
void py_tpsetfinal(py_Type type) {
assert(type);
py_TypeInfo* ti = pk_typeinfo(type);
ti->is_final = true;
}
void py_tphookattributes(py_Type type, void py_tphookattributes(py_Type type,
bool (*getattribute)(py_Ref self, py_Name name), bool (*getattribute)(py_Ref self, py_Name name),
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val), bool (*setattribute)(py_Ref self, py_Name name, py_Ref val),

View File

@ -16,7 +16,7 @@ static bool Enum__wrapper_field(py_Name name, py_Ref value, void* ctx) {
} }
static void Enum__on_end_subclass(py_TypeInfo* derived_ti) { static void Enum__on_end_subclass(py_TypeInfo* derived_ti) {
derived_ti->is_sealed = true; derived_ti->is_final = true;
py_applydict(&derived_ti->self, Enum__wrapper_field, &derived_ti->self); py_applydict(&derived_ti->self, Enum__wrapper_field, &derived_ti->self);
} }