Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

printing bytes to stdout in Py3

6 views
Skip to first unread message

Peter Billam

unread,
Feb 17, 2009, 12:04:23 AM2/17/09
to
Greetings. (Newbie warning as usual) In Python3, sys.stdout is a
io.TextIOWrapper object; but I want to output bytes
(e.g. muscript -midi t > t.mid )
and they're coming out stringified :-( How can I either change the
encoding on sys.stdout, or close sys.stdout and reopen it in 'b'
mode, or dup(fd) it first, or whatever the right thing to do is ?

Regards, Peter

--
Peter Billam www.pjb.com.au www.pjb.com.au/comp/contact.html

Gabriel Genellina

unread,
Feb 17, 2009, 5:17:37 AM2/17/09
to pytho...@python.org
En Tue, 17 Feb 2009 03:04:23 -0200, Peter Billam <pe...@www.pjb.com.au>
escribió:

> Greetings. (Newbie warning as usual) In Python3, sys.stdout is a
> io.TextIOWrapper object; but I want to output bytes
> (e.g. muscript -midi t > t.mid )
> and they're coming out stringified :-( How can I either change the
> encoding on sys.stdout, or close sys.stdout and reopen it in 'b'
> mode, or dup(fd) it first, or whatever the right thing to do is ?

I cannot test this with Python 3 right now, but I think this should work
(right at the start of your script):

sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb')

--
Gabriel Genellina

Christian Heimes

unread,
Feb 17, 2009, 7:28:01 AM2/17/09
to pytho...@python.org
Peter Billam schrieb:

> Greetings. (Newbie warning as usual) In Python3, sys.stdout is a
> io.TextIOWrapper object; but I want to output bytes
> (e.g. muscript -midi t > t.mid )
> and they're coming out stringified :-( How can I either change the
> encoding on sys.stdout, or close sys.stdout and reopen it in 'b'
> mode, or dup(fd) it first, or whatever the right thing to do is ?

The official API to write binary data to stdout is:

>>> count = sys.stdout.buffer.write(b"abc\n")
abc

Christian

Casey

unread,
Feb 17, 2009, 11:31:28 AM2/17/09
to

Is this really the 'official' way to do this? This isn't meant to be
confrontational or trolling; I honestly don't know the answer and I
had similar questions when I first started with the 3.0 release
candidates and I have yet to find a good answer in the Python v3.0
documentation. Why wouldn't you just use:

print(bytes.decode(b'abc\n'), end='')

Peter Billam

unread,
Feb 17, 2009, 12:23:26 PM2/17/09
to

That's the one that works the best for me :-)
Thanks for all the suggestions!

Christian Heimes

unread,
Feb 17, 2009, 12:33:41 PM2/17/09
to pytho...@python.org
Casey wrote:
> Is this really the 'official' way to do this? This isn't meant to be
> confrontational or trolling; I honestly don't know the answer and I
> had similar questions when I first started with the 3.0 release
> candidates and I have yet to find a good answer in the Python v3.0
> documentation.

Yes, it's really the official way. You can google up the discussion
between me and Guido on the python-dev list if you don't trust me. ;)
The docs concur with me, too.

http://docs.python.org/3.0/library/sys.html#sys.stdin

Note: The standard streams are in text mode by default. To write or read
binary data to these, use the underlying binary buffer. For example, to
write bytes to stdout, use sys.stdout.buffer.write(b'abc').

> Why wouldn't you just use:
>
> print(bytes.decode(b'abc\n'), end='')

Because it doesn't work with binary data. You can't convert random bytes
to unicode. Try that with a JPEG file or even the byte sequence that
contains some invalid UTF-8 chars.

>>> bytes((255, 255, 255))
b'\xff\xff\xff'
>>> bytes((255, 255, 255)).decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0:
unexpected code byte

Christian

Casey

unread,
Feb 17, 2009, 1:15:09 PM2/17/09
to
On Feb 17, 12:33 pm, Christian Heimes <li...@cheimes.de> wrote:
> Yes, it's really the official way. You can google up the discussion
> between me and Guido on the python-dev list if you don't trust me. ;)
> The docs concur with me, too.
>
> http://docs.python.org/3.0/library/sys.html#sys.stdin
>
> Note: The standard streams are in text mode by default. To write or read
> binary data to these, use the underlying binary buffer. For example, to
> write bytes to stdout, use sys.stdout.buffer.write(b'abc').

Thanks! Incidentally, the 'Note:' section you reference in the HTML
docs doesn't appear to be in the .CHM file that installs with the
windows version of 3.01. That would have made my search a lot
easier :-%

Scott David Daniels

unread,
Feb 17, 2009, 1:31:07 PM2/17/09
to
Casey wrote:
> ... Is this the 'official' way to do this?... Why wouldn't you just use:

> print(bytes.decode(b'abc\n'), end='')

Because that code is incapable of sending bytes that cannot be
interpreted as encoded in the "default" encoding. If you are
sending a picture, for example, all possible byte sequences might
show up. If the default encoding is "utf-8", for example, there
are byte sequences which are illegal. I suspect you are confused
by thinking each byte must map to a character; such an encoding
could never suffice for Chinese, for example.

--Scott David Daniels
Scott....@Acm.Org

Christian Heimes

unread,
Feb 17, 2009, 1:28:47 PM2/17/09
to pytho...@python.org
Casey schrieb:

Oh, that should not happen. Please report this bug!

Christian

0 new messages