mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +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 @@ verify(unicode('hello','utf-8') == u'hello')
|
||||||
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 @@ o.x = u'abc'
|
||||||
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