Skip to content

io.TextIOWrapper always closes wrapped files #65562

Closed

Description

@mitsuhiko
BPO 21363
Nosy @mitsuhiko, @bitdancer, @mitar, @vadmium, @eryksun, @mhvk

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2014-05-14.21:38:28.102>
created_at = <Date 2014-04-27.12:56:29.304>
labels = ['type-feature', 'invalid']
title = 'io.TextIOWrapper always closes wrapped files'
updated_at = <Date 2021-06-03.15:01:56.919>
user = 'https://github.com/mitsuhiko'

bugs.python.org fields:

activity = <Date 2021-06-03.15:01:56.919>
actor = 'mhvk'
assignee = 'none'
closed = True
closed_date = <Date 2014-05-14.21:38:28.102>
closer = 'r.david.murray'
components = []
creation = <Date 2014-04-27.12:56:29.304>
creator = 'aronacher'
dependencies = []
files = []
hgrepos = []
issue_num = 21363
keywords = []
message_count = 8.0
messages = ['217260', '217278', '218575', '218576', '218577', '218578', '328156', '395005']
nosy_count = 6.0
nosy_names = ['aronacher', 'r.david.murray', 'mitar', 'martin.panter', 'eryksun', 'mhvk']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue21363'
versions = []

Activity

  1. mitsuhiko commented on Apr 27, 2014

    @mitsuhiko
    MemberAuthor

    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.

  2. eryksun commented on Apr 27, 2014

    @eryksun
    Contributor

    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'
  3. bitdancer commented on May 14, 2014

    @bitdancer
    Member

    I think detach is the correct way to to this, so I'm closing the issue.

  4. mitsuhiko commented on May 14, 2014

    @mitsuhiko
    MemberAuthor

    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

  5. mitsuhiko commented on May 14, 2014

    @mitsuhiko
    MemberAuthor

    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.

  6. mitsuhiko commented on May 14, 2014

    @mitsuhiko
    MemberAuthor

    I can confirm that calling detach() in __del__ within an except block solves the issue.

  7. mitar commented on Oct 20, 2018

    mitarmannequin
    Mannequin

    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.

  8. mhvk commented on Jun 3, 2021

    mhvkmannequin
    Mannequin

    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] astropy/astropy#11809

  9. transferred this issue fromon Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions