[pypy-svn] r73610 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test
jandem at codespeak.net
jandem at codespeak.net
Sat Apr 10 13:48:55 CEST 2010
Author: jandem
Date: Sat Apr 10 13:48:53 2010
New Revision: 73610
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/api.py
pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h
pypy/branch/cpython-extension/pypy/module/cpyext/object.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py
Log:
add PyObject_RichCompare{Bool}, with tests
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Apr 10 13:48:53 2010
@@ -59,6 +59,7 @@
METH_COEXIST METH_STATIC METH_CLASS
METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O
Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS
+Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE
""".split()
for name in constant_names:
setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name))
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sat Apr 10 13:48:53 2010
@@ -57,6 +57,21 @@
#define Py_None (&_Py_NoneStruct)
+/*
+Py_NotImplemented is a singleton used to signal that an operation is
+not implemented for a given type combination.
+*/
+PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
+#define Py_NotImplemented (&_Py_NotImplementedStruct)
+
+/* Rich comparison opcodes */
+#define Py_LT 0
+#define Py_LE 1
+#define Py_EQ 2
+#define Py_NE 3
+#define Py_GT 4
+#define Py_GE 5
+
struct _typeobject;
typedef void (*freefunc)(void *);
typedef void (*destructor)(PyObject *);
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Sat Apr 10 13:48:53 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import cpython_api, generic_cpy_call, CANNOT_FAIL,\
- Py_ssize_t, PyVarObject, Py_TPFLAGS_HEAPTYPE
+ Py_ssize_t, PyVarObject, Py_TPFLAGS_HEAPTYPE,\
+ Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE
from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef
from pypy.module.cpyext.state import State
@@ -112,3 +113,31 @@
Python expression repr(o). Called by the repr() built-in function and
by reverse quotes."""
return space.repr(w_obj)
+
+ at cpython_api([PyObject, PyObject, rffi.INT_real], PyObject)
+def PyObject_RichCompare(space, w_o1, w_o2, opid):
+ """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 <,
+ <=, ==, !=, >, or >= respectively. This is the equivalent of
+ the Python expression o1 op o2, where op is the operator corresponding
+ to opid. Returns the value of the comparison on success, or NULL on failure."""
+ if opid == Py_LT: return space.lt(w_o1, w_o2)
+ if opid == Py_LE: return space.le(w_o1, w_o2)
+ if opid == Py_EQ: return space.eq(w_o1, w_o2)
+ if opid == Py_NE: return space.ne(w_o1, w_o2)
+ if opid == Py_GT: return space.gt(w_o1, w_o2)
+ if opid == Py_GE: return space.ge(w_o1, w_o2)
+ PyErr_BadInternalCall(space)
+
+ at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
+def PyObject_RichCompareBool(space, ref1, ref2, opid):
+ """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 <,
+ <=, ==, !=, >, or >= respectively. Returns -1 on error,
+ 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)
+ return PyObject_IsTrue(space, w_res)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Sat Apr 10 13:48:53 2010
@@ -2,7 +2,8 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.rpython.lltypesystem import rffi, lltype
-
+from pypy.module.cpyext.api import Py_LT, Py_LE, Py_NE, Py_EQ,\
+ Py_GE, Py_GT
class TestObject(BaseApiTest):
def test_IsTrue(self, space, api):
@@ -53,7 +54,6 @@
lltype.free(charp1, flavor="raw")
lltype.free(charp2, flavor="raw")
-
def test_getitem(self, space, api):
w_t = space.wrap((1, 2, 3, 4, 5))
assert space.unwrap(api.PyObject_GetItem(w_t, space.wrap(3))) == 4
@@ -68,3 +68,28 @@
def test_repr(self, space, api):
w_list = space.newlist([space.w_None, space.wrap(42)])
assert space.str_w(api.PyObject_Repr(w_list)) == "[None, 42]"
+
+ def test_RichCompare(self, space, api):
+ w_i1 = space.wrap(1)
+ w_i2 = space.wrap(2)
+ w_i3 = space.wrap(3)
+
+ def compare(w_o1, w_o2, opid):
+ res = api.PyObject_RichCompareBool(w_o1, w_o2, opid)
+ w_res = api.PyObject_RichCompare(w_o1, w_o2, opid)
+ assert space.is_true(w_res) == res
+ return res
+
+ def test_compare(o1, o2):
+ w_o1 = space.wrap(o1)
+ w_o2 = space.wrap(o2)
+
+ for opid, expected in [
+ (Py_LT, o1 < o2), (Py_LE, o1 <= o2),
+ (Py_NE, o1 != o2), (Py_EQ, o1 == o2),
+ (Py_GT, o1 > o2), (Py_GE, o1 >= o2)]:
+ assert compare(w_o1, w_o2, opid) == expected
+
+ test_compare(1, 2)
+ test_compare(2, 2)
+ test_compare('2', '1')
More information about the Pypy-commit
mailing list