Kaydet (Commit) d7fb7644 authored tarafından Walter Dörwald's avatar Walter Dörwald

Add a format specifier %V to PyUnicode_FromFormat(), that works similar to %U,

but requires an additional char * that will be used if the unicode object is
NULL.

Use %V in descrobject.c and classobject.c.
üst 3ef72bb0
...@@ -227,7 +227,7 @@ method_repr(PyMethodObject *a) ...@@ -227,7 +227,7 @@ method_repr(PyMethodObject *a)
PyObject *func = a->im_func; PyObject *func = a->im_func;
PyObject *klass = a->im_class; PyObject *klass = a->im_class;
PyObject *funcname = NULL, *klassname = NULL, *result = NULL; PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
char *sfuncname = "?", *sklassname = "?"; char *defname = "?";
funcname = PyObject_GetAttrString(func, "__name__"); funcname = PyObject_GetAttrString(func, "__name__");
if (funcname == NULL) { if (funcname == NULL) {
...@@ -239,8 +239,6 @@ method_repr(PyMethodObject *a) ...@@ -239,8 +239,6 @@ method_repr(PyMethodObject *a)
Py_DECREF(funcname); Py_DECREF(funcname);
funcname = NULL; funcname = NULL;
} }
else
sfuncname = PyUnicode_AsString(funcname);
if (klass == NULL) if (klass == NULL)
klassname = NULL; klassname = NULL;
else { else {
...@@ -254,16 +252,16 @@ method_repr(PyMethodObject *a) ...@@ -254,16 +252,16 @@ method_repr(PyMethodObject *a)
Py_DECREF(klassname); Py_DECREF(klassname);
klassname = NULL; klassname = NULL;
} }
else
sklassname = PyUnicode_AsString(klassname);
} }
if (self == NULL) if (self == NULL)
result = PyUnicode_FromFormat("<unbound method %s.%s>", result = PyUnicode_FromFormat("<unbound method %V.%V>",
sklassname, sfuncname); klassname, defname,
funcname, defname);
else { else {
/* XXX Shouldn't use repr()/%R here! */ /* XXX Shouldn't use repr()/%R here! */
result = PyUnicode_FromFormat("<bound method %s.%s of %R>", result = PyUnicode_FromFormat("<bound method %V.%V of %R>",
sklassname, sfuncname, self); klassname, defname,
funcname, defname, self);
} }
Py_XDECREF(funcname); Py_XDECREF(funcname);
Py_XDECREF(klassname); Py_XDECREF(klassname);
......
...@@ -12,51 +12,50 @@ descr_dealloc(PyDescrObject *descr) ...@@ -12,51 +12,50 @@ descr_dealloc(PyDescrObject *descr)
PyObject_GC_Del(descr); PyObject_GC_Del(descr);
} }
static char * static PyObject *
descr_name(PyDescrObject *descr) descr_name(PyDescrObject *descr)
{ {
if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
return PyUnicode_AsString(descr->d_name); return descr->d_name;
else if (descr->d_name != NULL && PyString_Check(descr->d_name)) return NULL;
/* XXX this should not happen */
return PyString_AS_STRING(descr->d_name);
else
return "?";
} }
static PyObject * static PyObject *
descr_repr(PyDescrObject *descr, char *format) descr_repr(PyDescrObject *descr, char *format)
{ {
return PyUnicode_FromFormat(format, descr_name(descr), PyObject *name = NULL;
descr->d_type->tp_name); if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
name = descr->d_name;
return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
} }
static PyObject * static PyObject *
method_repr(PyMethodDescrObject *descr) method_repr(PyMethodDescrObject *descr)
{ {
return descr_repr((PyDescrObject *)descr, return descr_repr((PyDescrObject *)descr,
"<method '%s' of '%s' objects>"); "<method '%V' of '%s' objects>");
} }
static PyObject * static PyObject *
member_repr(PyMemberDescrObject *descr) member_repr(PyMemberDescrObject *descr)
{ {
return descr_repr((PyDescrObject *)descr, return descr_repr((PyDescrObject *)descr,
"<member '%s' of '%s' objects>"); "<member '%V' of '%s' objects>");
} }
static PyObject * static PyObject *
getset_repr(PyGetSetDescrObject *descr) getset_repr(PyGetSetDescrObject *descr)
{ {
return descr_repr((PyDescrObject *)descr, return descr_repr((PyDescrObject *)descr,
"<attribute '%s' of '%s' objects>"); "<attribute '%V' of '%s' objects>");
} }
static PyObject * static PyObject *
wrapperdescr_repr(PyWrapperDescrObject *descr) wrapperdescr_repr(PyWrapperDescrObject *descr)
{ {
return descr_repr((PyDescrObject *)descr, return descr_repr((PyDescrObject *)descr,
"<slot wrapper '%s' of '%s' objects>"); "<slot wrapper '%V' of '%s' objects>");
} }
static int static int
...@@ -69,9 +68,9 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) ...@@ -69,9 +68,9 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
} }
if (!PyObject_TypeCheck(obj, descr->d_type)) { if (!PyObject_TypeCheck(obj, descr->d_type)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%s' for '%s' objects " "descriptor '%V' for '%s' objects "
"doesn't apply to '%s' object", "doesn't apply to '%s' object",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name, descr->d_type->tp_name,
obj->ob_type->tp_name); obj->ob_type->tp_name);
*pres = NULL; *pres = NULL;
...@@ -90,27 +89,27 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) ...@@ -90,27 +89,27 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
else { else {
/* Wot - no type?! */ /* Wot - no type?! */
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%s' for type '%s' " "descriptor '%V' for type '%s' "
"needs either an object or a type", "needs either an object or a type",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name); descr->d_type->tp_name);
return NULL; return NULL;
} }
} }
if (!PyType_Check(type)) { if (!PyType_Check(type)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%s' for type '%s' " "descriptor '%V' for type '%s' "
"needs a type, not a '%s' as arg 2", "needs a type, not a '%s' as arg 2",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name, descr->d_type->tp_name,
type->ob_type->tp_name); type->ob_type->tp_name);
return NULL; return NULL;
} }
if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%s' for type '%s' " "descriptor '%V' for type '%s' "
"doesn't apply to type '%s'", "doesn't apply to type '%s'",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name, descr->d_type->tp_name,
((PyTypeObject *)type)->tp_name); ((PyTypeObject *)type)->tp_name);
return NULL; return NULL;
...@@ -148,8 +147,8 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) ...@@ -148,8 +147,8 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
if (descr->d_getset->get != NULL) if (descr->d_getset->get != NULL)
return descr->d_getset->get(obj, descr->d_getset->closure); return descr->d_getset->get(obj, descr->d_getset->closure);
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"attribute '%.300s' of '%.100s' objects is not readable", "attribute '%V' of '%.100s' objects is not readable",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name); descr->d_type->tp_name);
return NULL; return NULL;
} }
...@@ -171,9 +170,9 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, ...@@ -171,9 +170,9 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
assert(obj != NULL); assert(obj != NULL);
if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) { if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%.200s' for '%.100s' objects " "descriptor '%V' for '%.100s' objects "
"doesn't apply to '%.100s' object", "doesn't apply to '%.100s' object",
descr_name(descr), descr_name(descr), "?",
descr->d_type->tp_name, descr->d_type->tp_name,
obj->ob_type->tp_name); obj->ob_type->tp_name);
*pres = -1; *pres = -1;
...@@ -203,8 +202,8 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) ...@@ -203,8 +202,8 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
return descr->d_getset->set(obj, value, return descr->d_getset->set(obj, value,
descr->d_getset->closure); descr->d_getset->closure);
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"attribute '%.300s' of '%.100s' objects is not writable", "attribute '%V' of '%.100s' objects is not writable",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name); descr->d_type->tp_name);
return -1; return -1;
} }
...@@ -220,19 +219,19 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) ...@@ -220,19 +219,19 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
argc = PyTuple_GET_SIZE(args); argc = PyTuple_GET_SIZE(args);
if (argc < 1) { if (argc < 1) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%.300s' of '%.100s' " "descriptor '%V' of '%.100s' "
"object needs an argument", "object needs an argument",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name); descr->d_type->tp_name);
return NULL; return NULL;
} }
self = PyTuple_GET_ITEM(args, 0); self = PyTuple_GET_ITEM(args, 0);
if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%.200s' " "descriptor '%V' "
"requires a '%.100s' object " "requires a '%.100s' object "
"but received a '%.100s'", "but received a '%.100s'",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name, descr->d_type->tp_name,
self->ob_type->tp_name); self->ob_type->tp_name);
return NULL; return NULL;
...@@ -278,19 +277,19 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) ...@@ -278,19 +277,19 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
argc = PyTuple_GET_SIZE(args); argc = PyTuple_GET_SIZE(args);
if (argc < 1) { if (argc < 1) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%.300s' of '%.100s' " "descriptor '%V' of '%.100s' "
"object needs an argument", "object needs an argument",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name); descr->d_type->tp_name);
return NULL; return NULL;
} }
self = PyTuple_GET_ITEM(args, 0); self = PyTuple_GET_ITEM(args, 0);
if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"descriptor '%.200s' " "descriptor '%V' "
"requires a '%.100s' object " "requires a '%.100s' object "
"but received a '%.100s'", "but received a '%.100s'",
descr_name((PyDescrObject *)descr), descr_name((PyDescrObject *)descr), "?",
descr->d_type->tp_name, descr->d_type->tp_name,
self->ob_type->tp_name); self->ob_type->tp_name);
return NULL; return NULL;
......
...@@ -631,6 +631,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) ...@@ -631,6 +631,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
n += PyUnicode_GET_SIZE(obj); n += PyUnicode_GET_SIZE(obj);
break; break;
} }
case 'V':
{
PyObject *obj = va_arg(count, PyObject *);
const char *str = va_arg(count, const char *);
assert(obj || str);
assert(!obj || PyUnicode_Check(obj));
if (obj)
n += PyUnicode_GET_SIZE(obj);
else
n += strlen(str);
break;
}
case 'S': case 'S':
{ {
PyObject *obj = va_arg(count, PyObject *); PyObject *obj = va_arg(count, PyObject *);
...@@ -775,6 +787,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) ...@@ -775,6 +787,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
s += size; s += size;
break; break;
} }
case 'V':
{
PyObject *obj = va_arg(vargs, PyObject *);
const char *str = va_arg(vargs, const char *);
if (obj) {
Py_ssize_t size = PyUnicode_GET_SIZE(obj);
Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
s += size;
} else {
appendstring(str);
}
break;
}
case 'S': case 'S':
case 'R': case 'R':
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment