Author: Faye Zhao <yufeiz...@google.com> Branch: Changeset: r81429:0c6b1683826d Date: 2015-12-22 13:54 -0800 http://bitbucket.org/pypy/pypy/changeset/0c6b1683826d/
Log: Expose tp_getattro for different builtin types. diff --git a/.cache/v/cache/lastfailed b/.cache/v/cache/lastfailed new file mode 100644 --- /dev/null +++ b/.cache/v/cache/lastfailed @@ -0,0 +1,3 @@ +{ + "pypy/module/cpyext/test/test_typeobject.py::AppTestSlots::()::test_binaryfunc": true +} \ No newline at end of file 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 @@ -380,6 +380,17 @@ space.call_function(delattr_fn, w_self, w_name) return 0 api_func = slot_tp_setattro.api_func + elif name == 'tp_getattro': + getattr_fn = w_type.getdictvalue(space, '__getattribute__') + if getattr_fn is None: + return + + @cpython_api([PyObject, PyObject], PyObject, + error=lltype.nullptr(rffi.VOIDP.TO), external=True) + @func_renamer("cpyext_tp_getattro_%s" % (typedef.name,)) + def slot_tp_getattro(space, w_self, w_name): + return space.call_function(getattr_fn, w_self, w_name) + api_func = slot_tp_getattro.api_func else: return 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 @@ -385,12 +385,55 @@ PyErr_SetString(PyExc_ValueError, "recursive tp_setattro"); return NULL; } + if (!args->ob_type->tp_getattro) + { + PyErr_SetString(PyExc_ValueError, "missing tp_getattro"); + return NULL; + } + if (args->ob_type->tp_getattro == + args->ob_type->tp_base->tp_getattro) + { + PyErr_SetString(PyExc_ValueError, "recursive tp_getattro"); + return NULL; + } Py_RETURN_TRUE; ''' ) ]) assert module.test_type(type(None)) + def test_tp_getattro(self): + module = self.import_extension('foo', [ + ("test_tp_getattro", "METH_VARARGS", + ''' + PyObject *obj = PyTuple_GET_ITEM(args, 0); + PyIntObject *value = PyTuple_GET_ITEM(args, 1); + if (!obj->ob_type->tp_getattro) + { + PyErr_SetString(PyExc_ValueError, "missing tp_getattro"); + return NULL; + } + PyObject *name = PyString_FromString("attr1"); + PyIntObject *attr1 = obj->ob_type->tp_getattro(obj, name); + if (attr1->ob_ival != value->ob_ival) + { + printf("attr1->ob_ival = %ld\\n", attr1->ob_ival); + printf("value->ob_ival = %ld\\n", value->ob_ival); + PyErr_SetString(PyExc_ValueError, + "tp_getattro returned wrong value"); + return NULL; + } + Py_DECREF(name); + Py_DECREF(attr1); + Py_RETURN_TRUE; + ''' + ) + ]) + class C: + def __init__(self): + self.attr1 = 123 + assert module.test_tp_getattro(C(), 123) + def test_nb_int(self): module = self.import_extension('foo', [ ("nb_int", "METH_O", 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 @@ -582,6 +582,8 @@ pto.c_tp_free = base.c_tp_free if not pto.c_tp_setattro: pto.c_tp_setattro = base.c_tp_setattro + if not pto.c_tp_getattro: + pto.c_tp_getattro = base.c_tp_getattro finally: Py_DecRef(space, base_pyo) @@ -651,6 +653,12 @@ PyObject_GenericSetAttr.api_func.functype, PyObject_GenericSetAttr.api_func.get_wrapper(space)) + if not pto.c_tp_getattro: + from pypy.module.cpyext.object import PyObject_GenericGetAttr + pto.c_tp_getattro = llhelper( + PyObject_GenericGetAttr.api_func.functype, + PyObject_GenericGetAttr.api_func.get_wrapper(space)) + if w_obj.is_cpytype(): Py_DecRef(space, pto.c_tp_dict) w_dict = w_obj.getdict(space) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit