blueloveTH há 2 anos atrás
pai
commit
a12eb4c8bc

+ 1 - 1
docs/cheatsheet.md

@@ -231,7 +231,7 @@ Compare two python objects
 ```cpp
 ```cpp
 PyObject* obj1 = py_var(vm, 1);
 PyObject* obj1 = py_var(vm, 1);
 PyObject* obj2 = py_var(vm, 2);
 PyObject* obj2 = py_var(vm, 2);
-bool ok = vm->py_equals(obj1, obj2);
+bool ok = vm->py_eq(obj1, obj2);
 ```
 ```
 
 
 Convert a python object to string
 Convert a python object to string

+ 1 - 1
include/pocketpy/common.h

@@ -23,7 +23,7 @@
 #include <bitset>
 #include <bitset>
 #include <deque>
 #include <deque>
 
 
-#define PK_VERSION				"1.2.7"
+#define PK_VERSION				"1.2.9"
 
 
 #include "config.h"
 #include "config.h"
 #include "export.h"
 #include "export.h"

+ 6 - 1
include/pocketpy/vm.h

@@ -304,7 +304,12 @@ public:
         PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
         PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
     }
     }
 
 
-    bool py_equals(PyObject* lhs, PyObject* rhs);
+    bool py_eq(PyObject* lhs, PyObject* rhs);
+    // new in v1.2.9
+    bool py_lt(PyObject* lhs, PyObject* rhs);
+    bool py_le(PyObject* lhs, PyObject* rhs);
+    bool py_gt(PyObject* lhs, PyObject* rhs);
+    bool py_ge(PyObject* lhs, PyObject* rhs);
 
 
     template<int ARGC>
     template<int ARGC>
     PyObject* bind_func(Str type, Str name, NativeFuncC fn) {
     PyObject* bind_func(Str type, Str name, NativeFuncC fn) {

+ 0 - 32
python/builtins.py

@@ -286,38 +286,6 @@ def __f(self, reverse=False, key=None):
         self.reverse()
         self.reverse()
 list.sort = __f
 list.sort = __f
 
 
-def __f(self, other):
-    for i, j in zip(self, other):
-        if i != j:
-            return i < j
-    return len(self) < len(other)
-tuple.__lt__ = __f
-list.__lt__ = __f
-
-def __f(self, other):
-    for i, j in zip(self, other):
-        if i != j:
-            return i > j
-    return len(self) > len(other)
-tuple.__gt__ = __f
-list.__gt__ = __f
-
-def __f(self, other):
-    for i, j in zip(self, other):
-        if i != j:
-            return i <= j
-    return len(self) <= len(other)
-tuple.__le__ = __f
-list.__le__ = __f
-
-def __f(self, other):
-    for i, j in zip(self, other):
-        if i != j:
-            return i >= j
-    return len(self) >= len(other)
-tuple.__ge__ = __f
-list.__ge__ = __f
-
 type.__repr__ = lambda self: "<class '" + self.__name__ + "'>"
 type.__repr__ = lambda self: "<class '" + self.__name__ + "'>"
 type.__getitem__ = lambda self, *args: self     # for generics
 type.__getitem__ = lambda self, *args: self     # for generics
 
 

+ 56 - 14
src/ceval.cpp

@@ -2,6 +2,48 @@
 
 
 namespace pkpy{
 namespace pkpy{
 
 
+#define BINARY_F_COMPARE(func, op, rfunc)                           \
+        PyObject* ret;                                              \
+        const PyTypeInfo* _ti = _inst_type_info(_0);                \
+        if(_ti->m##func){                               \
+            ret = _ti->m##func(this, _0, _1);           \
+        }else{                                          \
+            PyObject* self;                                                     \
+            PyObject* _2 = get_unbound_method(_0, func, &self, false);          \
+            if(_2 != nullptr) ret = call_method(self, _2, _1);                  \
+            else ret = NotImplemented;                                          \
+        }                                                                       \
+        if(ret == NotImplemented){                                              \
+            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);                       \
+        }
+
+
+bool VM::py_lt(PyObject* _0, PyObject* _1){
+    BINARY_F_COMPARE(__lt__, "<", __gt__);
+    return CAST(bool, ret);
+}
+
+bool VM::py_le(PyObject* _0, PyObject* _1){
+    BINARY_F_COMPARE(__le__, "<=", __ge__);
+    return CAST(bool, ret);
+}
+
+bool VM::py_gt(PyObject* _0, PyObject* _1){
+    BINARY_F_COMPARE(__gt__, ">", __lt__);
+    return CAST(bool, ret);
+}
+
+bool VM::py_ge(PyObject* _0, PyObject* _1){
+    BINARY_F_COMPARE(__ge__, ">=", __le__);
+    return CAST(bool, ret);
+}
+
+#undef BINARY_F_COMPARE
+
 static i64 _py_sint(PyObject* obj) noexcept {
 static i64 _py_sint(PyObject* obj) noexcept {
     return (i64)(PK_BITS(obj) >> 2);
     return (i64)(PK_BITS(obj) >> 2);
 }
 }
@@ -386,34 +428,34 @@ __NEXT_STEP:;
         if(TOP() == NotImplemented) BinaryOptError("%");
         if(TOP() == NotImplemented) BinaryOptError("%");
     } DISPATCH()
     } DISPATCH()
     TARGET(COMPARE_LT){
     TARGET(COMPARE_LT){
-        PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
-        BINARY_OP_SPECIAL(__lt__);
-        BINARY_OP_RSPECIAL("<", __gt__);
+        PyObject* _1 = POPX();
+        PyObject* _0 = TOP();
+        TOP() = VAR(py_lt(_0, _1));
     } DISPATCH()
     } DISPATCH()
     TARGET(COMPARE_LE){
     TARGET(COMPARE_LE){
-        PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
-        BINARY_OP_SPECIAL(__le__);
-        BINARY_OP_RSPECIAL("<=", __ge__);
+        PyObject* _1 = POPX();
+        PyObject* _0 = TOP();
+        TOP() = VAR(py_le(_0, _1));
     } DISPATCH()
     } DISPATCH()
     TARGET(COMPARE_EQ){
     TARGET(COMPARE_EQ){
         PyObject* _1 = POPX();
         PyObject* _1 = POPX();
         PyObject* _0 = TOP();
         PyObject* _0 = TOP();
-        TOP() = VAR(py_equals(_0, _1));
+        TOP() = VAR(py_eq(_0, _1));
     } DISPATCH()
     } DISPATCH()
     TARGET(COMPARE_NE){
     TARGET(COMPARE_NE){
         PyObject* _1 = POPX();
         PyObject* _1 = POPX();
         PyObject* _0 = TOP();
         PyObject* _0 = TOP();
-        TOP() = VAR(!py_equals(_0, _1));
+        TOP() = VAR(!py_eq(_0, _1));
     } DISPATCH()
     } DISPATCH()
     TARGET(COMPARE_GT){
     TARGET(COMPARE_GT){
-        PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
-        BINARY_OP_SPECIAL(__gt__);
-        BINARY_OP_RSPECIAL(">", __lt__);
+        PyObject* _1 = POPX();
+        PyObject* _0 = TOP();
+        TOP() = VAR(py_gt(_0, _1));
     } DISPATCH()
     } DISPATCH()
     TARGET(COMPARE_GE){
     TARGET(COMPARE_GE){
-        PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
-        BINARY_OP_SPECIAL(__ge__);
-        BINARY_OP_RSPECIAL(">=", __le__);
+        PyObject* _1 = POPX();
+        PyObject* _0 = TOP();
+        TOP() = VAR(py_ge(_0, _1));
     } DISPATCH()
     } DISPATCH()
     TARGET(BITWISE_LSHIFT){
     TARGET(BITWISE_LSHIFT){
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;
         PyObject* _0; PyObject* _1; const PyTypeInfo* _ti;

+ 9 - 9
src/collections.cpp

@@ -145,7 +145,7 @@ namespace pkpy
                      if (self.dequeItems.size() != other.dequeItems.size()) // trivial case
                      if (self.dequeItems.size() != other.dequeItems.size()) // trivial case
                          return VAR(false);
                          return VAR(false);
                      for (int i = 0; i < self.dequeItems.size(); i++)
                      for (int i = 0; i < self.dequeItems.size(); i++)
-                         if (!vm->py_equals(self.dequeItems[i], other.dequeItems[i]))
+                         if (!vm->py_eq(self.dequeItems[i], other.dequeItems[i]))
                              return VAR(false);
                              return VAR(false);
                      return VAR(true);
                      return VAR(true);
                  });
                  });
@@ -235,7 +235,7 @@ namespace pkpy
                      int cnt = 0, sz = self.dequeItems.size();
                      int cnt = 0, sz = self.dequeItems.size();
                      for (auto it = self.dequeItems.begin(); it != self.dequeItems.end(); ++it)
                      for (auto it = self.dequeItems.begin(); it != self.dequeItems.end(); ++it)
                      {
                      {
-                         if (vm->py_equals((*it), obj))
+                         if (vm->py_eq((*it), obj))
                              cnt++;
                              cnt++;
                          if (sz != self.dequeItems.size())// mutating the deque during iteration is not allowed
                          if (sz != self.dequeItems.size())// mutating the deque during iteration is not allowed
                              vm->RuntimeError("deque mutated during iteration"); 
                              vm->RuntimeError("deque mutated during iteration"); 
@@ -265,9 +265,9 @@ namespace pkpy
                      PyDeque &self = _CAST(PyDeque &, args[0]);
                      PyDeque &self = _CAST(PyDeque &, args[0]);
                      PyObject *obj = args[1];
                      PyObject *obj = args[1];
                      int start = 0, stop = self.dequeItems.size(); // default values
                      int start = 0, stop = self.dequeItems.size(); // default values
-                     if (!vm->py_equals(args[2], vm->None))
+                     if (!vm->py_eq(args[2], vm->None))
                          start = CAST(int, args[2]);
                          start = CAST(int, args[2]);
-                     if (!vm->py_equals(args[3], vm->None))
+                     if (!vm->py_eq(args[3], vm->None))
                          stop = CAST(int, args[3]);
                          stop = CAST(int, args[3]);
                      int index = self.findIndex(vm, obj, start, stop);
                      int index = self.findIndex(vm, obj, start, stop);
                      if (index != -1)
                      if (index != -1)
@@ -398,7 +398,7 @@ namespace pkpy
     PyDeque::PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen)
     PyDeque::PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen)
     {
     {
 
 
-        if (!vm->py_equals(maxlen, vm->None)) // fix the maxlen first
+        if (!vm->py_eq(maxlen, vm->None)) // fix the maxlen first
         {
         {
             int tmp = CAST(int, maxlen);
             int tmp = CAST(int, maxlen);
             if (tmp < 0)
             if (tmp < 0)
@@ -414,7 +414,7 @@ namespace pkpy
             this->bounded = false;
             this->bounded = false;
             this->maxlen = -1;
             this->maxlen = -1;
         }
         }
-        if (!vm->py_equals(iterable, vm->None))
+        if (!vm->py_eq(iterable, vm->None))
         {
         {
             this->dequeItems.clear();              // clear the deque
             this->dequeItems.clear();              // clear the deque
             auto _lock = vm->heap.gc_scope_lock(); // locking the heap
             auto _lock = vm->heap.gc_scope_lock(); // locking the heap
@@ -467,7 +467,7 @@ namespace pkpy
         int sz = this->dequeItems.size();
         int sz = this->dequeItems.size();
         for (int i = start; i < loopSize; i++)
         for (int i = start; i < loopSize; i++)
         {
         {
-            if (vm->py_equals(this->dequeItems[i], obj))
+            if (vm->py_eq(this->dequeItems[i], obj))
                 return i;
                 return i;
             if (sz != this->dequeItems.size())// mutating the deque during iteration is not allowed
             if (sz != this->dequeItems.size())// mutating the deque during iteration is not allowed
                 vm->RuntimeError("deque mutated during iteration");
                 vm->RuntimeError("deque mutated during iteration");
@@ -479,7 +479,7 @@ namespace pkpy
     /// @param front  if true, pop from the front of the deque
     /// @param front  if true, pop from the front of the deque
     /// @param back if true, pop from the back of the deque
     /// @param back if true, pop from the back of the deque
     /// @param item if front and back is not set, remove the first occurence of item from the deque
     /// @param item if front and back is not set, remove the first occurence of item from the deque
-    /// @param vm is needed for the py_equals
+    /// @param vm is needed for the py_eq
     /// @return PyObject* if front or back is set, this is a pop operation and we return a PyObject*, if front and back are not set, this is a remove operation and we return the removed item or nullptr
     /// @return PyObject* if front or back is set, this is a pop operation and we return a PyObject*, if front and back are not set, this is a remove operation and we return the removed item or nullptr
     PyObject *PyDeque::popObj(bool front, bool back, PyObject *item, VM *vm)
     PyObject *PyDeque::popObj(bool front, bool back, PyObject *item, VM *vm)
     {
     {
@@ -510,7 +510,7 @@ namespace pkpy
             int sz = this->dequeItems.size();
             int sz = this->dequeItems.size();
             for (auto it = this->dequeItems.begin(); it != this->dequeItems.end(); ++it)
             for (auto it = this->dequeItems.begin(); it != this->dequeItems.end(); ++it)
             {
             {
-                bool found = vm->py_equals((*it), item);
+                bool found = vm->py_eq((*it), item);
                 if (sz != this->dequeItems.size()) // mutating the deque during iteration is not allowed
                 if (sz != this->dequeItems.size()) // mutating the deque during iteration is not allowed
                     vm->IndexError("deque mutated during iteration");
                     vm->IndexError("deque mutated during iteration");
                 if (found)
                 if (found)

+ 33 - 9
src/pocketpy.cpp

@@ -736,14 +736,14 @@ void init_builtins(VM* _vm) {
 
 
     _vm->bind__contains__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* item) {
     _vm->bind__contains__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* item) {
         List& self = _CAST(List&, obj);
         List& self = _CAST(List&, obj);
-        for(PyObject* i: self) if(vm->py_equals(i, item)) return vm->True;
+        for(PyObject* i: self) if(vm->py_eq(i, item)) return vm->True;
         return vm->False;
         return vm->False;
     });
     });
 
 
     _vm->bind_method<1>("list", "count", [](VM* vm, ArgsView args) {
     _vm->bind_method<1>("list", "count", [](VM* vm, ArgsView args) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
         int count = 0;
         int count = 0;
-        for(PyObject* i: self) if(vm->py_equals(i, args[1])) count++;
+        for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
         return VAR(count);
         return VAR(count);
     });
     });
 
 
@@ -753,7 +753,7 @@ void init_builtins(VM* _vm) {
         List& b = _CAST(List&, rhs);
         List& b = _CAST(List&, rhs);
         if(a.size() != b.size()) return vm->False;
         if(a.size() != b.size()) return vm->False;
         for(int i=0; i<a.size(); i++){
         for(int i=0; i<a.size(); i++){
-            if(!vm->py_equals(a[i], b[i])) return vm->False;
+            if(!vm->py_eq(a[i], b[i])) return vm->False;
         }
         }
         return vm->True;
         return vm->True;
     });
     });
@@ -762,7 +762,7 @@ void init_builtins(VM* _vm) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
         PyObject* obj = args[1];
         PyObject* obj = args[1];
         for(int i=0; i<self.size(); i++){
         for(int i=0; i<self.size(); i++){
-            if(vm->py_equals(self[i], obj)) return VAR(i);
+            if(vm->py_eq(self[i], obj)) return VAR(i);
         }
         }
         vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
         vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
         return vm->None;
         return vm->None;
@@ -772,7 +772,7 @@ void init_builtins(VM* _vm) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
         PyObject* obj = args[1];
         PyObject* obj = args[1];
         for(int i=0; i<self.size(); i++){
         for(int i=0; i<self.size(); i++){
-            if(vm->py_equals(self[i], obj)){
+            if(vm->py_eq(self[i], obj)){
                 self.erase(i);
                 self.erase(i);
                 return vm->None;
                 return vm->None;
             }
             }
@@ -858,6 +858,30 @@ void init_builtins(VM* _vm) {
 
 
     _vm->bind_method<0>("list", "copy", PK_LAMBDA(VAR(_CAST(List, args[0]))));
     _vm->bind_method<0>("list", "copy", PK_LAMBDA(VAR(_CAST(List, args[0]))));
 
 
+#define BIND_RICH_CMP(name, op, _t, _T)    \
+    _vm->bind__##name##__(_vm->_t, [](VM* vm, PyObject* lhs, PyObject* rhs){        \
+        if(!is_non_tagged_type(rhs, vm->_t)) return vm->NotImplemented;             \
+        auto& a = _CAST(_T&, lhs);                                                  \
+        auto& b = _CAST(_T&, rhs);                                                  \
+        for(int i=0; i<a.size() && i<b.size(); i++){                                \
+            if(vm->py_eq(a[i], b[i])) continue;                                     \
+            return VAR(vm->py_##name(a[i], b[i]));                                  \
+        }                                                                           \
+        return VAR(a.size() op b.size());                                           \
+    });
+
+    BIND_RICH_CMP(lt, <, tp_list, List)
+    BIND_RICH_CMP(le, <=, tp_list, List)
+    BIND_RICH_CMP(gt, >, tp_list, List)
+    BIND_RICH_CMP(ge, >=, tp_list, List)
+    
+    BIND_RICH_CMP(lt, <, tp_tuple, Tuple)
+    BIND_RICH_CMP(le, <=, tp_tuple, Tuple)
+    BIND_RICH_CMP(gt, >, tp_tuple, Tuple)
+    BIND_RICH_CMP(ge, >=, tp_tuple, Tuple)
+
+#undef BIND_RICH_CMP
+
     _vm->bind__add__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
     _vm->bind__add__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
         const List& self = _CAST(List&, lhs);
         const List& self = _CAST(List&, lhs);
         const List& other = CAST(List&, rhs);
         const List& other = CAST(List&, rhs);
@@ -900,14 +924,14 @@ void init_builtins(VM* _vm) {
 
 
     _vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
     _vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
         Tuple& self = _CAST(Tuple&, obj);
         Tuple& self = _CAST(Tuple&, obj);
-        for(PyObject* i: self) if(vm->py_equals(i, item)) return vm->True;
+        for(PyObject* i: self) if(vm->py_eq(i, item)) return vm->True;
         return vm->False;
         return vm->False;
     });
     });
 
 
     _vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) {
     _vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) {
         Tuple& self = _CAST(Tuple&, args[0]);
         Tuple& self = _CAST(Tuple&, args[0]);
         int count = 0;
         int count = 0;
-        for(PyObject* i: self) if(vm->py_equals(i, args[1])) count++;
+        for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
         return VAR(count);
         return VAR(count);
     });
     });
 
 
@@ -917,7 +941,7 @@ void init_builtins(VM* _vm) {
         const Tuple& other = _CAST(Tuple&, rhs);
         const Tuple& other = _CAST(Tuple&, rhs);
         if(self.size() != other.size()) return vm->False;
         if(self.size() != other.size()) return vm->False;
         for(int i = 0; i < self.size(); i++) {
         for(int i = 0; i < self.size(); i++) {
-            if(!vm->py_equals(self[i], other[i])) return vm->False;
+            if(!vm->py_eq(self[i], other[i])) return vm->False;
         }
         }
         return vm->True;
         return vm->True;
     });
     });
@@ -1282,7 +1306,7 @@ void init_builtins(VM* _vm) {
             if(item.first == nullptr) continue;
             if(item.first == nullptr) continue;
             PyObject* value = other.try_get(item.first);
             PyObject* value = other.try_get(item.first);
             if(value == nullptr) return vm->False;
             if(value == nullptr) return vm->False;
-            if(!vm->py_equals(item.second, value)) return vm->False;
+            if(!vm->py_eq(item.second, value)) return vm->False;
         }
         }
         return vm->True;
         return vm->True;
     });
     });

+ 3 - 3
src/vm.cpp

@@ -249,7 +249,7 @@ namespace pkpy{
         return &_all_types[obj->type];
         return &_all_types[obj->type];
     }
     }
 
 
-    bool VM::py_equals(PyObject* lhs, PyObject* rhs){
+    bool VM::py_eq(PyObject* lhs, PyObject* rhs){
         if(lhs == rhs) return true;
         if(lhs == rhs) return true;
         const PyTypeInfo* ti = _inst_type_info(lhs);
         const PyTypeInfo* ti = _inst_type_info(lhs);
         PyObject* res;
         PyObject* res;
@@ -1230,7 +1230,7 @@ void Dict::_probe_0(PyObject *key, bool &ok, int &i) const{
     // std::cout << CAST(Str, vm->py_repr(key)) << " " << hash << " " << i << std::endl;
     // std::cout << CAST(Str, vm->py_repr(key)) << " " << hash << " " << i << std::endl;
     for(int j=0; j<_capacity; j++) {
     for(int j=0; j<_capacity; j++) {
         if(_items[i].first != nullptr){
         if(_items[i].first != nullptr){
-            if(vm->py_equals(_items[i].first, key)) { ok = true; break; }
+            if(vm->py_eq(_items[i].first, key)) { ok = true; break; }
         }else{
         }else{
             if(_items[i].second == nullptr) break;
             if(_items[i].second == nullptr) break;
         }
         }
@@ -1244,7 +1244,7 @@ void Dict::_probe_1(PyObject *key, bool &ok, int &i) const{
     ok = false;
     ok = false;
     i = vm->py_hash(key) & _mask;
     i = vm->py_hash(key) & _mask;
     while(_items[i].first != nullptr) {
     while(_items[i].first != nullptr) {
-        if(vm->py_equals(_items[i].first, key)) { ok = true; break; }
+        if(vm->py_eq(_items[i].first, key)) { ok = true; break; }
         // https://github.com/python/cpython/blob/3.8/Objects/dictobject.c#L166
         // https://github.com/python/cpython/blob/3.8/Objects/dictobject.c#L166
         i = ((5*i) + 1) & _mask;
         i = ((5*i) + 1) & _mask;
     }
     }

+ 0 - 3
tests/70_collections.py

@@ -826,6 +826,3 @@ d = deque()
 for i in range(100):
 for i in range(100):
     d.append(1)
     d.append(1)
     gc.collect()
     gc.collect()
-
-
-print('✓', "ALL TEST PASSED!!")

+ 4 - 4
tests/99_builtin_func.py

@@ -380,7 +380,7 @@ except:
 #     #####:  649:        List& self = _CAST(List&, args[0]);
 #     #####:  649:        List& self = _CAST(List&, args[0]);
 #     #####:  650:        PyObject* obj = args[1];
 #     #####:  650:        PyObject* obj = args[1];
 #     #####:  651:        for(int i=0; i<self.size(); i++){
 #     #####:  651:        for(int i=0; i<self.size(); i++){
-#     #####:  652:            if(vm->py_equals(self[i], obj)) return VAR(i);
+#     #####:  652:            if(vm->py_eq(self[i], obj)) return VAR(i);
 #         -:  653:        }
 #         -:  653:        }
 #     #####:  654:        vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
 #     #####:  654:        vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
 #     #####:  655:        return vm->None;
 #     #####:  655:        return vm->None;
@@ -401,7 +401,7 @@ except:
 #         1:  659:        List& self = _CAST(List&, args[0]);
 #         1:  659:        List& self = _CAST(List&, args[0]);
 #         1:  660:        PyObject* obj = args[1];
 #         1:  660:        PyObject* obj = args[1];
 #         2:  661:        for(int i=0; i<self.size(); i++){
 #         2:  661:        for(int i=0; i<self.size(); i++){
-#         2:  662:            if(vm->py_equals(self[i], obj)){
+#         2:  662:            if(vm->py_eq(self[i], obj)){
 #         1:  663:                self.erase(i);
 #         1:  663:                self.erase(i);
 #         1:  664:                return vm->None;
 #         1:  664:                return vm->None;
 #         -:  665:            }
 #         -:  665:            }
@@ -474,7 +474,7 @@ except:
 # 未完全测试准确性-----------------------------------------------
 # 未完全测试准确性-----------------------------------------------
 #       118:  793:    _vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
 #       118:  793:    _vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
 #         1:  794:        Tuple& self = _CAST(Tuple&, obj);
 #         1:  794:        Tuple& self = _CAST(Tuple&, obj);
-#         3:  795:        for(PyObject* i: self) if(vm->py_equals(i, item)) return vm->True;
+#         3:  795:        for(PyObject* i: self) if(vm->py_eq(i, item)) return vm->True;
 #     #####:  796:        return vm->False;
 #     #####:  796:        return vm->False;
 #         1:  797:    });
 #         1:  797:    });
 # test tuple.__contains__:
 # test tuple.__contains__:
@@ -485,7 +485,7 @@ assert (1,2,3).__contains__(5) == False
 #       116:  799:    _vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) {
 #       116:  799:    _vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) {
 #     #####:  800:        Tuple& self = _CAST(Tuple&, args[0]);
 #     #####:  800:        Tuple& self = _CAST(Tuple&, args[0]);
 #         -:  801:        int count = 0;
 #         -:  801:        int count = 0;
-#     #####:  802:        for(PyObject* i: self) if(vm->py_equals(i, args[1])) count++;
+#     #####:  802:        for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
 #     #####:  803:        return VAR(count);
 #     #####:  803:        return VAR(count);
 #         -:  804:    });
 #         -:  804:    });
 # test tuple.count:
 # test tuple.count: