Jay Hacker
Jay Hacker

Reputation: 1915

Python 2.7: print doesn't speak unicode to the io module?

import sys, codecs, io

codecsout = codecs.getwriter('utf8')(sys.stdout)
ioout = io.open(sys.stdout.fileno(), mode='w', encoding='utf8')
print >> sys.stdout, 1
print >> codecsout, 2
print >> ioout, 3

Fails with:

1
2
Traceback (most recent call last):
  File "print.py", line 7, in <module>
    print >> ioout, 3
TypeError: must be unicode, not str

It fails with print(3, file=ioout) from the __future__ as well.

Does print not know how to talk to the io module?

Upvotes: 3

Views: 964

Answers (2)

Screwtape
Screwtape

Reputation: 429

The print statement implicitly calls __str__ on each thing it prints. sys.stdout is a byte-stream, so sending it a str is fine. codecs.getwriter is an old Python API so I'm guessing it just implicitly converts str to unicode as Python 2.x traditionally does. However, the new io module is strict about converting str to unicode as Python 3.x is, which is why it complains.

So, if you want to send unicode data to a stream, use the .write() method instead of print:

>>> sys.stdout.write(u'1\n')
1
>>> codecsout.write(u'1\n')
1
>>> sys.stdout.write(u'1\n')
1

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308364

Evidently it doesn't. Even if you give it an explicit Unicode string, it doesn't work.

>>> print >> ioout, u'3'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be unicode, not str

I'm guessing the problem is in the newline that is automatically appended to the end. The print function from the future doesn't appear to have the same problem:

>>> from __future__ import print_function
>>> print(unicode(3), file=ioout)
3

Upvotes: 2

Related Questions