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: Ambiguity with regard to the effect of accessing a closed IOBase instance
Type: behavior Stage: resolved
Components: Documentation, IO Versions: Python 3.2, Python 3.3, Python 3.4, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: akuchling, alexkon, asvetlov, benjamin.peterson, docs@python, hynek, math_foo, meador.inge, pitrou, python-dev, stutzbach
Priority: normal Keywords: patch

Created on 2012-09-01 18:33 by alexkon, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
comment15840.patch math_foo, 2014-04-14 19:11 review
Messages (10)
msg169660 - (view) Author: Alexander Konovalenko (alexkon) Date: 2012-09-01 18:33
Two pieces of the documentation for io.IOBase seem to contradict each other:

At http://docs.python.org/library/io.html#io.IOBase:
"Note that calling any method (even inquiries) on a closed stream is undefined. Implementations may raise IOError in this case."

At http://docs.python.org/library/io.html#io.IOBase.close:
"Once the file is closed, any operation on the file (e.g. reading or writing) will raise a ValueError."

Perhaps the confusion arises in part because it is not clear when a requirement for all IOBase implementations is documented and when the docs merely describe the default behavior of IOBase that implementations are free to override.

Those passages are inconsistent on two points:

1) IOError and ValueError are not subclasses one of another. So what should we expect an IOBase implementation to raise?

2) Undefined behavior means literally anything can happen. Technically, that means calling read() or readable() on a closed file (or other kind of stream) could wreak havoc in a totally unrelated part of the system or segfault the Python interpreter. That is definitely a thing to carefully avoid in any production systems.

On the other hand, raising an exception, even if we don't know in advance whether it will be ValueError or IOError, is pretty much defined behavior. An exception is easy to deal with and to contain inside a module.

So please clarify how dangerous it actually is to access an IOBase stream after it has been closed.
msg169663 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-09-01 19:13
> 1) IOError and ValueError are not subclasses one of another. So what
> should we expect an IOBase implementation to raise?

Ideally, ValueError should be raised, but I suspect some methods raise IOError instead.

> Undefined behavior means literally anything can happen.

In practice, it will either raise an error, or be ignored. For example, calling close() a second time would be ignored. Calling readable() may return the original value (before the file was closed), etc.

Any non-trivial behaviour should be reported as a bug, though. Especially, reading or writing methods (read(), write(), readline() etc.) should *never* succeed on a closed file.
msg169664 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-09-01 19:16
Actually, I would suggest we standardize the docs on raising ValueError as the official behaviour, and fix non-compliant behaviours as bugs.
msg169667 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-09-01 19:20
Related: issue15841 and issue15842.
msg178286 - (view) Author: Hynek Schlawack (hynek) * (Python committer) Date: 2012-12-27 09:48
I agree that standardize behavior here would be useful. But it sounds like a candidate for 3.4. Unifying/changing it for existing releases appears rather hairy to me?
msg178469 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2012-12-29 03:34
Agree with you, Hynek. It should be fixed in 3.4 only (and change should be well documented).
msg216181 - (view) Author: Caelyn McAulay (math_foo) Date: 2014-04-14 19:11
Changed documentation to state that ValueError should be raised if any operation (excluding close()) is called on a closed stream.

This appears to be what is done in iobase.c; and some investigation of inheriting types (rawiobase, fileio, bufferedio, etc.) indicates that there is nowhere where an IOError is being raised instead.

Sphinx documentation appears to already be update to date.

Is there any known place where operations on a closed stream raise IOError? I am currently assuming no.
msg216378 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014-04-15 20:16
New changeset 0c7cf0e598e7 by Andrew Kuchling in branch '2.7':
#15840: make docs consistent by saying operations on closed files raise ValueError.
http://hg.python.org/cpython/rev/0c7cf0e598e7
msg216413 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014-04-16 01:13
New changeset 7a27039e4a42 by Andrew Kuchling in branch '3.4':
#15840: make docs consistent by saying operations on closed files raise ValueError.
http://hg.python.org/cpython/rev/7a27039e4a42
msg216415 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2014-04-16 01:30
Committed to 2.7, 3.4, and default.  Thanks for your patch!
History
Date User Action Args
2022-04-11 14:57:35adminsetgithub: 60044
2014-04-16 01:30:54akuchlingsetstatus: open -> closed

nosy: + akuchling
messages: + msg216415

resolution: fixed
stage: needs patch -> resolved
2014-04-16 01:13:20python-devsetmessages: + msg216413
2014-04-15 20:16:02python-devsetnosy: + python-dev
messages: + msg216378
2014-04-14 19:11:42math_foosetfiles: + comment15840.patch

nosy: + math_foo
messages: + msg216181

keywords: + patch
2012-12-29 03:34:35asvetlovsetmessages: + msg178469
2012-12-29 02:41:48meador.ingesetnosy: + meador.inge
2012-12-27 09:48:01hyneksetassignee: docs@python ->
type: behavior
messages: + msg178286
versions: + Python 3.4
2012-09-02 16:45:52asvetlovsetnosy: + asvetlov
2012-09-01 19:20:25pitrousetmessages: + msg169667
2012-09-01 19:19:09pitrousetnosy: + benjamin.peterson, stutzbach, hynek
2012-09-01 19:16:53pitrousetmessages: + msg169664
2012-09-01 19:13:58pitrousetversions: + Python 3.2, Python 3.3
nosy: + pitrou

messages: + msg169663

components: + IO
stage: needs patch
2012-09-01 18:33:44alexkoncreate