]> granicus.if.org Git - python/commitdiff
Add a format specifier %V to PyUnicode_FromFormat(), that works similar to %U,
authorWalter Dörwald <walter@livinglogic.de>
Mon, 11 Jun 2007 16:36:59 +0000 (16:36 +0000)
committerWalter Dörwald <walter@livinglogic.de>
Mon, 11 Jun 2007 16:36:59 +0000 (16:36 +0000)
but requires an additional char * that will be used if the unicode object is
NULL.

Use %V in descrobject.c and classobject.c.

Objects/classobject.c
Objects/descrobject.c
Objects/unicodeobject.c

index 2dcc88ffdaef76f3890910e392a8b086c19ce3aa..9c9c49ef808cc9a3ac6edb81fe55ccc7b06dc84f 100644 (file)
@@ -227,7 +227,7 @@ method_repr(PyMethodObject *a)
        PyObject *func = a->im_func;
        PyObject *klass = a->im_class;
        PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
-       char *sfuncname = "?", *sklassname = "?";
+       char *defname = "?";
 
        funcname = PyObject_GetAttrString(func, "__name__");
        if (funcname == NULL) {
@@ -239,8 +239,6 @@ method_repr(PyMethodObject *a)
                Py_DECREF(funcname);
                funcname = NULL;
        }
-       else
-               sfuncname = PyUnicode_AsString(funcname);
        if (klass == NULL)
                klassname = NULL;
        else {
@@ -254,16 +252,16 @@ method_repr(PyMethodObject *a)
                        Py_DECREF(klassname);
                        klassname = NULL;
                }
-               else
-                       sklassname = PyUnicode_AsString(klassname);
        }
        if (self == NULL)
-               result = PyUnicode_FromFormat("<unbound method %s.%s>",
-                                            sklassname, sfuncname);
+               result = PyUnicode_FromFormat("<unbound method %V.%V>",
+                                             klassname, defname,
+                                             funcname, defname);
        else {
                /* XXX Shouldn't use repr()/%R here! */
-               result = PyUnicode_FromFormat("<bound method %s.%s of %R>",
-                                             sklassname, sfuncname, self);
+               result = PyUnicode_FromFormat("<bound method %V.%V of %R>",
+                                             klassname, defname,
+                                             funcname, defname, self);
        }
        Py_XDECREF(funcname);
        Py_XDECREF(klassname);
index acd24007d1125c85886f2a138a3b6b71cf121229..e75fc8091acb470751db8fa62b304c92281d158a 100644 (file)
@@ -12,51 +12,50 @@ descr_dealloc(PyDescrObject *descr)
        PyObject_GC_Del(descr);
 }
 
-static char *
+static PyObject *
 descr_name(PyDescrObject *descr)
 {
        if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
-               return PyUnicode_AsString(descr->d_name);
-       else if (descr->d_name != NULL && PyString_Check(descr->d_name))
-               /* XXX this should not happen */
-               return PyString_AS_STRING(descr->d_name);
-       else
-               return "?";
+               return descr->d_name;
+       return NULL;
 }
 
 static PyObject *
 descr_repr(PyDescrObject *descr, char *format)
 {
-       return PyUnicode_FromFormat(format, descr_name(descr),
-                                  descr->d_type->tp_name);
+       PyObject *name = NULL;
+       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 *
 method_repr(PyMethodDescrObject *descr)
 {
        return descr_repr((PyDescrObject *)descr,
-                         "<method '%s' of '%s' objects>");
+                         "<method '%V' of '%s' objects>");
 }
 
 static PyObject *
 member_repr(PyMemberDescrObject *descr)
 {
        return descr_repr((PyDescrObject *)descr,
-                         "<member '%s' of '%s' objects>");
+                         "<member '%V' of '%s' objects>");
 }
 
 static PyObject *
 getset_repr(PyGetSetDescrObject *descr)
 {
        return descr_repr((PyDescrObject *)descr,
-                         "<attribute '%s' of '%s' objects>");
+                         "<attribute '%V' of '%s' objects>");
 }
 
 static PyObject *
 wrapperdescr_repr(PyWrapperDescrObject *descr)
 {
        return descr_repr((PyDescrObject *)descr,
-                         "<slot wrapper '%s' of '%s' objects>");
+                         "<slot wrapper '%V' of '%s' objects>");
 }
 
 static int
@@ -69,9 +68,9 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
        }
        if (!PyObject_TypeCheck(obj, descr->d_type)) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%s' for '%s' objects "
+                            "descriptor '%V' for '%s' objects "
                             "doesn't apply to '%s' object",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name,
                             obj->ob_type->tp_name);
                *pres = NULL;
@@ -90,27 +89,27 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
                else {
                        /* Wot - no type?! */
                        PyErr_Format(PyExc_TypeError,
-                                    "descriptor '%s' for type '%s' "
+                                    "descriptor '%V' for type '%s' "
                                     "needs either an object or a type",
-                                    descr_name((PyDescrObject *)descr),
+                                    descr_name((PyDescrObject *)descr), "?",
                                     descr->d_type->tp_name);
                        return NULL;
                }
        }
        if (!PyType_Check(type)) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%s' for type '%s' "
+                            "descriptor '%V' for type '%s' "
                             "needs a type, not a '%s' as arg 2",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name,
                             type->ob_type->tp_name);
                return NULL;
        }
        if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%s' for type '%s' "
+                            "descriptor '%V' for type '%s' "
                             "doesn't apply to type '%s'",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name,
                             ((PyTypeObject *)type)->tp_name);
                return NULL;
@@ -148,8 +147,8 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
        if (descr->d_getset->get != NULL)
                return descr->d_getset->get(obj, descr->d_getset->closure);
        PyErr_Format(PyExc_AttributeError,
-                    "attribute '%.300s' of '%.100s' objects is not readable",
-                    descr_name((PyDescrObject *)descr),
+                    "attribute '%V' of '%.100s' objects is not readable",
+                    descr_name((PyDescrObject *)descr), "?",
                     descr->d_type->tp_name);
        return NULL;
 }
@@ -171,9 +170,9 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
        assert(obj != NULL);
        if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%.200s' for '%.100s' objects "
+                            "descriptor '%V' for '%.100s' objects "
                             "doesn't apply to '%.100s' object",
-                            descr_name(descr),
+                            descr_name(descr), "?",
                             descr->d_type->tp_name,
                             obj->ob_type->tp_name);
                *pres = -1;
@@ -203,8 +202,8 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
                return descr->d_getset->set(obj, value,
                                            descr->d_getset->closure);
        PyErr_Format(PyExc_AttributeError,
-                    "attribute '%.300s' of '%.100s' objects is not writable",
-                    descr_name((PyDescrObject *)descr),
+                    "attribute '%V' of '%.100s' objects is not writable",
+                    descr_name((PyDescrObject *)descr), "?",
                     descr->d_type->tp_name);
        return -1;
 }
@@ -220,19 +219,19 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
        argc = PyTuple_GET_SIZE(args);
        if (argc < 1) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%.300s' of '%.100s' "
+                            "descriptor '%V' of '%.100s' "
                             "object needs an argument",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name);
                return NULL;
        }
        self = PyTuple_GET_ITEM(args, 0);
        if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%.200s' "
+                            "descriptor '%V' "
                             "requires a '%.100s' object "
                             "but received a '%.100s'",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name,
                             self->ob_type->tp_name);
                return NULL;
@@ -278,19 +277,19 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
        argc = PyTuple_GET_SIZE(args);
        if (argc < 1) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%.300s' of '%.100s' "
+                            "descriptor '%V' of '%.100s' "
                             "object needs an argument",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name);
                return NULL;
        }
        self = PyTuple_GET_ITEM(args, 0);
        if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
                PyErr_Format(PyExc_TypeError,
-                            "descriptor '%.200s' "
+                            "descriptor '%V' "
                             "requires a '%.100s' object "
                             "but received a '%.100s'",
-                            descr_name((PyDescrObject *)descr),
+                            descr_name((PyDescrObject *)descr), "?",
                             descr->d_type->tp_name,
                             self->ob_type->tp_name);
                return NULL;
index 87c5c997281bf8df3f5a05409a2e8545ab570506..39b746288b58d87c4f073e0fb33586c0e7a31985 100644 (file)
@@ -631,6 +631,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
                                n += PyUnicode_GET_SIZE(obj);
                                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':
                        {
                                PyObject *obj = va_arg(count, PyObject *);
@@ -775,6 +787,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
                                s += size;
                                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 'R':
                        {