mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
SF bug [#468061] __str__ ignored in str subclass.
object.c, PyObject_Str: Don't try to optimize anything except exact string objects here; in particular, let str subclasses go thru tp_str, same as non-str objects. This allows overrides of tp_str to take effect. stringobject.c: + string_print (str's tp_print): If the argument isn't an exact string object, get one from PyObject_Str. + string_str (str's tp_str): Make a genuine-string copy of the object if it's of a proper str subclass type. str() applied to a str subclass that doesn't override __str__ ends up here. test_descr.py: New str_of_str_subclass() test.
This commit is contained in:
parent
dfefc06fe0
commit
c993315b18
3 changed files with 52 additions and 8 deletions
|
@ -2298,6 +2298,36 @@ def buffer_inherit():
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def str_of_str_subclass():
|
||||||
|
import binascii
|
||||||
|
import cStringIO
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print "Testing __str__ defined in subclass of str ..."
|
||||||
|
|
||||||
|
class octetstring(str):
|
||||||
|
def __str__(self):
|
||||||
|
return binascii.b2a_hex(self)
|
||||||
|
def __repr__(self):
|
||||||
|
return self + " repr"
|
||||||
|
|
||||||
|
o = octetstring('A')
|
||||||
|
vereq(type(o), octetstring)
|
||||||
|
vereq(type(str(o)), str)
|
||||||
|
vereq(type(repr(o)), str)
|
||||||
|
vereq(ord(o), 0x41)
|
||||||
|
vereq(str(o), '41')
|
||||||
|
vereq(repr(o), 'A repr')
|
||||||
|
vereq(o.__str__(), '41')
|
||||||
|
vereq(o.__repr__(), 'A repr')
|
||||||
|
|
||||||
|
capture = cStringIO.StringIO()
|
||||||
|
# Calling str() or not exercises different internal paths.
|
||||||
|
print >> capture, o
|
||||||
|
print >> capture, str(o)
|
||||||
|
vereq(capture.getvalue(), '41\n41\n')
|
||||||
|
capture.close()
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
class_docstrings()
|
class_docstrings()
|
||||||
lists()
|
lists()
|
||||||
|
@ -2346,6 +2376,7 @@ def test_main():
|
||||||
binopoverride()
|
binopoverride()
|
||||||
subclasspropagation()
|
subclasspropagation()
|
||||||
buffer_inherit()
|
buffer_inherit()
|
||||||
|
str_of_str_subclass()
|
||||||
if verbose: print "All OK"
|
if verbose: print "All OK"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -261,12 +261,6 @@ PyObject_Str(PyObject *v)
|
||||||
Py_INCREF(v);
|
Py_INCREF(v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
if (PyString_Check(v)) {
|
|
||||||
/* For a string subtype that's not a string, return a true
|
|
||||||
string with the same string data. */
|
|
||||||
PyStringObject *s = (PyStringObject *)v;
|
|
||||||
return PyString_FromStringAndSize(s->ob_sval, s->ob_size);
|
|
||||||
}
|
|
||||||
if (v->ob_type->tp_str == NULL)
|
if (v->ob_type->tp_str == NULL)
|
||||||
return PyObject_Repr(v);
|
return PyObject_Repr(v);
|
||||||
|
|
||||||
|
|
|
@ -566,7 +566,18 @@ string_print(PyStringObject *op, FILE *fp, int flags)
|
||||||
int i;
|
int i;
|
||||||
char c;
|
char c;
|
||||||
int quote;
|
int quote;
|
||||||
|
|
||||||
/* XXX Ought to check for interrupts when writing long strings */
|
/* XXX Ought to check for interrupts when writing long strings */
|
||||||
|
if (! PyString_CheckExact(op)) {
|
||||||
|
int ret;
|
||||||
|
/* A str subclass may have its own __str__ method. */
|
||||||
|
op = (PyStringObject *) PyObject_Str((PyObject *)op);
|
||||||
|
if (op == NULL)
|
||||||
|
return -1;
|
||||||
|
ret = string_print(op, fp, flags);
|
||||||
|
Py_DECREF(op);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if (flags & Py_PRINT_RAW) {
|
if (flags & Py_PRINT_RAW) {
|
||||||
fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
|
fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -651,8 +662,16 @@ string_repr(register PyStringObject *op)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
string_str(PyObject *s)
|
string_str(PyObject *s)
|
||||||
{
|
{
|
||||||
Py_INCREF(s);
|
assert(PyString_Check(s));
|
||||||
return s;
|
if (PyString_CheckExact(s)) {
|
||||||
|
Py_INCREF(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Subtype -- return genuine string with the same value. */
|
||||||
|
PyStringObject *t = (PyStringObject *) s;
|
||||||
|
return PyString_FromStringAndSize(t->ob_sval, t->ob_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue