[pypy-commit] pypy release-pypy2.7-5.x: Issue #2523
arigo
pypy.commits at gmail.com
Tue Mar 28 15:23:40 EDT 2017
Author: Armin Rigo <arigo at tunes.org>
Branch: release-pypy2.7-5.x
Changeset: r90851:32cd8a5d7221
Date: 2017-03-28 22:17 +0300
http://bitbucket.org/pypy/pypy/changeset/32cd8a5d7221/
Log: Issue #2523
This should fix it. The slotdefs entry was removed in 1b0451031b2e
but we didn't have any test for that. (grafted from
f77701c9f5706a297821c43779219df4a0aa70b0)
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
@@ -1032,6 +1032,7 @@
TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
TPSLOT("__getattr__", tp_getattro, slot_tp_getattr, NULL, ""),
+ TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
"x.__setattr__('name', value) <==> x.name = value"),
TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
diff --git a/pypy/module/cpyext/test/foo.c b/pypy/module/cpyext/test/foo.c
--- a/pypy/module/cpyext/test/foo.c
+++ b/pypy/module/cpyext/test/foo.c
@@ -670,6 +670,34 @@
return PyInt_FromLong(tf);
}
+static PyTypeObject GetType1 = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "foo.GetType1", /*tp_name*/
+ sizeof(PyObject), /*tp_size*/
+};
+static PyTypeObject GetType2 = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "foo.GetType2", /*tp_name*/
+ sizeof(PyObject), /*tp_size*/
+};
+static PyObject *gettype1, *gettype2;
+
+static PyObject *gettype1_getattr(PyObject *self, char *name)
+{
+ char buf[200];
+ strcpy(buf, "getattr:");
+ strcat(buf, name);
+ return PyString_FromString(buf);
+}
+static PyObject *gettype2_getattro(PyObject *self, PyObject *name)
+{
+ char buf[200];
+ strcpy(buf, "getattro:");
+ strcat(buf, PyString_AS_STRING(name));
+ return PyString_FromString(buf);
+}
+
+
/* List of functions exported by this module */
static PyMethodDef foo_functions[] = {
@@ -769,6 +797,18 @@
if (PyType_Ready(&TupleLike) < 0)
INITERROR;
+ GetType1.tp_flags = Py_TPFLAGS_DEFAULT;
+ GetType1.tp_getattr = &gettype1_getattr;
+ if (PyType_Ready(&GetType1) < 0)
+ INITERROR;
+ gettype1 = PyObject_New(PyObject, &GetType1);
+
+ GetType2.tp_flags = Py_TPFLAGS_DEFAULT;
+ GetType2.tp_getattro = &gettype2_getattro;
+ if (PyType_Ready(&GetType2) < 0)
+ INITERROR;
+ gettype2 = PyObject_New(PyObject, &GetType2);
+
d = PyModule_GetDict(module);
if (d == NULL)
@@ -791,6 +831,10 @@
INITERROR;
if (PyDict_SetItemString(d, "TupleLike", (PyObject *) &TupleLike) < 0)
INITERROR;
+ if (PyDict_SetItemString(d, "gettype1", gettype1) < 0)
+ INITERROR;
+ if (PyDict_SetItemString(d, "gettype2", gettype2) < 0)
+ INITERROR;
#if PY_MAJOR_VERSION >=3
return module;
#endif
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
@@ -1245,3 +1245,14 @@
pass
bases = module.foo(C)
assert bases == (A, B)
+
+ def test_getattr_getattro(self):
+ module = self.import_module(name='foo')
+ assert module.gettype2.dcba == 'getattro:dcba'
+ assert (type(module.gettype2).__getattribute__(module.gettype2, 'dcBA')
+ == 'getattro:dcBA')
+ assert module.gettype1.abcd == 'getattr:abcd'
+ # GetType1 objects have a __getattribute__ method, but this
+ # doesn't call tp_getattr at all, also on CPython
+ raises(AttributeError, type(module.gettype1).__getattribute__,
+ module.gettype1, 'dcBA')
More information about the pypy-commit
mailing list