Kaydet (Commit) 7d6b0141 authored tarafından Benjamin Peterson's avatar Benjamin Peterson

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
........
üst f9214693
...@@ -9,12 +9,7 @@ import unittest ...@@ -9,12 +9,7 @@ import unittest
from test import test_support from test import test_support
import sys import sys
if sys.version_info[0] == 3: from StringIO import StringIO
# 3.x
from io import StringIO
else:
# 2.x
from StringIO import StringIO
NotDefined = object() NotDefined = object()
...@@ -112,6 +107,34 @@ class TestPrint(unittest.TestCase): ...@@ -112,6 +107,34 @@ class TestPrint(unittest.TestCase):
self.assertRaises(TypeError, print, '', end=3) self.assertRaises(TypeError, print, '', end=3)
self.assertRaises(AttributeError, print, '', file='') 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(): def test_main():
test_support.run_unittest(TestPrint) test_support.run_unittest(TestPrint)
......
...@@ -15,6 +15,9 @@ Core and Builtins ...@@ -15,6 +15,9 @@ Core and Builtins
- Issue #4547: When debugging a very large function, it was not always - Issue #4547: When debugging a very large function, it was not always
possible to update the lineno attribute of the current frame. 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 - Issue #6119: Fixed a incorrect Py3k warning about order comparisons of builtin
functions and methods. functions and methods.
......
...@@ -1556,14 +1556,40 @@ static PyObject * ...@@ -1556,14 +1556,40 @@ static PyObject *
builtin_print(PyObject *self, PyObject *args, PyObject *kwds) builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
{ {
static char *kwlist[] = {"sep", "end", "file", 0}; 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; PyObject *sep = NULL, *end = NULL, *file = NULL;
int i, err; int i, err, use_unicode = 0;
if (dummy_args == NULL) { if (dummy_args == NULL) {
if (!(dummy_args = PyTuple_New(0))) if (!(dummy_args = PyTuple_New(0)))
return NULL; 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", if (!PyArg_ParseTupleAndKeywords(dummy_args, kwds, "|OOO:print",
kwlist, &sep, &end, &file)) kwlist, &sep, &end, &file))
return NULL; return NULL;
...@@ -1573,26 +1599,56 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -1573,26 +1599,56 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
if (file == Py_None) if (file == Py_None)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
if (sep == Py_None) {
sep = 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 (sep && sep != Py_None && !PyString_Check(sep) && if (!use_unicode) {
!PyUnicode_Check(sep)) { for (i = 0; i < PyTuple_Size(args); i++) {
PyErr_Format(PyExc_TypeError, if (PyUnicode_Check(PyTuple_GET_ITEM(args, i))) {
"sep must be None, str or unicode, not %.200s", use_unicode = 1;
sep->ob_type->tp_name); break;
return NULL; }
}
} }
if (end && end != Py_None && !PyString_Check(end) && if (use_unicode) {
!PyUnicode_Check(end)) { newline = unicode_newline;
PyErr_Format(PyExc_TypeError, space = unicode_space;
"end must be None, str or unicode, not %.200s", }
end->ob_type->tp_name); else {
return NULL; newline = str_newline;
space = str_space;
} }
for (i = 0; i < PyTuple_Size(args); i++) { for (i = 0; i < PyTuple_Size(args); i++) {
if (i > 0) { if (i > 0) {
if (sep == NULL || sep == Py_None) if (sep == NULL)
err = PyFile_WriteString(" ", file); err = PyFile_WriteObject(space, file,
Py_PRINT_RAW);
else else
err = PyFile_WriteObject(sep, file, err = PyFile_WriteObject(sep, file,
Py_PRINT_RAW); Py_PRINT_RAW);
...@@ -1605,8 +1661,8 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -1605,8 +1661,8 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
if (end == NULL || end == Py_None) if (end == NULL)
err = PyFile_WriteString("\n", file); err = PyFile_WriteObject(newline, file, Py_PRINT_RAW);
else else
err = PyFile_WriteObject(end, file, Py_PRINT_RAW); err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
if (err) if (err)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment