[pypy-svn] pypy default: Implement PyInt_AsUnsignedLongMask

amauryfa commits-noreply at bitbucket.org
Fri Dec 17 19:00:17 CET 2010


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r40101:7fb4b3b3b895
Date: 2010-11-07 20:36 +0000
http://bitbucket.org/pypy/pypy/changeset/7fb4b3b3b895/

Log:	Implement PyInt_AsUnsignedLongMask

diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1813,14 +1813,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.ULONG, error=-1)
-def PyInt_AsUnsignedLongMask(space, io):
-    """Will first attempt to cast the object to a PyIntObject or
-    PyLongObject, if it is not already one, and then return its value as
-    unsigned long.  This function does not check for overflow.
-    """
-    raise NotImplementedError
-
 @cpython_api([PyObject], rffi.LONGLONG, error=-1)
 def PyInt_AsUnsignedLongLongMask(space, io):
     """Will first attempt to cast the object to a PyIntObject or
@@ -1953,13 +1945,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.ULONG, error=-1)
-def PyLong_AsUnsignedLongMask(space, io):
-    """Return a C unsigned long from a Python long integer, without checking
-    for overflow.
-    """
-    raise NotImplementedError
-
 @cpython_api([PyObject], rffi.ULONGLONG, error=-1)
 def PyLong_AsUnsignedLongLongMask(space, io):
     """Return a C unsigned long long from a Python long integer, without

diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py
--- a/pypy/module/cpyext/longobject.py
+++ b/pypy/module/cpyext/longobject.py
@@ -3,6 +3,7 @@
                                     CONST_STRING, ADDR)
 from pypy.objspace.std.longobject import W_LongObject
 from pypy.interpreter.error import OperationError
+from pypy.module.cpyext.intobject import PyInt_AsUnsignedLongMask
 
 
 PyLong_Check, PyLong_CheckExact = build_type_checkers("Long")
@@ -38,6 +39,13 @@
     raised."""
     return rffi.cast(rffi.ULONG, space.uint_w(w_long))
 
+ at cpython_api([PyObject], rffi.ULONG, error=-1)
+def PyLong_AsUnsignedLongMask(space, w_long):
+    """Return a C unsigned long from a Python long integer, without checking
+    for overflow.
+    """
+    return PyInt_AsUnsignedLongMask(space, w_long)
+
 @cpython_api([PyObject], lltype.Signed, error=-1)
 def PyLong_AsLong(space, w_long):
     """

diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
--- a/pypy/module/cpyext/intobject.py
+++ b/pypy/module/cpyext/intobject.py
@@ -3,7 +3,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.api import (cpython_api, PyObject, CANNOT_FAIL,
                                     build_type_checkers, Py_ssize_t)
-
+from pypy.rlib.rarithmetic import r_uint
 
 PyInt_Check, PyInt_CheckExact = build_type_checkers("Int")
 
@@ -35,6 +35,20 @@
                              space.wrap("an integer is required, got NULL"))
     return space.uint_w(space.int(w_obj))
 
+ at cpython_api([PyObject], rffi.ULONG, error=-1)
+def PyInt_AsUnsignedLongMask(space, w_obj):
+    """Will first attempt to cast the object to a PyIntObject or
+    PyLongObject, if it is not already one, and then return its value as
+    unsigned long.  This function does not check for overflow.
+    """
+    w_int = space.int(w_obj)
+    if space.is_true(space.isinstance(w_int, space.w_int)):
+        num = space.int_w(w_int)
+        return r_uint(num)
+    else:
+        num = space.bigint_w(w_int)
+        return num.uintmask()
+
 @cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
 def PyInt_AS_LONG(space, w_int):
     """Return the value of the object w_int. No error checking is performed."""

diff --git a/pypy/module/cpyext/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -28,6 +28,11 @@
         assert api.PyErr_Occurred() is space.w_ValueError
         api.PyErr_Clear()
 
+        assert (api.PyInt_AsUnsignedLongMask(space.wrap(sys.maxint))
+                == sys.maxint)
+        assert (api.PyInt_AsUnsignedLongMask(space.wrap(10**30))
+                == 10**30 % ((sys.maxint + 1) * 2))
+
     def test_coerce(self, space, api):
         class Coerce(object):
             def __int__(self):



More information about the Pypy-commit mailing list