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: io.TextIOWrapper always closes wrapped files
Type: enhancement Stage: resolved
Components: Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: aronacher, eryksun, martin.panter, mhvk, mitar, r.david.murray
Priority: normal Keywords:

Created on 2014-04-27 12:56 by aronacher, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (8)
msg217260 - (view) Author: Armin Ronacher (aronacher) * (Python committer) Date: 2014-04-27 12:56
I'm trying to write some code that fixes a misconfigured sys.stdin on a case by case bases but unfortunately I cannot use TextIOWrapper for this because it always closes the underlying file:


Python

>>> import io
>>> sys.stdin.encoding
'ANSI_X3.4-1968'
>>> stdin = sys.stdin
>>> correct_stdin = io.TextIOWrapper(stdin.buffer, 'utf-8')
>>> correct_stdin.readline()
foobar
'foobar\n'
>>> del correct_stdin
>>> stdin.readline()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.

Ideally there would be a way to disable this behavior.
msg217278 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2014-04-27 16:21
It works if you detach the buffer beforehand:

    >>> import io, sys
    >>> stdin = sys.stdin
    >>> stdin.flush()
    >>> correct_stdin = io.TextIOWrapper(stdin.buffer, 'utf-8')
    >>> correct_stdin.readline()
    foobar
    'foobar\n'

    >>> correct_stdin.detach()
    <_io.BufferedReader name='<stdin>'>

    >>> del correct_stdin
    >>> stdin.readline()
    foobar
    'foobar\n'
msg218575 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-05-14 21:38
I think detach is the correct way to to this, so I'm closing the issue.
msg218576 - (view) Author: Armin Ronacher (aronacher) * (Python committer) Date: 2014-05-14 21:40
Detach "destroys" the stream, so it's not a solution.  I can't just randomly destroy global state just because it's convenient.

This is what I am doing now which seems borderline insane: https://github.com/mitsuhiko/click/blob/master/click/_compat.py#L31
msg218577 - (view) Author: Armin Ronacher (aronacher) * (Python committer) Date: 2014-05-14 21:42
Ah. Misread.  This is about detaching the underlying stream from TextIOWrapper.  I assume this could be done in the __del__ so that would work.  I'm checking this now.
msg218578 - (view) Author: Armin Ronacher (aronacher) * (Python committer) Date: 2014-05-14 21:45
I can confirm that calling detach() in __del__ within an except block solves the issue.
msg328156 - (view) Author: Mitar (mitar) * Date: 2018-10-20 16:13
I have a similar problem that text wrapper is closing the handle, and if I want to make a workaround, it also fails:

buffer = io.Bytes()
with io.TextIOWrapper(buffer, encoding='utf8') as text_buffer:
    write_content_to(text_buffer)
    text_buffer.flush()
    text_buffer.detach()

Now this fails when context manager is trying to close the text_buffer with an error that it is already detached. If I do not detach it, then it closes buffer as well.
msg395005 - (view) Author: Marten H. van Kerkwijk (mhvk) Date: 2021-06-03 15:01
In astropy we are now working around the auto-closing of the underlying stream in TextIOWrapper by subclassing and overriding `__del__` to detach [1]. It would seem more elegant if `TestIOWrapper` (and really, `BufferedReader`) could gain an `closefd` argument, just like `open` has, which is `True` by default.

p.s. Do let me know if it is better to open a new issue.

[1] https://github.com/astropy/astropy/pull/11809
History
Date User Action Args
2022-04-11 14:58:02adminsetgithub: 65562
2021-06-03 15:01:56mhvksettype: enhancement

messages: + msg395005
nosy: + mhvk
2018-10-20 16:13:57mitarsetnosy: + mitar
messages: + msg328156
2014-05-14 21:45:23aronachersetmessages: + msg218578
2014-05-14 21:42:11aronachersetmessages: + msg218577
2014-05-14 21:40:23aronachersetmessages: + msg218576
2014-05-14 21:38:28r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg218575

resolution: not a bug
stage: resolved
2014-05-02 02:39:05martin.pantersetnosy: + martin.panter
2014-04-27 16:21:14eryksunsetnosy: + eryksun
messages: + msg217278
2014-04-27 12:56:29aronachercreate