Author: Matti Picus <matti.pi...@gmail.com>
Branch: cpyext-null-slots
Changeset: r87375:c85aef87f0df
Date: 2016-09-25 15:37 +0300
http://bitbucket.org/pypy/pypy/changeset/c85aef87f0df/

Log:    cpython compatible slot lookup does not traverse mro, implement and
        ensure slots are filled at PyType_Ready

diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -40,7 +40,7 @@
 def _PyObject_New(space, type):
     return _PyObject_NewVar(space, type, 0)
 
-@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True)
+@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyVarObject, result_is_ll=True)
 def _PyObject_NewVar(space, type, itemcount):
     w_type = from_ref(space, rffi.cast(PyObject, type))
     assert isinstance(w_type, W_TypeObject)
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -453,6 +453,23 @@
             api_func = slot_func.api_func
             handled = True
 
+    # unary functions returning Py_ssize_t
+    for tp_name, attr in [('tp_as_sequence.c_sq_length', '__len__'),
+                          #('tp_as_mapping.c_mp_length', '__len__'),
+                          ]:
+        if name == tp_name:
+            slot_fn = w_type.getdictvalue(space, attr)
+            if slot_fn is None:
+                return
+
+            @cpython_api([PyObject], Py_ssize_t, header=header, error=-1)
+            @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), 
typedef.name))
+            def slot_func(space, w_self):
+                ret = space.call_function(slot_fn, w_self)
+                return space.int_w(ret)
+            api_func = slot_func.api_func
+            handled = True
+
     # binary functions
     for tp_name, attr in [('tp_as_number.c_nb_add', '__add__'),
                           ('tp_as_number.c_nb_subtract', '__sub__'),
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -480,6 +480,7 @@
         a = module.newsubstr('abc')
         assert type(a).__name__ == 'string_'
         assert a == 'abc'
+        assert str(a) == 'abc'
         #print type(a).mro(type(a))
         raises(ValueError, int, a)
 
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
@@ -479,6 +479,10 @@
         if pto.c_tp_doc:
             self.w_doc = space.wrap(rffi.charp2str(pto.c_tp_doc))
 
+    def lookup(self, name):
+        # do not traverse the mro, look only in self
+        return self.getdictvalue(self.space, name)
+
 @bootstrap_function
 def init_typeobject(space):
     make_typedescr(space.w_type.layout.typedef,
@@ -819,15 +823,24 @@
     # inheriting tp_as_* slots
     base = py_type.c_tp_base
     if base:
+        remap_slots = False
         if not py_type.c_tp_as_number: 
             py_type.c_tp_as_number = base.c_tp_as_number
             py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_CHECKTYPES
             py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
+            remap_slots = True
         if not py_type.c_tp_as_sequence:
             py_type.c_tp_as_sequence = base.c_tp_as_sequence
             py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
-        if not py_type.c_tp_as_mapping: py_type.c_tp_as_mapping = 
base.c_tp_as_mapping
-        if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer = 
base.c_tp_as_buffer
+            remap_slots = True
+        if not py_type.c_tp_as_mapping:
+            py_type.c_tp_as_mapping = base.c_tp_as_mapping
+            remap_slots = True
+        if not py_type.c_tp_as_buffer:
+            py_type.c_tp_as_buffer = base.c_tp_as_buffer
+            remap_slots = True
+        if remap_slots:
+            add_operators(space, w_obj.dict_w, py_type)
 
     return w_obj
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to