[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