[pypy-svn] r73948 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test
afa at codespeak.net
afa at codespeak.net
Wed Apr 21 19:42:38 CEST 2010
Author: afa
Date: Wed Apr 21 19:42:36 2010
New Revision: 73948
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/number.py
pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_number.py
Log:
Add PyNumber_* abstract operations
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/number.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/number.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/number.py Wed Apr 21 19:42:36 2010
@@ -2,6 +2,7 @@
from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t
from pypy.module.cpyext.pyobject import PyObject
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.tool.sourcetools import func_with_new_name
@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def PyIndex_Check(space, w_obj):
@@ -25,3 +26,66 @@
integer or PY_SSIZE_T_MAX for a positive integer.
"""
return space.int_w(w_obj) #XXX: this is wrong
+
+def func_rename(newname):
+ return lambda func: func_with_new_name(func, newname)
+
+def make_numbermethod(name, spacemeth):
+ @cpython_api([PyObject, PyObject], PyObject)
+ @func_rename('PyNumber_%s' % (name,))
+ def PyNumber_Method(space, w_o1, w_o2):
+ meth = getattr(space, spacemeth)
+ return meth(w_o1, w_o2)
+
+def make_unary_numbermethod(name, spacemeth):
+ @cpython_api([PyObject], PyObject)
+ @func_rename('PyNumber_%s' % (name,))
+ def PyNumber_Method(space, w_o1):
+ meth = getattr(space, spacemeth)
+ return meth(w_o1)
+
+def make_inplace_numbermethod(name, spacemeth):
+ spacemeth = 'inplace_' + spacemeth.rstrip('_')
+ @cpython_api([PyObject, PyObject], PyObject)
+ @func_rename('PyNumber_Inplace%s' % (name,))
+ def PyNumber_Method(space, w_o1, w_o2):
+ meth = getattr(space, spacemeth)
+ return meth(w_o1, w_o2)
+
+for name, spacemeth in [
+ ('Add', 'add'),
+ ('Subtract', 'sub'),
+ ('Multiply', 'mul'),
+ ('Divide', 'div'),
+ ('FloorDivide', 'floordiv'),
+ ('TrueDivide', 'truediv'),
+ ('Remainder', 'mod'),
+ ('Lshift', 'lshift'),
+ ('Rshift', 'rshift'),
+ ('And', 'and_'),
+ ('Xor', 'xor'),
+ ('Or', 'or_'),
+ ('Divmod', 'divmod'),
+ ]:
+ make_numbermethod(name, spacemeth)
+ if name != 'Divmod':
+ make_inplace_numbermethod(name, spacemeth)
+
+for name, spacemeth in [
+ ('Negative', 'neg'),
+ ('Positive', 'pos'),
+ ('Absolute', 'abs'),
+ ('Invert', 'invert')]:
+ make_unary_numbermethod(name, spacemeth)
+
+ at cpython_api([PyObject, PyObject, PyObject], PyObject)
+def PyNumber_Power(space, w_o1, w_o2, w_o3):
+ return space.pow(w_o1, w_o2, w_o3)
+
+ at cpython_api([PyObject, PyObject, PyObject], PyObject)
+def PyNumber_InplacePower(space, w_o1, w_o2, w_o3):
+ if not space.is_w(w_o3, space.w_None):
+ raise OperationError(space.w_ValueError, space.wrap(
+ "PyNumber_InplacePower with non-None modulus is not supported"))
+ return space.inplace_pow(w_o1, w_o2)
+
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Wed Apr 21 19:42:36 2010
@@ -3905,222 +3905,6 @@
the equivalent of the Python expression o1 - o2."""
raise NotImplementedError
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Multiply(space, o1, o2):
- """Returns the result of multiplying o1 and o2, or NULL on failure. This is
- the equivalent of the Python expression o1 * o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Divide(space, o1, o2):
- """Returns the result of dividing o1 by o2, or NULL on failure. This is the
- equivalent of the Python expression o1 / o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_FloorDivide(space, o1, o2):
- """Return the floor of o1 divided by o2, or NULL on failure. This is
- equivalent to the "classic" division of integers.
- """
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_TrueDivide(space, o1, o2):
- """Return a reasonable approximation for the mathematical value of o1 divided by
- o2, or NULL on failure. The return value is "approximate" because binary
- floating point numbers are approximate; it is not possible to represent all real
- numbers in base two. This function can return a floating point value when
- passed two integers.
- """
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Remainder(space, o1, o2):
- """Returns the remainder of dividing o1 by o2, or NULL on failure. This is
- the equivalent of the Python expression o1 % o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Divmod(space, o1, o2):
- """
-
-
-
- See the built-in function divmod(). Returns NULL on failure. This is
- the equivalent of the Python expression divmod(o1, o2)."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject, PyObject], PyObject)
-def PyNumber_Power(space, o1, o2, o3):
- """
-
-
-
- See the built-in function pow(). Returns NULL on failure. This is the
- equivalent of the Python expression pow(o1, o2, o3), where o3 is optional.
- If o3 is to be ignored, pass Py_None in its place (passing NULL for
- o3 would cause an illegal memory access)."""
- raise NotImplementedError
-
- at cpython_api([PyObject], PyObject)
-def PyNumber_Negative(space, o):
- """Returns the negation of o on success, or NULL on failure. This is the
- equivalent of the Python expression -o."""
- raise NotImplementedError
-
- at cpython_api([PyObject], PyObject)
-def PyNumber_Positive(space, o):
- """Returns o on success, or NULL on failure. This is the equivalent of the
- Python expression +o."""
- raise NotImplementedError
-
- at cpython_api([PyObject], PyObject)
-def PyNumber_Absolute(space, o):
- """
-
-
-
- Returns the absolute value of o, or NULL on failure. This is the equivalent
- of the Python expression abs(o)."""
- raise NotImplementedError
-
- at cpython_api([PyObject], PyObject)
-def PyNumber_Invert(space, o):
- """Returns the bitwise negation of o on success, or NULL on failure. This is
- the equivalent of the Python expression ~o."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Lshift(space, o1, o2):
- """Returns the result of left shifting o1 by o2 on success, or NULL on
- failure. This is the equivalent of the Python expression o1 << o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Rshift(space, o1, o2):
- """Returns the result of right shifting o1 by o2 on success, or NULL on
- failure. This is the equivalent of the Python expression o1 >> o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_And(space, o1, o2):
- """Returns the "bitwise and" of o1 and o2 on success and NULL on failure.
- This is the equivalent of the Python expression o1 & o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Xor(space, o1, o2):
- """Returns the "bitwise exclusive or" of o1 by o2 on success, or NULL on
- failure. This is the equivalent of the Python expression o1 ^ o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_Or(space, o1, o2):
- """Returns the "bitwise or" of o1 and o2 on success, or NULL on failure.
- This is the equivalent of the Python expression o1 | o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceAdd(space, o1, o2):
- """Returns the result of adding o1 and o2, or NULL on failure. The operation
- is done in-place when o1 supports it. This is the equivalent of the Python
- statement o1 += o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceSubtract(space, o1, o2):
- """Returns the result of subtracting o2 from o1, or NULL on failure. The
- operation is done in-place when o1 supports it. This is the equivalent of
- the Python statement o1 -= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceMultiply(space, o1, o2):
- """Returns the result of multiplying o1 and o2, or NULL on failure. The
- operation is done in-place when o1 supports it. This is the equivalent of
- the Python statement o1 *= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceDivide(space, o1, o2):
- """Returns the result of dividing o1 by o2, or NULL on failure. The
- operation is done in-place when o1 supports it. This is the equivalent of
- the Python statement o1 /= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceFloorDivide(space, o1, o2):
- """Returns the mathematical floor of dividing o1 by o2, or NULL on failure.
- The operation is done in-place when o1 supports it. This is the equivalent
- of the Python statement o1 //= o2.
- """
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceTrueDivide(space, o1, o2):
- """Return a reasonable approximation for the mathematical value of o1 divided by
- o2, or NULL on failure. The return value is "approximate" because binary
- floating point numbers are approximate; it is not possible to represent all real
- numbers in base two. This function can return a floating point value when
- passed two integers. The operation is done in-place when o1 supports it.
- """
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceRemainder(space, o1, o2):
- """Returns the remainder of dividing o1 by o2, or NULL on failure. The
- operation is done in-place when o1 supports it. This is the equivalent of
- the Python statement o1 %= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject, PyObject], PyObject)
-def PyNumber_InPlacePower(space, o1, o2, o3):
- """
-
-
-
- See the built-in function pow(). Returns NULL on failure. The operation
- is done in-place when o1 supports it. This is the equivalent of the Python
- statement o1 **= o2 when o3 is Py_None, or an in-place variant of
- pow(o1, o2, o3) otherwise. If o3 is to be ignored, pass Py_None
- in its place (passing NULL for o3 would cause an illegal memory access)."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceLshift(space, o1, o2):
- """Returns the result of left shifting o1 by o2 on success, or NULL on
- failure. The operation is done in-place when o1 supports it. This is the
- equivalent of the Python statement o1 <<= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceRshift(space, o1, o2):
- """Returns the result of right shifting o1 by o2 on success, or NULL on
- failure. The operation is done in-place when o1 supports it. This is the
- equivalent of the Python statement o1 >>= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceAnd(space, o1, o2):
- """Returns the "bitwise and" of o1 and o2 on success and NULL on failure. The
- operation is done in-place when o1 supports it. This is the equivalent of
- the Python statement o1 &= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceXor(space, o1, o2):
- """Returns the "bitwise exclusive or" of o1 by o2 on success, or NULL on
- failure. The operation is done in-place when o1 supports it. This is the
- equivalent of the Python statement o1 ^= o2."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyNumber_InPlaceOr(space, o1, o2):
- """Returns the "bitwise or" of o1 and o2 on success, or NULL on failure. The
- operation is done in-place when o1 supports it. This is the equivalent of
- the Python statement o1 |= o2."""
- raise NotImplementedError
-
@cpython_api([PyObjectP, PyObjectP], rffi.INT_real)
def PyNumber_Coerce(space, p1, p2):
"""
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_number.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_number.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_number.py Wed Apr 21 19:42:36 2010
@@ -7,3 +7,29 @@
def test_index(self, space, api):
assert api.PyIndex_Check(space.wrap(12))
assert not api.PyIndex_Check(space.wrap('12'))
+
+ def test_numbermethods(self, space, api):
+ assert "ab" == space.unwrap(
+ api.PyNumber_Add(space.wrap("a"), space.wrap("b")))
+ assert "aaa" == space.unwrap(
+ api.PyNumber_Multiply(space.wrap("a"), space.wrap(3)))
+
+ w_l = space.newlist([1, 2, 3])
+ w_l2 = api.PyNumber_Multiply(w_l, space.wrap(3))
+ assert api.PyObject_Size(w_l2) == 9
+ assert api.PyObject_Size(w_l) == 3
+
+ w_l3 = api.PyNumber_InplaceMultiply(w_l, space.wrap(3))
+ assert api.PyObject_Size(w_l) == 9
+ assert w_l3 is w_l
+
+ # unary function
+ assert 9 == space.unwrap(api.PyNumber_Absolute(space.wrap(-9)))
+
+ # power
+ assert 9 == space.unwrap(
+ api.PyNumber_Power(space.wrap(3), space.wrap(2), space.w_None))
+ assert 4 == space.unwrap(
+ api.PyNumber_Power(space.wrap(3), space.wrap(2), space.wrap(5)))
+ assert 9 == space.unwrap(
+ api.PyNumber_InplacePower(space.wrap(3), space.wrap(2), space.w_None))
More information about the Pypy-commit
mailing list