Author: Matti Picus <matti.pi...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit