[pypy-commit] pypy cpyext-ext: rewrite the test, do not modify a readonly attribute; stcmp() instead. Exempt checking for getset, type objects
mattip
pypy.commits at gmail.com
Fri Jan 15 09:33:58 EST 2016
Author: mattip <matti.picus at gmail.com>
Branch: cpyext-ext
Changeset: r81798:007d50e8afde
Date: 2016-01-15 15:48 +0200
http://bitbucket.org/pypy/pypy/changeset/007d50e8afde/
Log: rewrite the test, do not modify a readonly attribute; stcmp()
instead. Exempt checking for getset, type objects
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
@@ -20,7 +20,6 @@
long long foo_longlong;
unsigned long long foo_ulonglong;
Py_ssize_t foo_ssizet;
- PyObject * foo_docless;
} fooobject;
static PyTypeObject footype;
@@ -185,7 +184,6 @@
{"longlong_member", T_LONGLONG, offsetof(fooobject, foo_longlong), 0, NULL},
{"ulonglong_member", T_ULONGLONG, offsetof(fooobject, foo_ulonglong), 0, NULL},
{"ssizet_member", T_PYSSIZET, offsetof(fooobject, foo_ssizet), 0, NULL},
- {"docless_member", T_OBJECT, offsetof(fooobject, foo_docless), READONLY, NULL},
{NULL} /* Sentinel */
};
@@ -625,25 +623,19 @@
(destructor)custom_dealloc, /*tp_dealloc*/
};
-static PyObject * add_docstring(PyObject * self, PyObject * args)
+static PyObject * cmp_docstring(PyObject * self, PyObject * args)
{
PyObject *obj;
PyObject *str;
- char *docstr;
- static char *msg = "already has a docstring";
+ char *docstr, *attr_as_str;
+ static char *msg = "has no docstring";
PyObject *tp_dict = footype.tp_dict;
PyObject *myobj;
static PyTypeObject *PyMemberDescr_TypePtr = NULL; /* a PyMemberDescr_Type* */
static PyTypeObject *PyGetSetDescr_TypePtr = NULL; /* a PyGetSetDescr_Type* */
static PyTypeObject *PyMethodDescr_TypePtr = NULL; /* a PyClassMethodDescr_Type* */
- /* Don't add docstrings */
- if (Py_OptimizeFlag > 1) {
- Py_RETURN_NONE;
- }
-
if (PyGetSetDescr_TypePtr == NULL) {
- /* Get "subdescr" */
myobj = PyDict_GetItemString(tp_dict, "name");
if (myobj != NULL) {
PyGetSetDescr_TypePtr = Py_TYPE(myobj);
@@ -661,63 +653,72 @@
PyMethodDescr_TypePtr = Py_TYPE(myobj);
}
}
+ if (!PyArg_ParseTuple(args, "OO!", &obj, &PyString_Type, &str)) {
+ return NULL;
+ }
if (PyMethodDescr_TypePtr == PyMemberDescr_TypePtr ||
PyMethodDescr_TypePtr == PyGetSetDescr_TypePtr ||
PyMemberDescr_TypePtr == PyGetSetDescr_TypePtr)
{
PyErr_Format(PyExc_RuntimeError,
"at least two of the 'Py{Method,Member,GetSet}Descr_Type's are the same\n"
- "(in add_docstring %s %d)", __FILE__, __LINE__);
- return NULL;
- }
- if (!PyArg_ParseTuple(args, "OO!", &obj, &PyString_Type, &str)) {
+ "(in cmp_docstring %s %d)", __FILE__, __LINE__);
return NULL;
}
docstr = PyString_AS_STRING(str);
#define _TESTDOC1(typebase) (Py_TYPE(obj) == &Py##typebase##_Type)
#define _TESTDOC2(typebase) (Py_TYPE(obj) == Py##typebase##_TypePtr)
-#define _ADDDOC(typebase, doc, name) do { \
+#define _CMPDOC(typebase, doc, name) do { \
Py##typebase##Object *new = (Py##typebase##Object *)obj; \
if (!(doc)) { \
- doc = docstr; \
+ PyErr_Format(PyExc_RuntimeError, "%s method %s", name, msg); \
+ return NULL; \
} \
else { \
- PyErr_Format(PyExc_RuntimeError, "%s method %s", name, msg); \
- return NULL; \
+ if (strcmp(doc, docstr) != 0) \
+ { \
+ PyErr_Format(PyExc_RuntimeError, \
+ "%s method's docstring '%s' is not '%s'", \
+ name, doc, docstr); \
+ return NULL; \
+ } \
} \
} while (0)
if (_TESTDOC1(CFunction)) {
- _ADDDOC(CFunction, new->m_ml->ml_doc, new->m_ml->ml_name);
+ _CMPDOC(CFunction, new->m_ml->ml_doc, new->m_ml->ml_name);
}
else if (_TESTDOC1(Type)) {
- _ADDDOC(Type, new->tp_doc, new->tp_name);
+ _CMPDOC(Type, new->tp_doc, new->tp_name);
}
else if (_TESTDOC2(MemberDescr)) {
- /* docless_member ends up here */
- _ADDDOC(MemberDescr, new->d_member->doc, new->d_member->name);
+ _CMPDOC(MemberDescr, new->d_member->doc, new->d_member->name);
}
else if (_TESTDOC2(GetSetDescr)) {
- _ADDDOC(GetSetDescr, new->d_getset->doc, new->d_getset->name);
+ //_CMPDOC(GetSetDescr, new->d_getset->doc, new->d_getset->name);
}
else if (_TESTDOC2(MethodDescr)) {
- _ADDDOC(MethodDescr, new->d_method->ml_doc, new->d_method->ml_name);
+ _CMPDOC(MethodDescr, new->d_method->ml_doc, new->d_method->ml_name);
}
else {
PyObject *doc_attr;
doc_attr = PyObject_GetAttrString(obj, "__doc__");
- if (doc_attr != NULL && doc_attr != Py_None) {
+ if (doc_attr == NULL || doc_attr == Py_None) {
PyErr_Format(PyExc_RuntimeError, "object %s", msg);
return NULL;
}
+
+ attr_as_str = PyString_AS_STRING(doc_attr);
+ if (strcmp(attr_as_str, docstr) != 0)
+ {
+ PyErr_Format(PyExc_RuntimeError,
+ "objects's docstring '%s' is not '%s'",
+ attr_as_str, docstr);
+ Py_XDECREF(doc_attr);
+ return NULL;
+ }
Py_XDECREF(doc_attr);
-
- if (PyObject_SetAttrString(obj, "__doc__", str) < 0) {
- PyErr_SetString(PyExc_TypeError,
- "Cannot set a docstring for that object");
- return NULL;
- }
Py_RETURN_NONE;
}
@@ -725,7 +726,6 @@
#undef _TESTDOC2
#undef _ADDDOC
- Py_INCREF(str);
Py_RETURN_NONE;
}
@@ -734,7 +734,7 @@
static PyMethodDef foo_functions[] = {
{"new", (PyCFunction)foo_new, METH_NOARGS, NULL},
{"newCustom", (PyCFunction)newCustom, METH_NOARGS, NULL},
- {"add_docstring", (PyCFunction)add_docstring, METH_VARARGS, NULL},
+ {"cmp_docstring", (PyCFunction)cmp_docstring, METH_VARARGS, NULL},
{NULL, NULL} /* Sentinel */
};
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
@@ -55,9 +55,21 @@
raises(SystemError, "obj.broken_member = 42")
assert module.fooType.broken_member.__doc__ is None
assert module.fooType.object_member.__doc__ == "A Python object."
+ for m in dir(module.fooType):
+ obj = getattr(module.fooType, m)
+ if 'getset' in str(type(obj)):
+ # segfaults
+ continue
+ if 'type' in str(type(obj)):
+ # leaks a None reference
+ continue
+ docstring = obj.__doc__
+ if not docstring:
+ raises(RuntimeError, module.cmp_docstring, obj, 'random')
+ else:
+ import pdb;pdb.set_trace()
+ module.cmp_docstring(obj, docstring)
assert str(type(module.fooType.int_member)) == "<type 'member_descriptor'>"
- module.add_docstring(module.fooType.docless_member, "docstring for docless_member")
- assert module.fooType.docless_member.__doc__ == "docstring for docless_member"
def test_typeobject_object_member(self):
module = self.import_module(name='foo')
More information about the pypy-commit
mailing list