use __qualname__ to compute bound method repr (closes #21389)

Patch from Steven Barker.
This commit is contained in:
Benjamin Peterson 2014-08-20 18:41:57 -05:00
parent 2b7ccbda90
commit 48ad7c0b01
4 changed files with 75 additions and 33 deletions

View file

@ -15,6 +15,7 @@ static int numfree = 0;
#endif
_Py_IDENTIFIER(__name__);
_Py_IDENTIFIER(__qualname__);
PyObject *
PyMethod_Function(PyObject *im)
@ -243,51 +244,33 @@ method_repr(PyMethodObject *a)
{
PyObject *self = a->im_self;
PyObject *func = a->im_func;
PyObject *klass;
PyObject *funcname = NULL ,*klassname = NULL, *result = NULL;
char *defname = "?";
PyObject *funcname = NULL, *result = NULL;
const char *defname = "?";
if (self == NULL) {
PyErr_BadInternalCall();
return NULL;
}
klass = (PyObject*)Py_TYPE(self);
funcname = _PyObject_GetAttrId(func, &PyId___name__);
funcname = _PyObject_GetAttrId(func, &PyId___qualname__);
if (funcname == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return NULL;
PyErr_Clear();
funcname = _PyObject_GetAttrId(func, &PyId___name__);
if (funcname == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return NULL;
PyErr_Clear();
}
}
else if (!PyUnicode_Check(funcname)) {
if (funcname != NULL && !PyUnicode_Check(funcname)) {
Py_DECREF(funcname);
funcname = NULL;
}
if (klass == NULL)
klassname = NULL;
else {
klassname = _PyObject_GetAttrId(klass, &PyId___name__);
if (klassname == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
Py_XDECREF(funcname);
return NULL;
}
PyErr_Clear();
}
else if (!PyUnicode_Check(klassname)) {
Py_DECREF(klassname);
klassname = NULL;
}
}
/* XXX Shouldn't use repr()/%R here! */
result = PyUnicode_FromFormat("<bound method %V.%V of %R>",
klassname, defname,
result = PyUnicode_FromFormat("<bound method %V of %R>",
funcname, defname, self);
Py_XDECREF(funcname);
Py_XDECREF(klassname);
return result;
}