Undocumented issue: Open system call blocks on named pipes (and a feature request)

Chris Angelico rosuav at gmail.com
Thu Dec 27 22:09:53 EST 2018

On Fri, Dec 28, 2018 at 1:38 PM Daniel Ojalvo via Python-list
<python-list at python.org> wrote:
> Hello,
> I've been working on a python3 project and I came across an issue with the open system call that, at the very least, isn't documented. In my humble opinion, the documentation<https://docs.python.org/3/library/functions.html#open> should be updated because folks wouldn't expect open to be a blocking operation and simply error out. Worse yet, open doesn't have an option to make itself non-blocking. You have to use the os system calls to kludge a solution.

Hmm. I disagree that the docs are deceptive here; I would normally
expect open() to block if it needs to. But looking at this as a
feature request, it seems reasonable. Actually, it's not even that
hard to do, since open() is already pluggable:

rosuav at sikorsky:~/tmp$ rm rene_magritte
rosuav at sikorsky:~/tmp$ mkfifo rene_magritte
rosuav at sikorsky:~/tmp$ ls -l rene_magritte
prw-r--r-- 1 rosuav rosuav 0 Dec 28 14:05 rene_magritte
rosuav at sikorsky:~/tmp$ python3
Python 3.8.0a0 (heads/master:8b9c33ea9c, Nov 20 2018, 02:18:50)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> def nonblock(fn, mode): return os.open(fn, mode | os.O_NONBLOCK)
>>> open("rene_magritte", opener=nonblock)
<_io.TextIOWrapper name='rene_magritte' mode='r' encoding='UTF-8'>
>>> _.read(1)

> Here is how I reproduced the issue:
> root at beefy:~/sandbox# mkfifo this_is_a_pipe

(my example file name is a more subtle reference...)

> I'm doing this to get a fileobject and make it error out if we do have a blocking special file:
> with os.fdopen(os.open(<filename>, os.O_RDONLY| os.O_NONBLOCK) , mode='rb') as file_obj:
> I think this is mostly a documentation bug because this wouldn't be expected behavior to someone reading the docs, but open is behaving as the fifo man page<http://man7.org/linux/man-pages/man7/fifo.7.html> is documented. The feature request would be to add a non-blocking option to the default open system call.

Honestly, I don't think there's a problem with it blocking by default.
Most of Python works that way. But it would be pretty straight-forward
to add "nonblocking=False" as another keyword-only parameter, and for
compatibility with existing versions (back as far as 3.3), the opener
should work just fine.


More information about the Python-list mailing list