Răsfoiți Sursa

`TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'`

blueloveTH 2 ani în urmă
părinte
comite
de41c27cfa
3 a modificat fișierele cu 25 adăugiri și 20 ștergeri
  1. 6 1
      include/pocketpy/vm.h
  2. 17 17
      src/ceval.cpp
  3. 2 2
      tests/80_linalg.py

+ 6 - 1
include/pocketpy/vm.h

@@ -343,9 +343,14 @@ public:
     void NameError(StrName name){ _builtin_error("NameError", fmt("name ", name.escape() + " is not defined")); }
     void UnboundLocalError(StrName name){ _builtin_error("UnboundLocalError", fmt("local variable ", name.escape() + " referenced before assignment")); }
     void KeyError(PyObject* obj){ _builtin_error("KeyError", obj); }
-    void BinaryOptError(const char* op) { TypeError(fmt("unsupported operand type(s) for ", op)); }
     void ImportError(const Str& msg){ _builtin_error("ImportError", msg); }
 
+    void BinaryOptError(const char* op, PyObject* _0, PyObject* _1) {
+        StrName name_0 = _type_name(vm, _tp(_0));
+        StrName name_1 = _type_name(vm, _tp(_1));
+        TypeError(fmt("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
+    }
+
     void AttributeError(PyObject* obj, StrName name){
         if(isinstance(obj, vm->tp_type)){
             _builtin_error("AttributeError", fmt("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));

+ 17 - 17
src/ceval.cpp

@@ -17,8 +17,8 @@ namespace pkpy{
             PyObject* self;                                                     \
             PyObject* _2 = get_unbound_method(_1, rfunc, &self, false);         \
             if(_2 != nullptr) ret = call_method(self, _2, _0);                  \
-            else BinaryOptError(op);                                            \
-            if(ret == NotImplemented) BinaryOptError(op);                       \
+            else BinaryOptError(op, _0, _1);                                    \
+            if(ret == NotImplemented) BinaryOptError(op, _0, _1);               \
         }
 
 
@@ -44,9 +44,9 @@ bool VM::py_ge(PyObject* _0, PyObject* _1){
 
 #undef BINARY_F_COMPARE
 
-static i64 _py_sint(PyObject* obj) noexcept {
-    return (i64)(PK_BITS(obj) >> 2);
-}
+// static i64 _py_sint(PyObject* obj) noexcept {
+//     return (i64)(PK_BITS(obj) >> 2);
+// }
 
 PyObject* VM::_run_top_frame(){
     FrameId frame = top_frame();
@@ -388,19 +388,19 @@ __NEXT_STEP:;
             PyObject* self;                                         \
             PyObject* _2 = get_unbound_method(_1, func, &self, false);        \
             if(_2 != nullptr) TOP() = call_method(self, _2, _0);    \
-            else BinaryOptError(op);                                \
-            if(TOP() == NotImplemented) BinaryOptError(op);         \
+            else BinaryOptError(op, _0, _1);                        \
+            if(TOP() == NotImplemented) BinaryOptError(op, _0, _1); \
         }
 
     TARGET(BINARY_TRUEDIV){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__truediv__);
-        if(TOP() == NotImplemented) BinaryOptError("/");
+        if(TOP() == NotImplemented) BinaryOptError("/", _0, _1);
     } DISPATCH();
     TARGET(BINARY_POW){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__pow__);
-        if(TOP() == NotImplemented) BinaryOptError("**");
+        if(TOP() == NotImplemented) BinaryOptError("**", _0, _1);
     } DISPATCH();
     TARGET(BINARY_ADD){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
@@ -420,12 +420,12 @@ __NEXT_STEP:;
     TARGET(BINARY_FLOORDIV){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__floordiv__);
-        if(TOP() == NotImplemented) BinaryOptError("//");
+        if(TOP() == NotImplemented) BinaryOptError("//", _0, _1);
     } DISPATCH()
     TARGET(BINARY_MOD){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__mod__);
-        if(TOP() == NotImplemented) BinaryOptError("%");
+        if(TOP() == NotImplemented) BinaryOptError("%", _0, _1);
     } DISPATCH()
     TARGET(COMPARE_LT){
         PyObject* _1 = POPX();
@@ -460,32 +460,32 @@ __NEXT_STEP:;
     TARGET(BITWISE_LSHIFT){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__lshift__);
-        if(TOP() == NotImplemented) BinaryOptError("<<");
+        if(TOP() == NotImplemented) BinaryOptError("<<", _0, _1);
     } DISPATCH()
     TARGET(BITWISE_RSHIFT){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__rshift__);
-        if(TOP() == NotImplemented) BinaryOptError(">>");
+        if(TOP() == NotImplemented) BinaryOptError(">>", _0, _1);
     } DISPATCH()
     TARGET(BITWISE_AND){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__and__);
-        if(TOP() == NotImplemented) BinaryOptError("&");
+        if(TOP() == NotImplemented) BinaryOptError("&", _0, _1);
     } DISPATCH()
     TARGET(BITWISE_OR){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__or__);
-        if(TOP() == NotImplemented) BinaryOptError("|");
+        if(TOP() == NotImplemented) BinaryOptError("|", _0, _1);
     } DISPATCH()
     TARGET(BITWISE_XOR){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__xor__);
-        if(TOP() == NotImplemented) BinaryOptError("^");
+        if(TOP() == NotImplemented) BinaryOptError("^", _0, _1);
     } DISPATCH()
     TARGET(BINARY_MATMUL){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__matmul__);
-        if(TOP() == NotImplemented) BinaryOptError("@");
+        if(TOP() == NotImplemented) BinaryOptError("@", _0, _1);
     } DISPATCH();
 
 #undef BINARY_OP_SPECIAL

+ 2 - 2
tests/80_linalg.py

@@ -337,8 +337,8 @@ test_mat_copy = test_mat.copy()
 test_mat_copy @ vec3(83,-9.12, 0.2983)
 try:
     test_mat_copy @ 12345
-    raise Exception('未能拦截错误 BinaryOptError("@") 在处理表达式 test_mat_copy @ 12345')
-except:
+    exit(1)
+except TypeError:
     pass