[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