bpo-25862: Fix assertion failures in io.TextIOWrapper.tell(). (GH-3918) · python/cpython@eabebbb

File tree

4 files changed

lines changed

  • Misc/NEWS.d/next/Core and Builtins

4 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -2149,6 +2149,7 @@ def write(self, s):

21492149

self.buffer.write(b)

21502150

if self._line_buffering and (haslf or "\r" in s):

21512151

self.flush()

2152+

self._set_decoded_chars('')

21522153

self._snapshot = None

21532154

if self._decoder:

21542155

self._decoder.reset()

Original file line numberDiff line numberDiff line change

@@ -3549,6 +3549,17 @@ def test_reconfigure_newline(self):

35493549

expected = 'linesep' + os.linesep + 'LF\nLF\nCR\rCRLF\r\n'

35503550

self.assertEqual(txt.detach().getvalue().decode('ascii'), expected)

35513551
3552+

def test_issue25862(self):

3553+

# Assertion failures occurred in tell() after read() and write().

3554+

t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii')

3555+

t.read(1)

3556+

t.read()

3557+

t.tell()

3558+

t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii')

3559+

t.read(1)

3560+

t.write('x')

3561+

t.tell()

3562+
35523563
35533564

class MemviewBytesIO(io.BytesIO):

35543565

'''A BytesIO object whose read method returns memoryviews

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,2 @@

1+

Fix assertion failures in the ``tell()`` method of ``io.TextIOWrapper``.

2+

Patch by Zackery Spytz.

Original file line numberDiff line numberDiff line change

@@ -694,6 +694,9 @@ typedef struct

694694

PyObject *dict;

695695

} textio;

696696
697+

static void

698+

textiowrapper_set_decoded_chars(textio *self, PyObject *chars);

699+
697700

/* A couple of specialized cases in order to bypass the slow incremental

698701

encoding methods for the most popular encodings. */

699702

@@ -1606,6 +1609,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text)

16061609

Py_DECREF(ret);

16071610

}

16081611
1612+

textiowrapper_set_decoded_chars(self, NULL);

16091613

Py_CLEAR(self->snapshot);

16101614
16111615

if (self->decoder) {

@@ -1835,6 +1839,7 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)

18351839

if (result == NULL)

18361840

goto fail;

18371841
1842+

textiowrapper_set_decoded_chars(self, NULL);

18381843

Py_CLEAR(self->snapshot);

18391844

return result;

18401845

}