41
41
42
42
import operator
43
43
from . import CPyExtType , CPyExtHeapType , compile_module_from_string , assert_raises , compile_module_from_file
44
+ from .test_indexed_slots import cmembers
44
45
45
46
46
47
def get_delegate (o ):
@@ -842,9 +843,9 @@ class DisablesHash2(TypeWithHash):
842
843
"TypeWithoutHashExplicit" ,
843
844
tp_hash = 'PyObject_HashNotImplemented' ,
844
845
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 };
848
849
''' ,
849
850
ready_code = '''
850
851
// 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():
1576
1577
struct_base = 'PyLongObject base;' )
1577
1578
assert MyNativeIntSubType (42 ) == 42
1578
1579
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