]> granicus.if.org Git - python/commitdiff
Marc-Andre Lemburg:
authorGuido van Rossum <guido@python.org>
Mon, 10 Apr 2000 13:47:21 +0000 (13:47 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 10 Apr 2000 13:47:21 +0000 (13:47 +0000)
* string_contains now calls PyUnicode_Contains() only when the other
  operand is a Unicode string (not whenever it's not a string).

* New format style '%r' inserts repr(arg) instead of str(arg).

* '...%s...' % u"abc" now coerces to Unicode just like
  string methods. Care is taken not to reevaluate already formatted
  arguments -- only the first Unicode object appearing in the
  argument mapping is looked up twice. Added test cases for
  this to test_unicode.py.

Objects/stringobject.c

index 10257f7562dada2fd60acb9a5fd53a78888704ce..1d7f61ab4d01fb18600c09ecf4daea8a7844f4a6 100644 (file)
@@ -389,9 +389,9 @@ PyObject *a, *el;
 {
        register char *s, *end;
        register char c;
-       if (!PyString_Check(el))
+       if (PyUnicode_Check(el))
                return PyUnicode_Contains(a, el);
-       if (PyString_Size(el) != 1) {
+       if (!PyString_Check(el) || PyString_Size(el) != 1) {
                PyErr_SetString(PyExc_TypeError,
                                "string member test needs char left operand");
                return -1;
@@ -2384,12 +2384,13 @@ PyString_Format(format, args)
        char *fmt, *res;
        int fmtcnt, rescnt, reslen, arglen, argidx;
        int args_owned = 0;
-       PyObject *result;
+       PyObject *result, *orig_args;
        PyObject *dict = NULL;
        if (format == NULL || !PyString_Check(format) || args == NULL) {
                PyErr_BadInternalCall();
                return NULL;
        }
+       orig_args = args;
        fmt = PyString_AsString(format);
        fmtcnt = PyString_Size(format);
        reslen = rescnt = fmtcnt + 100;
@@ -2434,6 +2435,8 @@ PyString_Format(format, args)
                        int sign;
                        int len;
                        char tmpbuf[120]; /* For format{float,int,char}() */
+                       char *fmt_start = fmt;
+                       
                        fmt++;
                        if (*fmt == '(') {
                                char *keystart;
@@ -2583,6 +2586,11 @@ PyString_Format(format, args)
                                len = 1;
                                break;
                        case 's':
+                       case 'r':
+                               if (PyUnicode_Check(v)) {
+                                       fmt = fmt_start;
+                                       goto unicode;
+                               }
                                temp = PyObject_Str(v);
                                if (temp == NULL)
                                        goto error;
@@ -2712,6 +2720,47 @@ PyString_Format(format, args)
        }
        _PyString_Resize(&result, reslen - rescnt);
        return result;
+
+ unicode:
+       if (args_owned) {
+               Py_DECREF(args);
+               args_owned = 0;
+       }
+       /* Fiddle args right (remove the first argidx-1 arguments) */
+       --argidx;
+       if (PyTuple_Check(orig_args) && argidx > 0) {
+               PyObject *v;
+               int n = PyTuple_GET_SIZE(orig_args) - argidx;
+               v = PyTuple_New(n);
+               if (v == NULL)
+                       goto error;
+               while (--n >= 0) {
+                       PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx);
+                       Py_INCREF(w);
+                       PyTuple_SET_ITEM(v, n, w);
+               }
+               args = v;
+       } else {
+               Py_INCREF(orig_args);
+               args = orig_args;
+       }
+       /* Paste rest of format string to what we have of the result
+          string; we reuse result for this */
+       rescnt = res - PyString_AS_STRING(result);
+       fmtcnt = PyString_GET_SIZE(format) - \
+                (fmt - PyString_AS_STRING(format));
+       if (_PyString_Resize(&result, rescnt + fmtcnt)) {
+               Py_DECREF(args);
+               goto error;
+       }
+       memcpy(PyString_AS_STRING(result) + rescnt, fmt, fmtcnt);
+       format = result;
+       /* Let Unicode do its magic */
+       result = PyUnicode_Format(format, args);
+       Py_DECREF(format);
+       Py_DECREF(args);
+       return result;
+       
  error:
        Py_DECREF(result);
        if (args_owned) {