Author: Ronan Lamy <ronan.l...@gmail.com> Branch: Changeset: r93900:276b2e484fdf Date: 2018-02-27 22:59 +0000 http://bitbucket.org/pypy/pypy/changeset/276b2e484fdf/
Log: Do overwrite existing slot in fill_slot(): otherwise subclasses can't overrride their parents' slots. Reverts e61e2f4a32fa Fixes issue #2760 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 @@ -648,6 +648,33 @@ self.attr1 = 123 assert module.test_tp_getattro(C(), 123) + def test_issue_2760_getattr(self): + module = self.import_extension('foo', [ + ("get_foo", "METH_O", + ''' + char* name = "foo"; + PyTypeObject *tp = Py_TYPE(args); + PyObject *res; + if (tp->tp_getattr != NULL) { + res = (*tp->tp_getattr)(args, name); + } + else if (tp->tp_getattro != NULL) { + PyObject *w = PyString_FromString(name); + res = (*tp->tp_getattro)(args, w); + Py_DECREF(w); + } + else { + res = Py_None; + } + return res; + ''')]) + class Passthrough(object): + def __getattr__(self, name): + return name + + obj = Passthrough() + assert module.get_foo(obj) == 'foo' + def test_nb_int(self): module = self.import_extension('foo', [ ("nb_int", "METH_VARARGS", 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 @@ -236,11 +236,6 @@ def update_all_slots(space, w_type, pto): # fill slots in pto - # Not very sure about it, but according to - # test_call_tp_dealloc, we should not - # overwrite slots that are already set: these ones are probably - # coming from a parent C type. - for method_name, slot_name, slot_names, slot_apifunc in slotdefs_for_tp_slots: slot_func_helper = None w_descr = w_type.dict_w.get(method_name, None) @@ -276,8 +271,7 @@ def fill_slot(space, pto, w_type, slot_names, slot_func_helper): # XXX special case wrapper-functions and use a "specific" slot func if len(slot_names) == 1: - if not getattr(pto, slot_names[0]): - setattr(pto, slot_names[0], slot_func_helper) + setattr(pto, slot_names[0], slot_func_helper) elif ((w_type is space.w_list or w_type is space.w_tuple) and slot_names[0] == 'c_tp_as_number'): # XXX hack - how can we generalize this? The problem is method @@ -311,8 +305,7 @@ struct = lltype.malloc(STRUCT_TYPE, flavor='raw', zero=True) setattr(pto, slot_names[0], struct) - if not getattr(struct, slot_names[1]): - setattr(struct, slot_names[1], slot_func_helper) + setattr(struct, slot_names[1], slot_func_helper) def add_operators(space, dict_w, pto): from pypy.module.cpyext.object import PyObject_HashNotImplemented _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit