This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: print statement delayed IOError when stdout has been closed
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: eugenet, iritkatriel, tholzer
Priority: normal Keywords:

Created on 2010-02-15 01:04 by tholzer, last changed 2022-04-11 14:56 by admin.

Messages (8)
msg99351 - (view) Author: (tholzer) Date: 2010-02-15 01:04
When printing to a closed stdout file descriptor, the print statement only raises an IOError at character 8192. 

The expected behaviour is that IOError gets raised immediately (i.e. on the first character). Compare this behaviour to writing to a closed sys.stderr.

To reproduce (using bash):

<pre>
# python -V
Python 2.6.4

# python -c 'print "x" * 8191' 1>&- ; echo $?
close failed in file object destructor:
Error in sys.excepthook:

Original exception was:
0

# python -c 'print "x" * 8192' 1>&- ; echo $?
Traceback (most recent call last):
  File "<string>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor
1
</pre>
msg99353 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2010-02-15 06:45
This is not a bug. The output stream gets buffered, and that it is closed is only detected when a flush is attempted. Use the -u option if you want unbuffered stdout.

It is, however, a bug that Python 2.6 apparently fails to flush the output at all; Python 2.5 did that correctly.
msg99371 - (view) Author: (tholzer) Date: 2010-02-15 21:03
This is not quite correct:

The following 2 lines fail as expected (unbuffered):

<pre>
python -u -c 'import sys; print >> sys.stdout, "x"' 1>&- ; echo $?
python -u -c 'import sys; print >> sys.stderr, "x"' 2>&- ; echo $?
</pre>

whereas in the following example, the first command succeeds and the second one fails:

<pre>
python -c 'import sys; print >> sys.stdout, "x"' 1>&- ; echo $?
python -c 'import sys; print >> sys.stderr, "x"' 2>&- ; echo $?
</pre>

This is counter-intuitive and somewhat contradicts the documentation, as stderr always seems to be unbuffered (irrespective of the -u option). IMHO, they should either both fail or both succeed.

They seem to behave the same in 2.5 & 2.6, however in 3.1, they all die with a SIGABRT, which I guess could be questioned as well. IMHO, they should just throw an exception like in 2.6.
msg219898 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2014-06-06 21:24
Is there any interest in following this up as 2.6 is out of support?
msg220058 - (view) Author: (tholzer) Date: 2014-06-08 21:52
It's still a problem in Python 2.7:

python -c 'import sys; print >> sys.stdout, "x"' 1>&- ; echo $?
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
0

But feel free to close as "won't fix", as this seems to be an edge case which might not be worth fixing.
msg221303 - (view) Author: (eugenet) Date: 2014-06-22 20:01
A similar problem seems to appear in Python 3.5

./python -c 'import sys; print("x", file=sys.stdout)' 1>&- ; echo $? 
0

./python -c 'import sys; print("x", file=sys.stderr)' 2>&- ; echo $?
x
0

but again, this does seem to be a very specific corner case.
msg221343 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2014-06-23 05:31
I have no interest to work on this.
msg407103 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-11-26 22:59
Reproduced on 3.11:

cpython % ./python.exe -c 'import sys; print("x", file=sys.stdout)' 1>&- ; echo $? 
0
cpython % ./python.exe -c 'import sys; print("x", file=sys.stderr)' 2>&- ; echo $?
x
0
History
Date User Action Args
2022-04-11 14:56:57adminsetgithub: 52180
2021-11-26 22:59:25iritkatrielsetnosy: + iritkatriel

messages: + msg407103
versions: + Python 3.11, - Python 3.5
2019-03-15 23:38:43BreamoreBoysetnosy: - BreamoreBoy
2014-06-23 05:31:50loewissetnosy: - loewis
2014-06-23 05:31:37loewissetnosy: loewis, tholzer, BreamoreBoy, eugenet
messages: + msg221343
2014-06-22 20:01:52eugenetsetnosy: + eugenet

messages: + msg221303
versions: + Python 3.5, - Python 2.6
2014-06-08 21:52:25tholzersetmessages: + msg220058
2014-06-06 21:24:45BreamoreBoysetnosy: + BreamoreBoy
messages: + msg219898
2010-02-15 21:03:44tholzersetmessages: + msg99371
2010-02-15 06:45:03loewissetnosy: + loewis
messages: + msg99353
2010-02-15 01:04:07tholzercreate