-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-103510: Support os.mkfifo
on Windows
#129420
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
Conversation
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Make os.mkfifo return an open fd on Windows and the original path object on Unix. The user would then pass the return value into open, which accepts both path and fd as file.
7fb0442
to
3cafd46
Compare
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
os.mkfifo
on Windows
Happy Year of the Snake! Could you add news entry(see bot) and update the document description? https://github.com/python/cpython/blob/main/Doc%2Flibrary%2Fos.rst#L2586-L2586 It would be even better if it could add whatnew3.14. Thanks! |
Hi @Wulian233, thanks for the response! For this draft PR I have not yet polished the formalities (and test cases as well), since the exact choice of API change is still unsettled. Once there is consensus (1 vs 2, whether to restrict number of instances, etc.), I will complete those and mark this PR ready for review. |
Py_END_ALLOW_THREADS | ||
if (INVALID_HANDLE_VALUE == h) | ||
return win32_error_object("CreateNamedPipeW", path->object); | ||
fd = _Py_open_osfhandle(h, _O_RDWR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_Py_open_osfhandle()
can return -1: see the Windows implementation of os.pipe()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's strange that that Windows implementation returns a file descriptor, whereas the Unix implementation returns None. I'm not sure if this change is a good idea :-(
@@ -12544,6 +12544,21 @@ static PyObject * | |||
os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) | |||
/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/ | |||
{ | |||
#ifdef MS_WINDOWS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should raise an error if dir_fd is used.
You should document that the mode is ignored on Windows.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Would option 2 be better in this case? It would be more verbose, but could avoid the multiplexed return type. |
This sounds like an incompatible change. You cannot simply modify |
Sorry I did not make it clear, old code that does not specify |
@SuibianP It's not as easy as you think. First, don't add any new arguments. Use the I suggest you create a symbolic link to Because a named pipe can only be opened once on each side, you need to create the illusion of the opposite. With Create 2 new objects from
All operations will be blocking, everything written will be received by the process that started it. Overlapped is required to read all incoming messages from several processes. The read data is not duplicated and is transferred to the first client. To create a named pipe identical to Unix, you will need a separate thread that will create a new NamedPipe instance for each open.
You also need to consider whether open() will be a blocking operation. Should you add |
I think we could consider changing os.mkfifo return value.
Then it would close the issue with:
And also allow open() to distinguish objects like: Dividing into Server and Client objects only allows creating several Clients. And a separate thread will constantly consume resources and slow down the interpreter. The simplest case will be os.mkfifo, which allows only 2 processes, but this is not very cool. |
I close the issue. You should go back to the design phase and first propose an API which works on all platforms. IMO modifying os.mkfifo() to return a file descriptor only on Windows is not an option. |
Please kindly take a look at API option 2 as proposed in my original PR body and second response, where |
I dislike option 2, since existing code using mode would suddenly leaks a file descriptor whereas the code works fine with Python 3.13. I suggest to continue the discussion in the issue instead. You may add a new function instead. |
Happy Year of the Snake!
The current common practice of
os.mkfifo
thenopen
the path cannot possibly be made to work on Windows (barring global state hacks at least), due to the named pipe semantics and indivisibility atNtCreateNamedPipeFile
syscall level. That said, it should be feasible to supportos.mkfifo
on Windows for the simple IPC case (named pipe with single R/W end) with certain API changes. There seems to be two ways forward:os.mkfifo
to return an open fd on Windows and the originalpath
object on Unix. The user would then pass the return value intoopen
, which accepts both path and fd asfile
. The fd, however, will always beO_RDWR
on Windows.os.mkfifo
to accept an additionalopen_mode
argument, and always returns an open fd or file object on any platform.This experimental patch that would fix #103510 implements the simpler former for a start.
It would have been convenient to automatically prepend the
\\.\pipe\
prefix so thatos.mkfifo("/tmp/mypipe")
can be truly platform independent, but this is not currently the case on VxWorks and the user likely would still need the full filename. Maybe something likeos.pipe_prefix
would help.Any comments would be much appreciated.