[Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.60,2.61

Guido van Rossum python-dev@python.org
Mon, 10 Apr 2000 09:47:24 -0400 (EDT)


Update of /projects/cvsroot/python/dist/src/Objects
In directory eric:/projects/python/develop/guido/src/Objects

Modified Files:
	stringobject.c 
Log Message:
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.


Index: stringobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.60
retrieving revision 2.61
diff -C2 -r2.60 -r2.61
*** stringobject.c	2000/03/20 16:36:43	2.60
--- stringobject.c	2000/04/10 13:47:21	2.61
***************
*** 390,396 ****
  	register char *s, *end;
  	register char c;
! 	if (!PyString_Check(el))
  		return PyUnicode_Contains(a, el);
! 	if (PyString_Size(el) != 1) {
  		PyErr_SetString(PyExc_TypeError,
  				"string member test needs char left operand");
--- 390,396 ----
  	register char *s, *end;
  	register char c;
! 	if (PyUnicode_Check(el))
  		return PyUnicode_Contains(a, el);
! 	if (!PyString_Check(el) || PyString_Size(el) != 1) {
  		PyErr_SetString(PyExc_TypeError,
  				"string member test needs char left operand");
***************
*** 2385,2389 ****
  	int fmtcnt, rescnt, reslen, arglen, argidx;
  	int args_owned = 0;
! 	PyObject *result;
  	PyObject *dict = NULL;
  	if (format == NULL || !PyString_Check(format) || args == NULL) {
--- 2385,2389 ----
  	int fmtcnt, rescnt, reslen, arglen, argidx;
  	int args_owned = 0;
! 	PyObject *result, *orig_args;
  	PyObject *dict = NULL;
  	if (format == NULL || !PyString_Check(format) || args == NULL) {
***************
*** 2391,2394 ****
--- 2391,2395 ----
  		return NULL;
  	}
+ 	orig_args = args;
  	fmt = PyString_AsString(format);
  	fmtcnt = PyString_Size(format);
***************
*** 2435,2438 ****
--- 2436,2441 ----
  			int len;
  			char tmpbuf[120]; /* For format{float,int,char}() */
+ 			char *fmt_start = fmt;
+ 			
  			fmt++;
  			if (*fmt == '(') {
***************
*** 2584,2587 ****
--- 2587,2595 ----
  				break;
  			case 's':
+   			case 'r':
+ 				if (PyUnicode_Check(v)) {
+ 					fmt = fmt_start;
+ 					goto unicode;
+ 				}
  				temp = PyObject_Str(v);
  				if (temp == NULL)
***************
*** 2713,2716 ****
--- 2721,2765 ----
  	_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);