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

afa at codespeak.net afa at codespeak.net
Fri May 7 14:17:47 CEST 2010


Author: afa
Date: Fri May  7 14:17:46 2010
New Revision: 74432

Modified:
   pypy/trunk/pypy/module/cpyext/stubs.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 and test tp_new_wrapper,
it works at least when tp_new=PyType_GenericNew


Modified: pypy/trunk/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/stubs.py	(original)
+++ pypy/trunk/pypy/module/cpyext/stubs.py	Fri May  7 14:17:46 2010
@@ -3058,10 +3058,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyTypeObjectPtr, PyObject, PyObject], PyObject)
-def PyType_GenericNew(space, type, args, kwds):
-    raise NotImplementedError
-
 @cpython_api([], rffi.INT_real, error=CANNOT_FAIL)
 def PyUnicode_ClearFreeList(space, ):
     """Clear the free list. Return the total number of freed items.

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	Fri May  7 14:17:46 2010
@@ -175,12 +175,6 @@
     {NULL}  /* Sentinel */
 };
 
-static PyObject *
-Fuu_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
-{
-  return subtype->tp_alloc(subtype, 0);
-}
-
 PyTypeObject FuuType = {
     PyObject_HEAD_INIT(NULL)
     0,
@@ -230,7 +224,7 @@
 
     0,          /*tp_init*/
     0,          /*tp_alloc  will be set to PyType_GenericAlloc in module init*/
-    Fuu_new,    /*tp_new*/
+    0,          /*tp_new*/
     0,          /*tp_free  Low-level free-memory routine */
     0,          /*tp_is_gc For PyObject_IS_GC */
     0,          /*tp_bases*/
@@ -269,10 +263,8 @@
 {
     PyObject *m, *d;
 
-    footype.ob_type = &PyType_Type;
+    footype.tp_new = PyType_GenericNew;
 
-    /* Workaround for quirk in Visual Studio, see
-        <http://www.python.it/faq/faq-3.html#3.24> */
     FuuType.tp_base = &PyUnicode_Type;
 
     if (PyType_Ready(&footype) < 0)

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	Fri May  7 14:17:46 2010
@@ -90,19 +90,18 @@
         raises(TypeError, "obj.char_member = 42")
 
     def test_new(self):
-        skip("skip")
         module = self.import_module(name='foo')
         obj = module.new()
         # call __new__
         newobj = module.FuuType(u"xyz")
         assert newobj == u"xyz"
+        assert isinstance(newobj, module.FuuType)
 
-        a = module.fooType
-        assert "cannot create" in raises(TypeError, "a()").value.message
+        assert isinstance(module.fooType(), module.fooType)
         class bar(module.fooType):
-            def baz(self):
-                return self
-        assert "cannot create" in raises(TypeError, "bar()").value.message
+            pass
+        assert isinstance(bar(), bar)
+
         fuu = module.FuuType
         class fuu2(fuu):
             def baz(self):

Modified: pypy/trunk/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/typeobject.py	Fri May  7 14:17:46 2010
@@ -156,11 +156,24 @@
         add_tp_new_wrapper(space, dict_w, pto)
 
 @cpython_api([PyObject, PyObject, PyObject], PyObject, external=False)
-def tp_new_wrapper(space, w_self, w_args, w_kwds):
-    fn = rffi.cast(PyTypeObjectPtr, make_ref(space, w_self)).c_tp_new
-    pyo = make_ref(space, w_self)
-    pto = rffi.cast(PyTypeObjectPtr, pyo)
-    return generic_cpy_call(space, fn, pto, w_args, w_kwds)
+def tp_new_wrapper(space, self, w_args, w_kwds):
+    tp_new = rffi.cast(PyTypeObjectPtr, self).c_tp_new
+
+    # Check that the user doesn't do something silly and unsafe like
+    # object.__new__(dict).  To do this, we check that the most
+    # derived base that's not a heap type is this type.
+    # XXX do it
+
+    args_w = space.fixedview(w_args)
+    w_subtype = args_w[0]
+    w_args = space.newtuple(args_w[1:])
+
+    subtype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_subtype))
+    try:
+        obj = generic_cpy_call(space, tp_new, subtype, w_args, w_kwds)
+    finally:
+        Py_DecRef(space, w_subtype)
+    return obj
 
 @specialize.memo()
 def get_new_method_def(space):
@@ -630,8 +643,12 @@
 
 @cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject)
 def PyType_GenericAlloc(space, type, nitems):
-    """This function used an int type for nitems. This might require
-    changes in your code for properly supporting 64-bit systems."""
     from pypy.module.cpyext.object import _PyObject_NewVar
     return _PyObject_NewVar(space, type, nitems)
 
+ at cpython_api([PyTypeObjectPtr, PyObject, PyObject], PyObject)
+def PyType_GenericNew(space, type, w_args, w_kwds):
+    return generic_cpy_call(
+        space, type.c_tp_alloc, type, 0)
+
+



More information about the Pypy-commit mailing list