소스 검색

fix error of "A() takes no arguments"

blueloveTH 2 달 전
부모
커밋
6cad72453b
2개의 변경된 파일29개의 추가작업 그리고 1개의 파일을 삭제
  1. 8 0
      src/interpreter/vm.c
  2. 21 1
      tests/400_class.py

+ 8 - 0
src/interpreter/vm.c

@@ -580,6 +580,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
         // [cls, NULL, args..., kwargs...]
         // [cls, NULL, args..., kwargs...]
         py_Ref new_f = py_tpfindmagic(py_totype(p0), __new__);
         py_Ref new_f = py_tpfindmagic(py_totype(p0), __new__);
         assert(new_f && py_isnil(p0 + 1));
         assert(new_f && py_isnil(p0 + 1));
+        bool is_default_new = new_f->type == tp_nativefunc && new_f->_cfunc == pk__object_new;
 
 
         // prepare a copy of args and kwargs
         // prepare a copy of args and kwargs
         int span = self->stack.sp - argv;
         int span = self->stack.sp - argv;
@@ -603,6 +604,13 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
             // [__init__, self, args..., kwargs...]
             // [__init__, self, args..., kwargs...]
             if(VM__vectorcall(self, argc, kwargc, false) == RES_ERROR) return RES_ERROR;
             if(VM__vectorcall(self, argc, kwargc, false) == RES_ERROR) return RES_ERROR;
             *py_retval() = p0[1];  // restore the new instance
             *py_retval() = p0[1];  // restore the new instance
+        } else {
+            if(is_default_new) {
+                if(argc != 0 || kwargc != 0) {
+                    TypeError("%t() takes no arguments", p0->type);
+                    return RES_ERROR;
+                }
+            }
         }
         }
         // reset the stack
         // reset the stack
         self->stack.sp = p0;
         self->stack.sp = p0;

+ 21 - 1
tests/400_class.py

@@ -135,4 +135,24 @@ assert MyClass.b == 1
 assert MyClass.c == 2
 assert MyClass.c == 2
 assert MyClass.d == 3
 assert MyClass.d == 3
 
 
-assert MyClass(1, 2).m == 1
+assert MyClass(1, 2).m == 1
+
+class E: pass
+try:
+    E(1,2,3)
+    exit(1)
+except TypeError:
+    pass
+
+class E1:
+    def __new__(cls, a, b):
+        o = object.__new__(cls)
+        o.a = a
+        o.b = b
+        return o
+
+    def sum(self):
+        return self.a + self.b
+
+e1 = E1(3,4)
+assert e1.sum() == 7