mirror of https://github.com/python/cpython
Merged revisions 73776 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r73776 | benjamin.peterson | 2009-07-02 13:16:45 -0500 (Thu, 02 Jul 2009) | 1 line when print() gets unicode arguments, sep and end should be unicode by default #4618 ........
This commit is contained in:
parent
f921469383
commit
7d6b01417f
|
@ -9,12 +9,7 @@ import unittest
|
|||
from test import test_support
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] == 3:
|
||||
# 3.x
|
||||
from io import StringIO
|
||||
else:
|
||||
# 2.x
|
||||
from StringIO import StringIO
|
||||
from StringIO import StringIO
|
||||
|
||||
NotDefined = object()
|
||||
|
||||
|
@ -112,6 +107,34 @@ class TestPrint(unittest.TestCase):
|
|||
self.assertRaises(TypeError, print, '', end=3)
|
||||
self.assertRaises(AttributeError, print, '', file='')
|
||||
|
||||
def test_mixed_args(self):
|
||||
# If an unicode arg is passed, sep and end should be unicode, too.
|
||||
class Recorder(object):
|
||||
|
||||
def __init__(self, must_be_unicode):
|
||||
self.buf = []
|
||||
self.force_unicode = must_be_unicode
|
||||
|
||||
def write(self, what):
|
||||
if self.force_unicode and not isinstance(what, unicode):
|
||||
raise AssertionError("{0!r} is not unicode".format(what))
|
||||
self.buf.append(what)
|
||||
|
||||
buf = Recorder(True)
|
||||
print(u'hi', file=buf)
|
||||
self.assertEqual(u''.join(buf.buf), 'hi\n')
|
||||
del buf.buf[:]
|
||||
print(u'hi', u'nothing', file=buf)
|
||||
self.assertEqual(u''.join(buf.buf), 'hi nothing\n')
|
||||
buf = Recorder(False)
|
||||
print('hi', 'bye', end=u'\n', file=buf)
|
||||
self.assertTrue(isinstance(buf.buf[1], unicode))
|
||||
self.assertTrue(isinstance(buf.buf[3], unicode))
|
||||
del buf.buf[:]
|
||||
print(sep=u'x', file=buf)
|
||||
self.assertTrue(isinstance(buf.buf[-1], unicode))
|
||||
|
||||
|
||||
def test_main():
|
||||
test_support.run_unittest(TestPrint)
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ Core and Builtins
|
|||
- Issue #4547: When debugging a very large function, it was not always
|
||||
possible to update the lineno attribute of the current frame.
|
||||
|
||||
- Issue #4618: When unicode arguments are passed to print(), the default
|
||||
separator and end should be unicode also.
|
||||
|
||||
- Issue #6119: Fixed a incorrect Py3k warning about order comparisons of builtin
|
||||
functions and methods.
|
||||
|
||||
|
|
|
@ -1556,14 +1556,40 @@ static PyObject *
|
|||
builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"sep", "end", "file", 0};
|
||||
static PyObject *dummy_args;
|
||||
static PyObject *dummy_args = NULL;
|
||||
static PyObject *unicode_newline = NULL, *unicode_space = NULL;
|
||||
static PyObject *str_newline = NULL, *str_space = NULL;
|
||||
PyObject *newline, *space;
|
||||
PyObject *sep = NULL, *end = NULL, *file = NULL;
|
||||
int i, err;
|
||||
int i, err, use_unicode = 0;
|
||||
|
||||
if (dummy_args == NULL) {
|
||||
if (!(dummy_args = PyTuple_New(0)))
|
||||
return NULL;
|
||||
}
|
||||
if (str_newline == NULL) {
|
||||
str_newline = PyString_FromString("\n");
|
||||
if (str_newline == NULL)
|
||||
return NULL;
|
||||
str_space = PyString_FromString(" ");
|
||||
if (str_space == NULL) {
|
||||
Py_CLEAR(str_newline);
|
||||
return NULL;
|
||||
}
|
||||
unicode_newline = PyUnicode_FromString("\n");
|
||||
if (unicode_newline == NULL) {
|
||||
Py_CLEAR(str_newline);
|
||||
Py_CLEAR(str_space);
|
||||
return NULL;
|
||||
}
|
||||
unicode_space = PyUnicode_FromString(" ");
|
||||
if (unicode_space == NULL) {
|
||||
Py_CLEAR(str_newline);
|
||||
Py_CLEAR(str_space);
|
||||
Py_CLEAR(unicode_space);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!PyArg_ParseTupleAndKeywords(dummy_args, kwds, "|OOO:print",
|
||||
kwlist, &sep, &end, &file))
|
||||
return NULL;
|
||||
|
@ -1573,26 +1599,56 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
if (file == Py_None)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (sep && sep != Py_None && !PyString_Check(sep) &&
|
||||
!PyUnicode_Check(sep)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"sep must be None, str or unicode, not %.200s",
|
||||
sep->ob_type->tp_name);
|
||||
return NULL;
|
||||
if (sep == Py_None) {
|
||||
sep = NULL;
|
||||
}
|
||||
if (end && end != Py_None && !PyString_Check(end) &&
|
||||
!PyUnicode_Check(end)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"end must be None, str or unicode, not %.200s",
|
||||
end->ob_type->tp_name);
|
||||
return NULL;
|
||||
else if (sep) {
|
||||
if (PyUnicode_Check(sep)) {
|
||||
use_unicode = 1;
|
||||
}
|
||||
else if (!PyString_Check(sep)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"sep must be None, str or unicode, not %.200s",
|
||||
sep->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (end == Py_None)
|
||||
end = NULL;
|
||||
else if (end) {
|
||||
if (PyUnicode_Check(end)) {
|
||||
use_unicode = 1;
|
||||
}
|
||||
else if (!PyString_Check(end)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"end must be None, str or unicode, not %.200s",
|
||||
end->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_unicode) {
|
||||
for (i = 0; i < PyTuple_Size(args); i++) {
|
||||
if (PyUnicode_Check(PyTuple_GET_ITEM(args, i))) {
|
||||
use_unicode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (use_unicode) {
|
||||
newline = unicode_newline;
|
||||
space = unicode_space;
|
||||
}
|
||||
else {
|
||||
newline = str_newline;
|
||||
space = str_space;
|
||||
}
|
||||
|
||||
for (i = 0; i < PyTuple_Size(args); i++) {
|
||||
if (i > 0) {
|
||||
if (sep == NULL || sep == Py_None)
|
||||
err = PyFile_WriteString(" ", file);
|
||||
if (sep == NULL)
|
||||
err = PyFile_WriteObject(space, file,
|
||||
Py_PRINT_RAW);
|
||||
else
|
||||
err = PyFile_WriteObject(sep, file,
|
||||
Py_PRINT_RAW);
|
||||
|
@ -1605,8 +1661,8 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (end == NULL || end == Py_None)
|
||||
err = PyFile_WriteString("\n", file);
|
||||
if (end == NULL)
|
||||
err = PyFile_WriteObject(newline, file, Py_PRINT_RAW);
|
||||
else
|
||||
err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
|
||||
if (err)
|
||||
|
|
Loading…
Reference in New Issue