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

afa at codespeak.net afa at codespeak.net
Sun May 9 11:10:03 CEST 2010


Author: afa
Date: Sun May  9 11:10:01 2010
New Revision: 74452

Modified:
   pypy/trunk/pypy/module/cpyext/slotdefs.py
   pypy/trunk/pypy/module/cpyext/test/foo.c
   pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
   pypy/trunk/pypy/module/cpyext/typeobject.py
Log:
Implement slot_tp_init, and inherit tp_init from base class.


Modified: pypy/trunk/pypy/module/cpyext/slotdefs.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/slotdefs.py	(original)
+++ pypy/trunk/pypy/module/cpyext/slotdefs.py	Sun May  9 11:10:01 2010
@@ -11,6 +11,7 @@
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.module.cpyext.state import State
 from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.argument import Arguments
 from pypy.rlib.unroll import unrolling_iterable
 
 space = None
@@ -116,6 +117,13 @@
     w_args_new = space.newtuple(args_w)
     return space.call(w_func, w_args_new, w_kwds)
 
+ at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
+def slot_tp_init(space, w_self, w_args, w_kwds):
+    w_descr = space.lookup(w_self, '__init__')
+    args = Arguments.frompacked(space, w_args, w_kwds)
+    space.get_and_call_args(w_descr, w_self, args)
+    return 0
+
 PyWrapperFlag_KEYWORDS = 1
 
 # adopted from typeobject.c

Modified: pypy/trunk/pypy/module/cpyext/test/foo.c
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/foo.c	(original)
+++ pypy/trunk/pypy/module/cpyext/test/foo.c	Sun May  9 11:10:01 2010
@@ -245,6 +245,65 @@
     0           /*tp_weaklist*/
 };
 
+PyTypeObject Fuu2Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "foo.fuu2",
+    sizeof(FuuObject),
+    0,
+    0,          /*tp_dealloc*/
+    0,          /*tp_print*/
+    0,          /*tp_getattr*/
+    0,          /*tp_setattr*/
+    0,          /*tp_compare*/
+    0,          /*tp_repr*/
+    0,          /*tp_as_number*/
+    0,          /*tp_as_sequence*/
+    0,          /*tp_as_mapping*/
+    0,          /*tp_hash */
+
+    0,          /*tp_call*/
+    0,          /*tp_str*/
+    0,          /*tp_getattro*/
+    0,          /*tp_setattro*/
+    0,          /*tp_as_buffer*/
+
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+    0,          /*tp_doc*/
+
+    0,          /*tp_traverse*/
+    0,          /*tp_clear*/
+
+    0,          /*tp_richcompare*/
+    0,          /*tp_weaklistoffset*/
+
+    0,          /*tp_iter*/
+    0,          /*tp_iternext*/
+
+    /* Attribute descriptor and subclassing stuff */
+
+    0,          /*tp_methods*/
+    0,          /*tp_members*/
+    0,          /*tp_getset*/
+    0,          /*tp_base*/
+    0,          /*tp_dict*/
+
+    0,          /*tp_descr_get*/
+    0,          /*tp_descr_set*/
+    0,          /*tp_dictoffset*/
+
+    0,          /*tp_init*/
+    0,          /*tp_alloc  will be set to PyType_GenericAlloc in module init*/
+    0,          /*tp_new*/
+    0,          /*tp_free  Low-level free-memory routine */
+    0,          /*tp_is_gc For PyObject_IS_GC */
+    0,          /*tp_bases*/
+    0,          /*tp_mro method resolution order */
+    0,          /*tp_cache*/
+    0,          /*tp_subclasses*/
+    0           /*tp_weaklist*/
+};
+
 
 /* foo functions */
 
@@ -277,11 +336,14 @@
     footype.tp_new = PyType_GenericNew;
 
     FuuType.tp_base = &PyUnicode_Type;
+    Fuu2Type.tp_base = &FuuType;
 
     if (PyType_Ready(&footype) < 0)
         return;
     if (PyType_Ready(&FuuType) < 0)
         return;
+    if (PyType_Ready(&Fuu2Type) < 0)
+        return;
     m = Py_InitModule("foo", foo_functions);
     if (m == NULL)
         return;
@@ -290,6 +352,7 @@
         if (PyDict_SetItemString(d, "fooType", (PyObject *)&footype) < 0)
             return;
         PyDict_SetItemString(d, "FuuType", (PyObject *) &FuuType);
+        PyDict_SetItemString(d, "Fuu2Type", (PyObject *) &Fuu2Type);
     }
        /* No need to check the error here, the caller will do that */
 }

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	Sun May  9 11:10:01 2010
@@ -113,7 +113,12 @@
         module = self.import_module(name="foo")
         newobj = module.FuuType()
         assert newobj.get_val() == 42
-        
+
+        # this subtype should inherit tp_init
+        newobj = module.Fuu2Type()
+        assert newobj.get_val() == 42
+
+        # this subclass redefines __init__
         class Fuu2(module.FuuType):
             def __init__(self):
                 self.foobar = 32

Modified: pypy/trunk/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/typeobject.py	Sun May  9 11:10:01 2010
@@ -293,16 +293,13 @@
         return w_obj
 
     # call tp_init
-    # XXX 1 w_obj_type should be used instead
-    pyo = make_ref(space, w_type)
+    pyo = make_ref(space, w_obj_type)
     pto = rffi.cast(PyTypeObjectPtr, pyo)
     try:
         if pto.c_tp_init:
-            generic_cpy_call(space, pto.c_tp_init, w_obj, w_args, w_kw)
-        else:
-            # XXX 2 this should not necessary: tp_init should be inherited
-            w_descr = space.lookup(w_obj, '__init__')
-            space.get_and_call_args(w_descr, w_obj, __args__)
+            if generic_cpy_call(space, pto.c_tp_init, w_obj, w_args, w_kw) < 0:
+                state = space.fromcache(State)
+                state.check_and_raise_exception()
     finally:
         Py_DecRef(space, pyo)
 
@@ -586,6 +583,8 @@
         base = rffi.cast(PyTypeObjectPtr, base_pyo)
         if not pto.c_tp_dealloc:
             pto.c_tp_dealloc = base.c_tp_dealloc
+        if not pto.c_tp_init:
+            pto.c_tp_init = base.c_tp_init
         if not pto.c_tp_alloc:
             pto.c_tp_alloc = base.c_tp_alloc
         # XXX check for correct GC flags!



More information about the Pypy-commit mailing list