mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Implement the changes proposed in patch #413333. unicode(obj) now
works just like str(obj) in that it tries __str__/tp_str on the object in case it finds that the object is not a string or buffer.
This commit is contained in:
		
							parent
							
								
									c60e6f7771
								
							
						
					
					
						commit
						6871f6ac57
					
				
					 2 changed files with 61 additions and 43 deletions
				
			
		| 
						 | 
					@ -429,6 +429,7 @@ def test_fixup(s):
 | 
				
			||||||
verify(unicode('hello','utf8') == u'hello')
 | 
					verify(unicode('hello','utf8') == u'hello')
 | 
				
			||||||
verify(unicode('hello','latin-1') == u'hello')
 | 
					verify(unicode('hello','latin-1') == u'hello')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Compatibility to str():
 | 
				
			||||||
class String:
 | 
					class String:
 | 
				
			||||||
    x = ''
 | 
					    x = ''
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
| 
						 | 
					@ -444,6 +445,10 @@ def __str__(self):
 | 
				
			||||||
verify(unicode(o) == u'abc')
 | 
					verify(unicode(o) == u'abc')
 | 
				
			||||||
verify(str(o) == 'abc')
 | 
					verify(str(o) == 'abc')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for obj in (123, 123.45, 123L):
 | 
				
			||||||
 | 
					    verify(unicode(obj) == unicode(str(obj)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Error handling
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    u'Andr\202 x'.encode('ascii')
 | 
					    u'Andr\202 x'.encode('ascii')
 | 
				
			||||||
    u'Andr\202 x'.encode('ascii','strict')
 | 
					    u'Andr\202 x'.encode('ascii','strict')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -398,10 +398,11 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
 | 
				
			||||||
				      const char *encoding,
 | 
									      const char *encoding,
 | 
				
			||||||
				      const char *errors)
 | 
									      const char *errors)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *s;
 | 
					    const char *s = NULL;
 | 
				
			||||||
    int len;
 | 
					    int len;
 | 
				
			||||||
    int owned = 0;
 | 
					    int owned = 0;
 | 
				
			||||||
    PyObject *v;
 | 
					    PyObject *v;
 | 
				
			||||||
 | 
					    int reclevel;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (obj == NULL) {
 | 
					    if (obj == NULL) {
 | 
				
			||||||
	PyErr_BadInternalCall();
 | 
						PyErr_BadInternalCall();
 | 
				
			||||||
| 
						 | 
					@ -409,25 +410,13 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Coerce object */
 | 
					    /* Coerce object */
 | 
				
			||||||
    if (PyInstance_Check(obj)) {
 | 
					    for (reclevel = 0; reclevel < 2; reclevel++) {
 | 
				
			||||||
	PyObject *func;
 | 
					
 | 
				
			||||||
	func = PyObject_GetAttrString(obj, "__str__");
 | 
					 | 
				
			||||||
	if (func == NULL) {
 | 
					 | 
				
			||||||
	    PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
		  "coercing to Unicode: instance doesn't define __str__");
 | 
					 | 
				
			||||||
	    return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	obj = PyEval_CallObject(func, NULL);
 | 
					 | 
				
			||||||
	Py_DECREF(func);
 | 
					 | 
				
			||||||
	if (obj == NULL)
 | 
					 | 
				
			||||||
	    return NULL;
 | 
					 | 
				
			||||||
	owned = 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
	if (PyUnicode_Check(obj)) {
 | 
						if (PyUnicode_Check(obj)) {
 | 
				
			||||||
	    if (encoding) {
 | 
						    if (encoding) {
 | 
				
			||||||
		PyErr_SetString(PyExc_TypeError,
 | 
							PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
				"decoding Unicode is not supported");
 | 
									"decoding Unicode is not supported");
 | 
				
			||||||
            return NULL;
 | 
							goto onError;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    if (PyUnicode_CheckExact(obj)) {
 | 
						    if (PyUnicode_CheckExact(obj)) {
 | 
				
			||||||
		Py_INCREF(obj);
 | 
							Py_INCREF(obj);
 | 
				
			||||||
| 
						 | 
					@ -444,14 +433,38 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
 | 
				
			||||||
	else if (PyString_Check(obj)) {
 | 
						else if (PyString_Check(obj)) {
 | 
				
			||||||
	    s = PyString_AS_STRING(obj);
 | 
						    s = PyString_AS_STRING(obj);
 | 
				
			||||||
	    len = PyString_GET_SIZE(obj);
 | 
						    len = PyString_GET_SIZE(obj);
 | 
				
			||||||
 | 
						    break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    else if (PyObject_AsCharBuffer(obj, &s, &len)) {
 | 
						else {
 | 
				
			||||||
	/* Overwrite the error message with something more useful in
 | 
						    PyObject *w;
 | 
				
			||||||
	   case of a TypeError. */
 | 
					
 | 
				
			||||||
	if (PyErr_ExceptionMatches(PyExc_TypeError))
 | 
						    /* Try char buffer interface */
 | 
				
			||||||
 | 
					            if (PyObject_AsCharBuffer(obj, &s, &len))
 | 
				
			||||||
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
						    /* Mimic the behaviour of str(object) if everything else
 | 
				
			||||||
 | 
					    	       fails (see PyObject_Str()); this also covers instances
 | 
				
			||||||
 | 
					    	       which implement __str__. */
 | 
				
			||||||
 | 
						    if (obj->ob_type->tp_str == NULL)
 | 
				
			||||||
 | 
							w = PyObject_Repr(obj);
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
							w = (*obj->ob_type->tp_str)(obj);
 | 
				
			||||||
 | 
						    if (w == NULL)
 | 
				
			||||||
 | 
							goto onError;
 | 
				
			||||||
 | 
						    if (owned) {
 | 
				
			||||||
 | 
							Py_DECREF(obj);
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    obj = w;
 | 
				
			||||||
 | 
						    owned = 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s == NULL) {
 | 
				
			||||||
	PyErr_Format(PyExc_TypeError,
 | 
						PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
			 "coercing to Unicode: need string or buffer, "
 | 
							     "coercing to Unicode: __str__ recursion limit exceeded "
 | 
				
			||||||
			 "%.80s found",
 | 
							     "(last type: %.80s)",
 | 
				
			||||||
		     obj->ob_type->tp_name);
 | 
							     obj->ob_type->tp_name);
 | 
				
			||||||
	goto onError;
 | 
						goto onError;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue