[pypy-svn] r74798 - in pypy/trunk/pypy/module/cpyext: . test

afa at codespeak.net afa at codespeak.net
Thu May 27 11:06:03 CEST 2010


Author: afa
Date: Thu May 27 11:06:02 2010
New Revision: 74798

Modified:
   pypy/trunk/pypy/module/cpyext/slotdefs.py
   pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
   pypy/trunk/pypy/module/cpyext/typeobject.py
Log:
Fill the slot tp_as_number.nb_int, when the type defines a __init__ method.


Modified: pypy/trunk/pypy/module/cpyext/slotdefs.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/slotdefs.py	(original)
+++ pypy/trunk/pypy/module/cpyext/slotdefs.py	Thu May 27 11:06:02 2010
@@ -124,6 +124,10 @@
     space.get_and_call_args(w_descr, w_self, args)
     return 0
 
+ at cpython_api([PyObject], PyObject)
+def slot_nb_int(space, w_self):
+    return space.int(w_self)
+
 PyWrapperFlag_KEYWORDS = 1
 
 # adopted from typeobject.c

Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py	Thu May 27 11:06:02 2010
@@ -189,3 +189,22 @@
         w_obj = api._PyType_Lookup(w_type, space.wrap("__invalid"))
         assert w_obj is None
         assert api.PyErr_Occurred() is None
+
+class AppTestSlots(AppTestCpythonExtensionBase):
+    def test_nb_int(self):
+        module = self.import_extension('foo', [
+            ("nb_int", "METH_O",
+             '''
+                 if (!args->ob_type->tp_as_number ||
+                     !args->ob_type->tp_as_number->nb_int)
+                 {
+                     PyErr_SetNone(PyExc_ValueError);
+                     return NULL;
+                 }
+                 return args->ob_type->tp_as_number->nb_int(args);
+             '''
+             )
+            ])
+        assert module.nb_int(10) == 10
+        assert module.nb_int(-12.3) == -12
+        raises(ValueError, module.nb_int, "123")

Modified: pypy/trunk/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/typeobject.py	Thu May 27 11:06:02 2010
@@ -27,8 +27,9 @@
     PyDescr_NewWrapper, PyCFunction_NewEx)
 from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef, _Py_Dealloc
 from pypy.module.cpyext.structmember import PyMember_GetOne, PyMember_SetOne
-from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \
-        PyGetSetDef, PyMemberDef, newfunc
+from pypy.module.cpyext.typeobjectdefs import (
+    PyTypeObjectPtr, PyTypeObject, PyGetSetDef, PyMemberDef, newfunc,
+    PyNumberMethods)
 from pypy.module.cpyext.slotdefs import slotdefs
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.rlib.rstring import rsplit
@@ -104,10 +105,10 @@
             dict_w[name] = w_descr
             i += 1
 
-def update_all_slots(space, w_obj, pto):
+def update_all_slots(space, w_type, pto):
     #  XXX fill slots in pto
     for method_name, slot_name, slot_func, _, _, _ in slotdefs:
-        w_descr = space.lookup(w_obj, method_name)
+        w_descr = w_type.lookup(method_name)
         if w_descr is None:
             # XXX special case iternext
             continue
@@ -129,7 +130,14 @@
             assert len(slot_name) == 2
             struct = getattr(pto, slot_name[0])
             if not struct:
-                continue
+                if slot_name[0] == 'c_tp_as_number':
+                    STRUCT_TYPE = PyNumberMethods
+                else:
+                    raise AssertionError(
+                        "Structure not allocated: %s" % (slot_name[0],))
+                struct = lltype.malloc(STRUCT_TYPE, flavor='raw', zero=True)
+                setattr(pto, slot_name[0], struct)
+
             setattr(struct, slot_name[1], slot_func_helper)
 
 def add_operators(space, dict_w, pto):
@@ -472,6 +480,8 @@
     if obj_pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
         if obj_pto.c_tp_as_buffer:
             lltype.free(obj_pto.c_tp_as_buffer, flavor='raw')
+        if obj_pto.c_tp_as_number:
+            lltype.free(obj_pto.c_tp_as_number, flavor='raw')
         Py_DecRef(space, base_pyo)
         rffi.free_charp(obj_pto.c_tp_name)
         obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto)



More information about the Pypy-commit mailing list