add __delattr__

This commit is contained in:
blueloveTH 2024-01-16 16:38:01 +08:00
parent 0b98c7b0bf
commit 2cd93de8be
5 changed files with 19 additions and 1 deletions

View File

@ -67,6 +67,18 @@ struct PyLuaTable: PyLuaObject{
)
};
ti->m__delattr__ = [](VM* vm, PyObject* obj, StrName name){
const PyLuaTable& self = _CAST(PyLuaTable&, obj);
LUA_PROTECTED(
lua_rawgeti(_L, LUA_REGISTRYINDEX, self.r);
lua_pushstring(_L, std::string(name.sv()).c_str());
lua_pushnil(_L);
lua_settable(_L, -3);
lua_pop(_L, 1);
)
return true;
};
vm->bind_constructor<1>(type, [](VM* vm, ArgsView args){
lua_newtable(_L); // push an empty table onto the stack
PyObject* obj = vm->heap.gcnew<PyLuaTable>(PK_OBJ_GET(Type, args[0]));

View File

@ -48,8 +48,10 @@ class Table:
def __getitem__(self, key): ...
def __setitem__(self, key, value): ...
def __delitem__(self, key): ...
def __getattr__(self, key): ...
def __setattr__(self, key, value): ...
def __delattr__(self, key): ...
```
Only basic types can be passed between python and lua.

View File

@ -40,4 +40,4 @@ The easiest way to test a feature is to [try it on your browser](https://pocketp
9. A `Tab` is equivalent to 4 spaces. You can mix `Tab` and spaces in indentation, but it is not recommended.
10. `%`, `&`, `//`, `^` and `|` for `int` behave the same as C, not python.
11. `str.split` and `str.splitlines` will remove all empty entries.
12. `__getattr__` and `__setattr__` can only be set in cpp.
12. `__getattr__`, `__setattr__` and `__delattr__` can only be set in cpp.

View File

@ -100,6 +100,8 @@ struct PyTypeInfo{
// attributes
void (*m__setattr__)(VM* vm, PyObject*, StrName, PyObject*) = nullptr;
PyObject* (*m__getattr__)(VM* vm, PyObject*, StrName) = nullptr;
bool (*m__delattr__)(VM* vm, PyObject*, StrName) = nullptr;
};
struct FrameId{

View File

@ -983,6 +983,8 @@ __FAST_CALL:
}
void VM::delattr(PyObject *_0, StrName _name){
const PyTypeInfo* ti = _inst_type_info(_0);
if(ti->m__delattr__ && ti->m__delattr__(this, _0, _name)) return;
if(is_tagged(_0) || !_0->is_attr_valid()) TypeError("cannot delete attribute");
if(!_0->attr().del(_name)) AttributeError(_0, _name);
}