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