summaryrefslogtreecommitdiffstats
path: root/Objects/stringobject.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2000-04-10 13:47:21 (GMT)
committerGuido van Rossum <guido@python.org>2000-04-10 13:47:21 (GMT)
commit90daa8756920ef188d233a9b0c3672a841f064dd (patch)
treeb3d8e80c216cd50f9791cbb54b0646f60018e20d /Objects/stringobject.c
parentb244f6950bd739a1d5dea7e119150e90ac03604f (diff)
downloadcpython-90daa8756920ef188d233a9b0c3672a841f064dd.zip
cpython-90daa8756920ef188d233a9b0c3672a841f064dd.tar.gz
cpython-90daa8756920ef188d233a9b0c3672a841f064dd.tar.bz2
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.
Diffstat (limited to 'Objects/stringobject.c')
-rw-r--r--Objects/stringobject.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 10257f7..1d7f61a 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -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) {