Commit 0f7465fb authored by Guido van Rossum's avatar Guido van Rossum

Marc-Andre Lemburg:

* 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.
parent 5b23cb1e
...@@ -389,9 +389,9 @@ PyObject *a, *el; ...@@ -389,9 +389,9 @@ PyObject *a, *el;
{ {
register char *s, *end; register char *s, *end;
register char c; register char c;
if (!PyString_Check(el)) if (PyUnicode_Check(el))
return PyUnicode_Contains(a, el); return PyUnicode_Contains(a, el);
if (PyString_Size(el) != 1) { if (!PyString_Check(el) || PyString_Size(el) != 1) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"string member test needs char left operand"); "string member test needs char left operand");
return -1; return -1;
...@@ -2384,12 +2384,13 @@ PyString_Format(format, args) ...@@ -2384,12 +2384,13 @@ PyString_Format(format, args)
char *fmt, *res; char *fmt, *res;
int fmtcnt, rescnt, reslen, arglen, argidx; int fmtcnt, rescnt, reslen, arglen, argidx;
int args_owned = 0; int args_owned = 0;
PyObject *result; PyObject *result, *orig_args;
PyObject *dict = NULL; PyObject *dict = NULL;
if (format == NULL || !PyString_Check(format) || args == NULL) { if (format == NULL || !PyString_Check(format) || args == NULL) {
PyErr_BadInternalCall(); PyErr_BadInternalCall();
return NULL; return NULL;
} }
orig_args = args;
fmt = PyString_AsString(format); fmt = PyString_AsString(format);
fmtcnt = PyString_Size(format); fmtcnt = PyString_Size(format);
reslen = rescnt = fmtcnt + 100; reslen = rescnt = fmtcnt + 100;
...@@ -2434,6 +2435,8 @@ PyString_Format(format, args) ...@@ -2434,6 +2435,8 @@ PyString_Format(format, args)
int sign; int sign;
int len; int len;
char tmpbuf[120]; /* For format{float,int,char}() */ char tmpbuf[120]; /* For format{float,int,char}() */
char *fmt_start = fmt;
fmt++; fmt++;
if (*fmt == '(') { if (*fmt == '(') {
char *keystart; char *keystart;
...@@ -2583,6 +2586,11 @@ PyString_Format(format, args) ...@@ -2583,6 +2586,11 @@ PyString_Format(format, args)
len = 1; len = 1;
break; break;
case 's': case 's':
case 'r':
if (PyUnicode_Check(v)) {
fmt = fmt_start;
goto unicode;
}
temp = PyObject_Str(v); temp = PyObject_Str(v);
if (temp == NULL) if (temp == NULL)
goto error; goto error;
...@@ -2712,6 +2720,47 @@ PyString_Format(format, args) ...@@ -2712,6 +2720,47 @@ PyString_Format(format, args)
} }
_PyString_Resize(&result, reslen - rescnt); _PyString_Resize(&result, reslen - rescnt);
return result; 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: error:
Py_DECREF(result); Py_DECREF(result);
if (args_owned) { if (args_owned) {
......
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