[pypy-commit] pypy missing-tp_new: hack around a missing "self" argument in slot_tp_new

mattip pypy.commits at gmail.com
Wed Nov 16 03:50:03 EST 2016


Author: Matti Picus <matti.picus at gmail.com>
Branch: missing-tp_new
Changeset: r88404:48bcbfaa8980
Date: 2016-11-16 10:13 +0200
http://bitbucket.org/pypy/pypy/changeset/48bcbfaa8980/

Log:	hack around a missing "self" argument in slot_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
@@ -1003,7 +1003,8 @@
         import datetime
         module = self.import_module(name='foo3')
         module.footype("X", (object,), {})
-        module.datetimetype(1, 1, 1)
+        a = module.datetimetype(1, 1, 1)
+        assert isinstance(a, module.datetimetype)
 
     def test_app_subclass_of_c_type(self):
         import sys
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
@@ -309,6 +309,8 @@
                     STRUCT_TYPE = PySequenceMethods
                 elif slot_names[0] == 'c_tp_as_buffer':
                     STRUCT_TYPE = PyBufferProcs
+                elif slot_names[0] == 'c_tp_as_mapping':
+                    STRUCT_TYPE = PyMappingMethods
                 else:
                     raise AssertionError(
                         "Structure not allocated: %s" % (slot_names[0],))
diff --git a/pypy/module/cpyext/userslot.py b/pypy/module/cpyext/userslot.py
--- a/pypy/module/cpyext/userslot.py
+++ b/pypy/module/cpyext/userslot.py
@@ -30,8 +30,20 @@
 
 @cpython_api([PyTypeObjectPtr, PyObject, PyObject], PyObject, header=None)
 def slot_tp_new(space, w_type, w_args, w_kwds):
-    w_impl = space.getattr(w_type, space.wrap('__new__'))
-    import pdb;pdb.set_trace()
+    # XXX problem - we need to find the actual __new__ function to call.
+    #     but we have no 'self' argument. Theoretically, self will be
+    #     w_type, but if w_type is a subclass of self, and w_type has a
+    #     __new__ function that calls super().__new__, and that call ends
+    #     up here, we will get infinite recursion. Prevent the recursion
+    #     in the simple case (from cython) where w_type is a cpytype, but
+    #     we know (since we are in this function) that self is not a cpytype
+    from pypy.module.cpyext.typeobject import W_PyCTypeObject
+    w_type0 = w_type
+    w_mro = space.listview(space.getattr(w_type0, space.wrap('__mro__')))
+    while w_type0.is_cpytype():
+        w_type0 = w_mro[1]
+        w_mro = space.listview(space.getattr(w_type0, space.wrap('__mro__')))
+    w_impl = space.getattr(w_type0, space.wrap('__new__'))
     args = Arguments(space, [w_type],
                      w_stararg=w_args, w_starstararg=w_kwds)
     return space.call_args(w_impl, args)


More information about the pypy-commit mailing list