Author: Matti Picus <[email protected]>
Branch:
Changeset: r92118:d6b37b7c15ee
Date: 2017-08-09 18:25 +0300
http://bitbucket.org/pypy/pypy/changeset/d6b37b7c15ee/
Log: test, fix for cpython compatibility when PyObject_RichCompareBool(a,
a, ...)
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -305,7 +305,7 @@
PyErr_BadInternalCall(space)
@cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
-def PyObject_RichCompareBool(space, ref1, ref2, opid):
+def PyObject_RichCompareBool(space, ref1, ref2, opid_int):
"""Compare the values of o1 and o2 using the operation specified by opid,
which must be one of Py_LT, Py_LE, Py_EQ,
Py_NE, Py_GT, or Py_GE, corresponding to <,
@@ -313,7 +313,15 @@
0 if the result is false, 1 otherwise. This is the equivalent of the
Python expression o1 op o2, where op is the operator corresponding to
opid."""
- w_res = PyObject_RichCompare(space, ref1, ref2, opid)
+ # Quick result when objects are the same.
+ # Guarantees that identity implies equality.
+ if ref1 is ref2:
+ opid = rffi.cast(lltype.Signed, opid_int)
+ if opid == Py_EQ:
+ return 1
+ if opid == Py_NE:
+ return 0
+ w_res = PyObject_RichCompare(space, ref1, ref2, opid_int)
return int(space.is_true(w_res))
@cpython_api([PyObject], PyObject, result_is_ll=True)
diff --git a/pypy/module/cpyext/test/test_object.py
b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -8,7 +8,7 @@
from pypy.module.cpyext.object import (
PyObject_IsTrue, PyObject_Not, PyObject_GetAttrString,
PyObject_DelAttrString, PyObject_GetAttr, PyObject_DelAttr,
- PyObject_GetItem, PyObject_RichCompareBool,
+ PyObject_GetItem,
PyObject_IsInstance, PyObject_IsSubclass, PyObject_AsFileDescriptor,
PyObject_Hash, PyObject_Cmp, PyObject_Unicode
)
@@ -136,7 +136,18 @@
w_i = space.wrap(1)
with raises_w(space, SystemError):
- PyObject_RichCompareBool(space, w_i, w_i, 123456)
+ api.PyObject_RichCompareBool(w_i, w_i, 123456)
+
+ def test_RichCompareNanlike(self, space,api):
+ w_obj = space.appexec([], """():
+ class Nanlike(object):
+ def __eq__(self, other):
+ raise RuntimeError('unreachable')
+ return Nanlike()""")
+ res = api.PyObject_RichCompareBool(w_obj, w_obj, Py_EQ)
+ assert res == 1
+ res = api.PyObject_RichCompareBool(w_obj, w_obj, Py_NE)
+ assert res == 0
def test_IsInstance(self, space, api):
assert api.PyObject_IsInstance(space.wrap(1), space.w_int) == 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit