Skip to content

gh-109523: Reading text from a non-blocking stream with read may now raise a BlockingIOError if the operation cannot immediately return bytes. #122933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
61cdfc5
Add unittest to handle non-blocking read scenarios.
giosiragusa Aug 12, 2024
5123ff6
📜🤖 Added by blurb_it.
blurb-it[bot] Aug 12, 2024
7a9037f
Update documentation for Text I/O and Buffered Streams to include han…
giosiragusa Aug 15, 2024
c31b0c7
Fix double backticks for inline literals.
giosiragusa Aug 15, 2024
ade7db0
Add a more meaningful message for the BlockingIOError.
giosiragusa Aug 15, 2024
0953ad0
Updated the TextIOWrapper test to use self.io.open() instead of open(…
giosiragusa Aug 15, 2024
100c4cb
- Raise `BlockingIOError` in `TextIOWrapper.read()` in `_pyio.py` whe…
giosiragusa Aug 15, 2024
bf5cc2b
Update NEWS entry to include references to _io and _pyio for Blocking…
giosiragusa Aug 17, 2024
fc02b20
Align documentation and code with Python style practices
giosiragusa Aug 17, 2024
c2d14e3
Fix news message for sphinx-lint
giosiragusa Aug 17, 2024
a735fff
Fix news message for sphinx-lint
giosiragusa Aug 17, 2024
5f1cbae
Fix news message for sphinx-lint
giosiragusa Aug 17, 2024
cabdf39
Make notes more consistent
giosiragusa Aug 17, 2024
8286a0a
Align BlockingIOError message in _pyio.py with the C implementation i…
giosiragusa Sep 19, 2024
8690397
Add blank line after note.
giosiragusa Nov 27, 2024
2f7fbb2
Remove unnecessary blank lines.
giosiragusa Nov 27, 2024
dbd807d
Keep the error message simple.
giosiragusa Nov 27, 2024
1ac9096
Release the reference before throwing the exception.
giosiragusa Nov 27, 2024
7d05cc3
Add blank line after notes.
giosiragusa Nov 27, 2024
9f1c5f4
Remove unnecessary blank lines.
giosiragusa Nov 27, 2024
317d402
Added what's new entry.
giosiragusa Nov 29, 2024
8e4e661
Update Doc/whatsnew/3.14.rst
giosiragusa Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Lib/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -3919,6 +3919,22 @@ def test_issue35928(self):
f.write(res)
self.assertEqual(res + f.readline(), 'foo\nbar\n')

@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
def test_read_non_blocking(self):
import os
r, w = os.pipe()
try:
os.set_blocking(r, False)
with open(r, 'r') as textfile:
r = None
# Nothing has been written so a non-blocking read raises a BlockingIOError exception.
with self.assertRaises(BlockingIOError):
textfile.read()
finally:
if r is not None:
os.close(r)
os.close(w)


class MemviewBytesIO(io.BytesIO):
'''A BytesIO object whose read method returns memoryviews
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In _io_TextIOWrapper_read_impl, raise BlockingIOError when read() from a non-blocking pipe does not return bytes.
6 changes: 6 additions & 0 deletions Modules/_io/textio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,12 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
if (bytes == NULL)
goto fail;

if (bytes == Py_None){
PyErr_SetString(PyExc_BlockingIOError, "read() should return bytes");
return NULL;

}

_PyIO_State *state = self->state;
if (Py_IS_TYPE(self->decoder, state->PyIncrementalNewlineDecoder_Type))
decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
Expand Down
Loading