[pypy-commit] pypy missing-tp_new: add test that passes when pure python __new__ is called, fails with tp_new

mattip pypy.commits at gmail.com
Sat Oct 29 14:30:38 EDT 2016


Author: Matti Picus <matti.picus at gmail.com>
Branch: missing-tp_new
Changeset: r87989:c5e8d9f4e473
Date: 2016-10-29 21:29 +0300
http://bitbucket.org/pypy/pypy/changeset/c5e8d9f4e473/

Log:	add test that passes when pure python __new__ is called, fails with
	tp_new

diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -2,6 +2,7 @@
 from rpython.rtyper.lltypesystem import rffi
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.api import generic_cpy_call
 from pypy.module.cpyext.pyobject import make_ref, from_ref
 from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 
@@ -429,6 +430,32 @@
         ref = make_ref(space, w_obj)
         api.Py_DecRef(ref)
 
+    def test_tp_new_from_python(self, space, api):
+        w_date = space.appexec([], """():
+            class Date(object):
+                def __new__(cls, year, month, day):
+                    self = object.__new__(cls)
+                    self.year = year
+                    self.month = month
+                    self.day = day
+                    return self
+            return Date
+            """)
+        py_datetype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_date))
+        one = space.newint(1)
+        arg = space.newtuple([one, one, one])
+        # call w_date.__new__
+        w_obj = space.call_function(w_date, one, one, one)
+        w_year = space.getattr(w_obj, space.newbytes('year'))
+        assert space.int_w(w_year) == 1
+
+        # currently fails with "object() takse no parameters,
+        # from the tp_new of space.w_object
+        w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, 
+                                 arg, space.newdict({}))
+        w_year = space.getattr(w_obj, space.newbytes('year'))
+        assert space.int_w(w_year) == 1
+
 class AppTestSlots(AppTestCpythonExtensionBase):
     def setup_class(cls):
         AppTestCpythonExtensionBase.setup_class.im_func(cls)
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -247,9 +247,6 @@
     # coming from a parent C type.
 
     typedef = w_type.layout.typedef
-    if w_type is not space.w_object:
-        # XXX fix, to prevent problems with slot lookups
-        assert typedef is not space.w_object.layout.typedef
     for method_name, slot_name, slot_names, slot_func in slotdefs_for_tp_slots:
         w_descr = w_type.lookup(method_name)
         if w_descr is None:
@@ -259,6 +256,12 @@
         slot_func_helper = None
 
         if slot_func is None and typedef is not None:
+            # XXX note that the w_type is retrieved inside this call via
+            # w_type = space.gettypeobject(typedef)
+            if w_type.name == 'Date' and slot_name == 'tp_new':
+                name = space.gettypeobject(typedef).name
+                print 'w_type inside build_slot_tp_function is "%s", wanted "%s"' %(
+                        name, w_type.name)
             get_slot = get_slot_tp_function(space, typedef, slot_name)
             if get_slot:
                 slot_func_helper = get_slot()


More information about the pypy-commit mailing list