Python 2 ‘print’, coercing arguments to Unicode

Peter Otten __peter__ at web.de
Tue Oct 6 10:30:31 EDT 2015


Ben Finney wrote:

> Ben Finney <ben+python at benfinney.id.au> writes:
> 
>> In Python 2.7, I am seeing this behaviour for ‘print’::
>>
>>     Python 2.7.10 (default, Sep 13 2015, 20:30:50)
>>     [GCC 5.2.1 20150911] on linux2
>>     Type "help", "copyright", "credits" or "license" for more
>>     information.
>>     >>> from __future__ import unicode_literals
>>     >>> from __future__ import print_function
>>     >>> import io
>>     >>> print(None)
>>     None
>>     >>> print(None, file=io.StringIO())
>>     Traceback (most recent call last):
>>       File "<stdin>", line 1, in <module>
>>     TypeError: unicode argument expected, got 'str'
>>
>> So, although my string literals are now Unicode objects, apparently
>> ‘print’ still coerces objects using the bytes type ‘str’.
> 
> To eliminate ‘from __future__ import print_function’ as a possible
> factor, here is another demonstration without that::
> 
>     Python 2.7.10 (default, Sep 13 2015, 20:30:50)
>     [GCC 5.2.1 20150911] on linux2
>     Type "help", "copyright", "credits" or "license" for more information.
>     >>> from __future__ import unicode_literals
>     >>> import sys
>     >>> import io
>     >>> print "foo"
>     foo
>     >>> print None
>     None
>     >>> sys.stdout = io.StringIO()
>     >>> print "foo"
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     TypeError: unicode argument expected, got 'str'
>     >>> print None
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     TypeError: unicode argument expected, got 'str'
> 
> So it appears that even a string literal, which is explicitly Unicode by
> the above ‘from __future__ import unicode_literals’, is still being
> coerced to a bytes ‘str’ object by ‘print’.
> 
> How can I convince ‘print’, everywhere throughout a module, that it
> should coerce its arguments using ‘unicode’?

I don't think this is possible with the print statement, but the print() 
function can be replaced with anything you like:

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import unicode_literals
>>> from __future__ import print_function
>>> import io
>>> _print = print
>>> def print(*args, **kw):
...     return _print(*map(unicode, args), **kw)
... 
>>> print(None, file=io.StringIO())
>>> outstream = io.StringIO()
>>> print(None, file=outstream)
>>> outstream.getvalue()
u'None\n'
>>> print(None)
None





More information about the Python-list mailing list