Skip to content

TextIOWrapper: issues with interlaced read-write #56424

Closed

Description

@vstinner
BPO 12215
Nosy @terryjreedy, @pitrou, @vstinner, @vadmium
Files
  • textiowrapper_interlaced_read_write.patch
  • 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 2017-06-28.01:38:47.592>
    created_at = <Date 2011-05-30.12:38:03.460>
    labels = ['expert-IO']
    title = 'TextIOWrapper: issues with interlaced read-write'
    updated_at = <Date 2018-11-24.00:31:23.606>
    user = 'https://github.com/vstinner'

    bugs.python.org fields:

    activity = <Date 2018-11-24.00:31:23.606>
    actor = 'martin.panter'
    assignee = 'none'
    closed = True
    closed_date = <Date 2017-06-28.01:38:47.592>
    closer = 'vstinner'
    components = ['IO']
    creation = <Date 2011-05-30.12:38:03.460>
    creator = 'vstinner'
    dependencies = []
    files = ['22192']
    hgrepos = []
    issue_num = 12215
    keywords = ['patch']
    message_count = 9.0
    messages = ['137260', '137262', '137596', '137598', '137616', '221439', '258636', '297126', '330367']
    nosy_count = 5.0
    nosy_names = ['terry.reedy', 'pitrou', 'vstinner', 'Arfrever', 'martin.panter']
    pr_nums = []
    priority = 'normal'
    resolution = 'wont fix'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue12215'
    versions = ['Python 2.7', 'Python 3.4', 'Python 3.5']

    Activity

    1. vstinner commented on May 30, 2011

      @vstinner
      MemberAuthor

      The following code fails on an assertion error (Python exception for _pyio, C assertion for io):

      ------------------

      with io.BytesIO(b'abcd') as raw:
          with _pyio.TextIOWrapper(raw, encoding='ascii') as f:
              f.read(1)
              f.write('2')
              f.tell()

      I found this assertion while testing interlaced read-write on TextIOWrapper:
      ------------------

      with io.BytesIO(b'abcd') as raw:
          with _pyio.TextIOWrapper(raw, encoding='ascii') as f:
              f.write("1")
              # read() must call writer.flush()
              assertEqual(f.read(1), 'b')
              # write() must rewind the raw stream
              f.write('2')
              assertEqual(f.read(), 'd')
              f.flush()
              assertEqual(raw.getvalue(), b'1b2d')
      
      with io.BytesIO(b'abc') as raw:
          with _pyio.TextIOWrapper(raw, encoding='ascii') as f:
              self.assertEqual(f.read(1), b'a')
              # write() must undo reader readahead
              f.write(b"2")
              assertEqual(f.read(1), b'c')
              f.flush()
              assertEqual(raw.getvalue(), b'a2c')

      These tests fails on "read, write, read" path: write() breaks TextIOWrapper internal state if a read() occured just before. Note that _pyio.TextIOWrapper.write() contains the following comment...

      # XXX What if we were just reading?

      See also the issue bpo-12213 for BufferedRandom and BufferedRWPair.

    2. vstinner commented on May 30, 2011

      @vstinner
      MemberAuthor

      textiowrapper_interlaced_read_write.patch: TextIOWrapper.write() calls self.seek(self.tell()) if it has a decoder or if snapshot is not None.

      I suppose that we can do better, but at least it does fix this issue.

      "read(); write(); write()" only calls self.seek(self.tell()) once, at the first write. So I don't think that it changes anything with performances.

      In which case snapshot can be not different than None, whereas decoder is None?

    3. terryjreedy commented on Jun 3, 2011

      @terryjreedy
      Member

      For c stdio files, intermixed reads and writes require a file positioning operation. This is a nuisance and source of program bugs. I do not see any such limitation documented for our io module. So for both reasons, it will be nice to not have the limitation in the code.

      If I understand, the essence of the patch is to do the file positioning automatically internally when needed.

    4. vstinner commented on Jun 3, 2011

      @vstinner
      MemberAuthor

      If I understand, the essence of the patch is to do
      the file positioning automatically internally when needed.

      My patch is just a proposition to fix the issue. I wrote "I suppose that we can do better": self.seek(self.tell()) is more a workaround than a real fix. I don't understand why it does fix this bug :-)

    5. terryjreedy commented on Jun 4, 2011

      @terryjreedy
      Member

      Perhaps the stdio requirement was based on an underlying OS (*nix?) requirement, which io has to fulfill even if it does not use stdio.

      Stdio was, I presume, optimized for speed. In the relatively rare case of mixed read/write, it *should* put the burden on the programmer. Python is a bit different.

    6. BreamoreBoy commented on Jun 24, 2014

      BreamoreBoymannequin
      Mannequin

      Does anybody want to follow up on this? bpo-12213 was closed as fixed, bpo-12513 is still open.

    7. vadmium commented on Jan 20, 2016

      @vadmium
      Member

      Consider codecs that maintain an internal buffer (UTF-7) or other state (ISO-2022). When you call TextIOWrapper.read() and then tell(), the I think the returned number is supposed to hold the _decoder_ state, so you can seek back and read again. But I don’t think the number holds any _encoder_ state, so seek() cannot set up the encoder properly for these more awkward codecs.

      I don’t think it is practical to fix this problem using the incremental codec API. You would need to construct the encoder’s state from the decoder. There are a couple of bugs marked as duplicates of this. What are the real-world use cases?

    8. vstinner commented on Jun 28, 2017

      @vstinner
      MemberAuthor

      Given that nobody complains the last 9 years (since Python 3.0 was released), I'm not sure that it's worth it to fix this corner case.

      If you consider that I'm wrong, please reopen the issue ;-)

    9. vadmium commented on Nov 24, 2018

      @vadmium
      Member

      For the record, the more recent bug I mentioned was a complaint from 2015 (one and a half years before Victor’s comment). Even if it is not worth supporting writing after reading, the problem could be documented.

    10. 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

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions