Skip to content

Commit 420c934

Browse files
committed
Add more tp_richcompare tests, remove deadcode in LookupAndCallBinaryNode
1 parent 5facbad commit 420c934

File tree

4 files changed

+77
-374
lines changed

4 files changed

+77
-374
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tp_slots.py

+73-3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
import operator
4343
from . import CPyExtType, CPyExtHeapType, compile_module_from_string, assert_raises, compile_module_from_file
44+
from .test_indexed_slots import cmembers
4445

4546

4647
def 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)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/RichCmpOp.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@
4040
*/
4141
package com.oracle.graal.python.lib;
4242

43-
import com.oracle.graal.python.builtins.objects.ints.PInt;
44-
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
45-
import com.oracle.truffle.api.CompilerDirectives;
46-
import com.oracle.truffle.api.strings.TruffleString;
47-
4843
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__;
4944
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GE__;
5045
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GT__;
@@ -53,6 +48,10 @@
5348
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NE__;
5449
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
5550

51+
import com.oracle.graal.python.builtins.objects.ints.PInt;
52+
import com.oracle.truffle.api.CompilerDirectives;
53+
import com.oracle.truffle.api.strings.TruffleString;
54+
5655
/**
5756
* Mirror of the CPython constants of the same name. The order is important: the ordinal should be
5857
* the same as the constant value on the CPython side.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallBinaryNode.java

-92
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,13 @@
4040
*/
4141
package com.oracle.graal.python.nodes.call.special;
4242

43-
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
44-
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
45-
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
4643
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
47-
import com.oracle.graal.python.nodes.PGuards;
4844
import com.oracle.graal.python.nodes.PNodeWithContext;
4945
import com.oracle.graal.python.runtime.PythonOptions;
5046
import com.oracle.graal.python.util.Supplier;
5147
import com.oracle.truffle.api.CompilerDirectives;
52-
import com.oracle.truffle.api.dsl.Fallback;
53-
import com.oracle.truffle.api.dsl.GenerateCached;
54-
import com.oracle.truffle.api.dsl.GenerateInline;
5548
import com.oracle.truffle.api.dsl.ImportStatic;
5649
import com.oracle.truffle.api.dsl.NeverDefault;
57-
import com.oracle.truffle.api.dsl.Specialization;
5850
import com.oracle.truffle.api.frame.VirtualFrame;
5951
import com.oracle.truffle.api.nodes.Node;
6052
import com.oracle.truffle.api.strings.TruffleString;
@@ -108,90 +100,6 @@ public static LookupAndCallBinaryNode create(SpecialMethodSlot slot, Supplier<No
108100
return LookupAndCallNonReversibleBinaryNodeGen.create(slot, handlerFactory, false);
109101
}
110102

111-
@NeverDefault
112-
public static LookupAndCallBinaryNode createReversible(SpecialMethodSlot slot, SpecialMethodSlot rslot, Supplier<NotImplementedHandler> handlerFactory) {
113-
return LookupAndCallReversibleBinaryNodeGen.create(slot, rslot, handlerFactory, false, false);
114-
}
115-
116-
@NeverDefault
117-
public static LookupAndCallBinaryNode create(SpecialMethodSlot slot, SpecialMethodSlot rslot, boolean alwaysCheckReverse, boolean ignoreDescriptorException) {
118-
return LookupAndCallReversibleBinaryNodeGen.create(slot, rslot, null, alwaysCheckReverse, ignoreDescriptorException);
119-
}
120-
121-
@ImportStatic(PGuards.class)
122-
@GenerateInline
123-
@GenerateCached(false)
124-
protected abstract static class AreSameCallables extends Node {
125-
public abstract boolean execute(Node inliningTarget, Object left, Object right);
126-
127-
@Specialization(guards = "a == b")
128-
static boolean areIdenticalFastPath(@SuppressWarnings("unused") Object a, @SuppressWarnings("unused") Object b) {
129-
return true;
130-
}
131-
132-
@Specialization(guards = "isNone(a) || isNone(b)")
133-
static boolean noneFastPath(@SuppressWarnings("unused") Object a, @SuppressWarnings("unused") Object b) {
134-
return a == b;
135-
}
136-
137-
@Specialization(replaces = "areIdenticalFastPath")
138-
static boolean doDescrs(BuiltinMethodDescriptor a, BuiltinMethodDescriptor b) {
139-
return a == b;
140-
}
141-
142-
@Specialization(replaces = "areIdenticalFastPath")
143-
static boolean doDescrFun1(BuiltinMethodDescriptor a, PBuiltinFunction b) {
144-
return a.isDescriptorOf(b);
145-
}
146-
147-
@Specialization(replaces = "areIdenticalFastPath")
148-
static boolean doDescrFun2(PBuiltinFunction a, BuiltinMethodDescriptor b) {
149-
return b.isDescriptorOf(a);
150-
}
151-
152-
@Specialization(replaces = "areIdenticalFastPath")
153-
static boolean doDescrMeth1(BuiltinMethodDescriptor a, PBuiltinMethod b) {
154-
return doDescrFun1(a, b.getBuiltinFunction());
155-
}
156-
157-
@Specialization(replaces = "areIdenticalFastPath")
158-
static boolean doDescrMeth2(PBuiltinMethod a, BuiltinMethodDescriptor b) {
159-
return doDescrFun2(a.getBuiltinFunction(), b);
160-
}
161-
162-
@Fallback
163-
static boolean doGenericRuntimeObjects(Object a, Object b) {
164-
return a == b;
165-
}
166-
}
167-
168-
@ImportStatic(PGuards.class)
169-
@GenerateInline
170-
@GenerateCached(false)
171-
protected abstract static class GetEnclosingType extends Node {
172-
public abstract Object execute(Node inliningTarget, Object callable);
173-
174-
@Specialization
175-
static Object doDescrs(BuiltinMethodDescriptor descriptor) {
176-
return descriptor.getEnclosingType();
177-
}
178-
179-
@Specialization
180-
static Object doBuiltinFun(PBuiltinFunction fun) {
181-
return fun.getEnclosingType();
182-
}
183-
184-
@Specialization
185-
static Object doBuiltinMethod(PBuiltinMethod a) {
186-
return doBuiltinFun(a.getBuiltinFunction());
187-
}
188-
189-
@Fallback
190-
static Object doOthers(@SuppressWarnings("unused") Object callable) {
191-
return null;
192-
}
193-
}
194-
195103
public abstract TruffleString getName();
196104

197105
protected final CallBinaryMethodNode ensureDispatch() {

0 commit comments

Comments
 (0)