blueloveTH 2 年 前
コミット
5ecd59f11c
6 ファイル変更28 行追加4 行削除
  1. 1 0
      include/pocketpy/vm.h
  2. 1 2
      src/ceval.cpp
  3. 5 0
      src/pocketpy.cpp
  4. 5 0
      src/vm.cpp
  5. 14 0
      tests/07_dict.py
  6. 2 2
      tests/80_linalg.py

+ 1 - 0
include/pocketpy/vm.h

@@ -449,6 +449,7 @@ public:
     Str disassemble(CodeObject_ co);
     void init_builtin_types();
     PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
+    void delattr(PyObject* obj, StrName name);
     PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
     void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step);
     PyObject* format(Str, PyObject*);

+ 1 - 2
src/ceval.cpp

@@ -220,8 +220,7 @@ __NEXT_STEP:;
     TARGET(DELETE_ATTR)
         _0 = POPX();
         _name = StrName(byte.arg);
-        if(is_tagged(_0) || !_0->is_attr_valid()) TypeError("cannot delete attribute");
-        if(!_0->attr().del(_name)) AttributeError(_0, _name);
+        delattr(_0, _name);
         DISPATCH();
     TARGET(DELETE_SUBSCR)
         _1 = POPX();

+ 5 - 0
src/pocketpy.cpp

@@ -309,6 +309,11 @@ void init_builtins(VM* _vm) {
         return vm->getattr(args[0], name);
     });
 
+    _vm->bind_builtin_func<2>("delattr", [](VM* vm, ArgsView args) {
+        vm->delattr(args[0], CAST(Str&, args[1]));
+        return vm->None;
+    });
+
     _vm->bind_builtin_func<1>("hex", [](VM* vm, ArgsView args) {
         std::stringstream ss;
         ss << std::hex << CAST(i64, args[0]);

+ 5 - 0
src/vm.cpp

@@ -915,6 +915,11 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
     return nullptr;
 }
 
+void VM::delattr(PyObject *_0, StrName _name){
+    if(is_tagged(_0) || !_0->is_attr_valid()) TypeError("cannot delete attribute");
+    if(!_0->attr().del(_name)) AttributeError(_0, _name);
+}
+
 // https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance
 PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){
     PyObject* objtype;

+ 14 - 0
tests/07_dict.py

@@ -113,6 +113,7 @@ for i in range(2, 1000):
 a = {'0': 0, '1': 1}
 b = ['0', '1']
 
+# dict delete test
 data = []
 j = 6
 for i in range(65535):
@@ -127,6 +128,19 @@ for i in range(len(data)):
         y = b.pop()
         del a[y]
 
+# namedict delete test
+class A: pass
+a = A()
+b = ['0', '1']
+
+for i in range(len(data)):
+    z = data[i]
+    setattr(a, str(z), i)
+    b.append(z)
+    if i % 3 == 0:
+        y = b.pop()
+        delattr(a, y)
+
 a = {1: 2, 3: 4}
 assert a.pop(1) == 2
 try:

+ 2 - 2
tests/80_linalg.py

@@ -60,12 +60,12 @@ assert str(static_test_vec3_float) == 'vec3(3.1887, -1.0984e+06, 9)'
 assert str(static_test_vec3_int) == 'vec3(278, -1.39197e+13, 1.36422e+15)'
 
 # test __getnewargs__
-element_name_list = [e for e in dir(test_vec3) if e in 'x,y,z,w']
+element_name_list = ['x', 'y', 'z']
 element_value_list = [getattr(test_vec3, attr) for attr in element_name_list]
 assert tuple(element_value_list) == test_vec3.__getnewargs__()
 
 # test copy
-element_name_list = [e for e in dir(test_vec3) if e in 'x,y,z,w']
+element_name_list = ['x', 'y', 'z']
 element_value_list = [getattr(test_vec3, attr) for attr in element_name_list]
 copy_element_value_list = [getattr(test_vec3.copy(), attr) for attr in element_name_list]
 assert element_value_list == copy_element_value_list