4141
4242import operator
4343from . import CPyExtType , CPyExtHeapType , compile_module_from_string , assert_raises , compile_module_from_file
44+ from .test_indexed_slots import cmembers
4445
4546
4647def get_delegate (o ):
@@ -842,9 +843,9 @@ class DisablesHash2(TypeWithHash):
842843 "TypeWithoutHashExplicit" ,
843844 tp_hash = 'PyObject_HashNotImplemented' ,
844845 code = '''
845- static hashfunc myglobal = PyObject_HashNotImplemented;
846- typedef struct { hashfunc x; } _mystruct_t;
847- static _mystruct_t mystruct = { PyObject_HashNotImplemented };
846+ // static hashfunc myglobal = PyObject_HashNotImplemented;
847+ // typedef struct { hashfunc x; } _mystruct_t;
848+ // static _mystruct_t mystruct = { PyObject_HashNotImplemented };
848849 ''' ,
849850 ready_code = '''
850851 // printf("TypeWithoutHashExplicitType.tp_hash=%p, PyObject_HashNotImplemented=%p, myglobal=%p, mystruct.x=%p\\ n", TypeWithoutHashExplicitType.tp_hash, &PyObject_HashNotImplemented, myglobal, mystruct.x);
@@ -1576,3 +1577,72 @@ def test_richcmp():
15761577 struct_base = 'PyLongObject base;' )
15771578 assert MyNativeIntSubType (42 ) == 42
15781579 assert MyNativeIntSubType (42 ) == MyNativeIntSubType (42 )
1580+
1581+ RichCmpMockType = CPyExtType ("RichCmpMock" ,
1582+ cmembers = "int results[Py_GE+1];" ,
1583+ code = '''
1584+ static PyTypeObject RichCmpMockType;
1585+
1586+ static PyObject* set_values(PyObject* self, PyObject* values) {
1587+ RichCmpMockObject* richCmp = (RichCmpMockObject*) self;
1588+ for (int i = 0; i <= Py_GE; i++) {
1589+ richCmp->results[i] = (int) PyLong_AsLong(PyTuple_GET_ITEM(values, i));
1590+ }
1591+ Py_RETURN_NONE;
1592+ }
1593+
1594+ static PyObject *custom_type_richcmp(PyObject *v, PyObject *w, int op) {
1595+ if (!PyObject_TypeCheck(v, &RichCmpMockType)) Py_RETURN_NOTIMPLEMENTED;
1596+ RichCmpMockObject* richCmp = (RichCmpMockObject*) v;
1597+ if (richCmp->results[op] == 0) {
1598+ Py_RETURN_FALSE;
1599+ } else if (richCmp->results[op] == 1) {
1600+ Py_RETURN_TRUE;
1601+ } else {
1602+ Py_RETURN_NOTIMPLEMENTED;
1603+ }
1604+ };
1605+ ''' ,
1606+ tp_methods = '{"set_values", (PyCFunction)set_values, METH_O, NULL}' ,
1607+ tp_richcompare = 'custom_type_richcmp' )
1608+
1609+ def create_mock (lt = - 1 , le = - 1 , eq = - 1 , ne = - 1 , gt = - 1 , ge = - 1 ):
1610+ mock = RichCmpMockType ()
1611+ mock .set_values (tuple ([lt , le , eq , ne , gt , ge ]))
1612+ return mock
1613+
1614+ def expect_type_error (code ):
1615+ try :
1616+ code ()
1617+ except TypeError as e :
1618+ assert "not supported between instances " in str (e )
1619+
1620+ def test_cmp (op_lambda , rop_lambda , op_name , rop_name ):
1621+ assert op_lambda (create_mock (** {op_name : 1 }), "whatever" )
1622+ assert op_lambda (create_mock (** {op_name : 1 }), create_mock (** {rop_name : 0 , op_name : 0 }))
1623+ assert not op_lambda (create_mock (** {op_name : 0 }), "whatever" )
1624+ expect_type_error (lambda : op_lambda (create_mock (), "whatever" ))
1625+
1626+ if rop_lambda :
1627+ assert rop_lambda ("whatever" , create_mock (** {op_name : 1 }))
1628+ assert rop_lambda (create_mock (), create_mock (** {op_name : 1 }))
1629+ assert not rop_lambda (create_mock (** {rop_name : 0 }), create_mock (** {op_name : 1 }))
1630+
1631+ import operator
1632+ test_cmp (operator .lt , operator .gt , "lt" , "gt" )
1633+ test_cmp (operator .le , operator .ge , "le" , "ge" )
1634+ test_cmp (operator .gt , operator .lt , "gt" , "lt" )
1635+ test_cmp (operator .ge , operator .le , "ge" , "le" )
1636+ test_cmp (operator .eq , operator .ne , "eq" , "ne" )
1637+ test_cmp (operator .ne , None , "ne" , "eq" )
1638+
1639+ test_cmp (lambda a ,b : a .__lt__ (b ), lambda a ,b : a .__gt__ (b ), "lt" , "gt" )
1640+ test_cmp (lambda a ,b : a .__le__ (b ), lambda a ,b : a .__ge__ (b ), "le" , "ge" )
1641+ test_cmp (lambda a ,b : a .__gt__ (b ), lambda a ,b : a .__lt__ (b ), "gt" , "lt" )
1642+ test_cmp (lambda a ,b : a .__ge__ (b ), lambda a ,b : a .__le__ (b ), "ge" , "le" )
1643+ test_cmp (lambda a ,b : a .__eq__ (b ), lambda a ,b : a .__ne__ (b ), "eq" , "ne" )
1644+ test_cmp (lambda a ,b : a .__ne__ (b ), None , "ne" , "eq" )
1645+
1646+ assert create_mock (ne = 1 ) == create_mock (eq = 1 )
1647+ assert create_mock (ne = 1 , eq = 0 ) != create_mock (ne = 0 , eq = 1 )
1648+ assert not create_mock (ne = 1 , eq = 0 ) == create_mock (ne = 0 , eq = 1 )
0 commit comments