Issue 12939: Add new io.FileIO using the native Windows API (original) (raw)

Created on 2011-09-08 23:19 by vstinner, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (40)

msg143741 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2011-09-08 23:19

On Windows, Python uses the POSIX API (file descriptors), instead of the native API (file handles). Some features cannot be used using the POSIX API, like setting security attributes. It would be nice to have a io.FileIO using Windows file handlers to get access to all Windows features. It would help feature #12105 to implement "O_CLOEXEC" flag using the lpSecurityAttributes argument.

We can maybe try with a prototype written in Python. Using _pyio.RawIOBase, only readinto(), write(), seek() and truncate() have to be implemented. But it is better to implement also close() :-)

msg143742 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2011-09-08 23:21

See also issue #1602: a prototype of a console object has been proposed to use the native Windows console API, instead of the POSIX API (read from fd 0, write to fd 1 or 2). The prototype is implemented in Python using ctypes.

msg146769 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2011-11-01 12:12

Instead of rewriting your own RawIO implementation, why not use _open_osfhandle? This should be simple now with the "opener" argument. http://msdn.microsoft.com/en-us/library/bdts1c9x.aspx

msg146788 - (view)

Author: Марк Коренберг (socketpair) *

Date: 2011-11-01 16:25

why not use _open_osfhandle?

Because it is wrapper for other CRT functions for Windows, like close(). In other words it is an emulation. I think Python should not create wrapper around wrapper around wrapper...

For example, in Python3, open() implemented using open() and not using fopen(). Why we should use another wrapper on Windows platform?

msg146789 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2011-11-01 16:33

why not use _open_osfhandle?

Because it is wrapper for other CRT functions for Windows, like close(). In other words it is an emulation. I think Python should not create wrapper around wrapper around wrapper...

Why do you think it makes a difference?

msg146792 - (view)

Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer)

Date: 2011-11-01 16:49

An implementation of RawIO with the win32 API can be useful (and I'd be interested to compare the performance) But maybe not for all usages: some Python interfaces are defined in terms of file descriptors, imp.load_module(), and PyTokenizer_FindEncoding for example.

msg146795 - (view)

Author: Марк Коренберг (socketpair) *

Date: 2011-11-01 16:56

Why do you think it makes a difference? Because adding one more dependency on unneeded libraries add the pain. Also it limit us on very restricted API of that wrapper. Windows native API is stable. So it's OK to rely on it's documented imlementation.

Suppose, we receive file-descriptor from _open_osfhandle.... For example it is a socket. It still unusable for stdin. Many standard functions does not work with such handle. The list of available functions : http://msdn.microsoft.com/en-us/library/kdfaxaay.aspx . As we see it is very narrow and function names are not POSIX-compatible (_chsize vs ftruncate). Documentation is very poor. For example, _close() is documented only here: http://msdn.microsoft.com/en-US/library/40bbyw78(v=VS.80).aspx .

msg146796 - (view)

Author: Марк Коренберг (socketpair) *

Date: 2011-11-01 17:02

The good example of implemetation is QT. I think we can get some things from this library. (Like using "\?" for long paths (or always, as in QT)).

msg146797 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2011-11-01 17:11

Why do you think it makes a difference? Because adding one more dependency on unneeded libraries add the pain.

MSVCRT is unneeded?? What are you talking about?

Also it limit us on very restricted API of that wrapper. Windows native API is stable. So it's OK to rely on it's documented imlementation.

Please provide a patch to demonstrate the claimed improvement.

Like using "\?" for long paths

That's completely unrelated to this issue.

msg146837 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2011-11-02 12:54

Instead of rewriting your own RawIO implementation, why not use _open_osfhandle?

I don't know yet what is the best approach. One important point is to keep the HANDLE, to be able to manipulate the open file using the Windows API (e.g. call WriteFile instead of write).

I propose a RawIO to call directly the Windows API: file.write() would call directly WriteFile() instead of the POSIX wrapper (write()).

We may use it to implement new features like async I/O on Windows (e.g. WriteFileEx).

Modules/_multiprocessing/win32_functions.c exposes already some low-level Windows functions like WriteFile(). We may reuse the RawIO to offer an object oriented API for the Windows multiprocessing pipes. Such RawIO would have extra methods, maybe a file.WriteFile() method to give access to extra options like "overlapped".

msg178900 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2013-01-03 02:12

I'm not really motivated to work on a Windows-specific issue. The issue has no patch, even no proof-of-concept implemented in Python. Can I close the issue, or is someone interested to work on this topic?

Python 3.3 adds a opener argument to open(). It may be enough to workaround this issue?

msg178923 - (view)

Author: Марк Коренберг (socketpair) *

Date: 2013-01-03 08:13

Yes, re-writing windows IO to direct API, without intemediate layer is still needed.

Please don't close bug. Maybe someone will implement this.

msg178943 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-03 13:11

A while ago I did write a PipeIO class which subclasses io.RawIOBase and works for overlapped pipe handles. (It was intended for multiprocessing and doing asynchronous IO with subprocess.)

As it is it would not work with normal files because when you do overlapped IO on files you must manually track the file position.

Yes, re-writing windows IO to direct API, without intemediate layer is still needed.

What are the expected benefits?

It would help feature #12105 to implement "O_CLOEXEC" flag using the lpSecurityAttributes argument.

Isn't O_NOINHERIT the Windows equivalent of O_CLOEXEC?

msg178969 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-03 17:36

Attached is a module for Python 3.3+ which subclasses io.RawIOBase. The constructor signature is

WinFileIO(handle, mode="r", closehandle=True)

where mode is "r", "w", "r+" or "w+". Handles can be created using _winapi.CreateFile().

Issues:

msg179181 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-06 13:59

Attached is a patch which adds a winio module which is a replacement for io, but uses windows handles instead of fds.

It reimplements FileIO and open(), and provides openhandle() and closehandle() as replacements for os.open() and os.close().

test_io has been modified to exercise winio (in addition to _io and _pyio) and all the tests pass.

Note that some of the implementation (openhandle(), open(), FileIO.init()) is still done in Python rather than C.

msg179229 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2013-01-06 21:30

I don't like the idea of a specific I/O module for an OS. Is the public API different? Can't you reuse the io module? Le 6 janv. 2013 14:59, "Richard Oudkerk" <report@bugs.python.org> a écrit :

Richard Oudkerk added the comment:

Attached is a patch which adds a winio module which is a replacement for io, but uses windows handles instead of fds.

It reimplements FileIO and open(), and provides openhandle() and closehandle() as replacements for os.open() and os.close().

test_io has been modified to exercise winio (in addition to _io and _pyio) and all the tests pass.

Note that some of the implementation (openhandle(), open(), FileIO.init()) is still done in Python rather than C.


keywords: +patch Added file: http://bugs.python.org/file28590/winfileio.patch


Python tracker <report@bugs.python.org> <http://bugs.python.org/issue12939>


msg179232 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-06 21:43

I don't like the idea of a specific I/O module for an OS. Is the public API different?

It was partly to make integration with the existing tests easier: _io, _pyio and winio are tested in parallel.

Can't you reuse the io module?

In what sense?

I don't really know how the API should be exposed.

msg179269 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2013-01-07 16:01

Hum, _get_osfhandle() was not mentionned in this issue. This function may be used to retrieve the internel file handle from a file descriptor. http://msdn.microsoft.com/en-us/library/ks2530z6%28v=vs.100%29.aspx

There is also the opposite: _open_osfhandle(). This function may be used for fileno() method of the Windows implementation of FileIO. http://msdn.microsoft.com/en-us/library/bdts1c9x%28v=vs.100%29.aspx

msg179809 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-12 15:13

Attached is a new patch which is implemented completely in C.

It adds a WinFileIO class to the io module, which has the same API as FileIO except that:

The patch also adds a keyword-only "rawfiletype" argument to io.open() so that you can write

f = open("somefile", "w", rawfiletype=WinFileIO)

msg179811 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-12 15:19

Forgot to mention, the handles are non-inheritable.

You can use _winapi.DuplicateHandle() to create an inheritable duplicate handle if you really need to.

msg179943 - (view)

Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer)

Date: 2013-01-14 14:36

Added some comments on Rietveld. The .fileno() method is missing. Can this cause a problem when the file is passed to stdlib functions? subprocess for example?

msg179944 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2013-01-14 14:42

What does this proposal bring exactly?

msg179973 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-14 19:55

Added some comments on Rietveld. The .fileno() method is missing. Can this cause a problem when the file is passed to stdlib functions? subprocess for example?

Thanks. An older version of the patch had a fileno() method which returned the handle -- but that would have confused anything that expects fileno() to return a true fd.

It would be possible to make fileno() lazily create an fd using open_osfhandle().

msg179975 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-14 20:17

What does this proposal bring exactly?

Unless we are willing to completely replace fds with handles on Windows, perhaps not too much. (At one point I had assumed that that was the plan for py3k.)

Although not advertised, openhandle() does have a share_flags parameter to control the share mode of the file. This makes it possible to delete files for which there are open handles. Mercurial needs a C extension to support this. regrtest could certainly benefit from such a feature.

But one thing that I would at least like to do is create a FileIO replacement for overlapped pipe/socket handles. Then multiprocessing.Connection could be a simple wrapper round a file object, and most of the platform specific code in multiprocessing.connection can go away.

The current patch does not support overlapped IO, but that could be added easily enough. (Overlapped IO for normal files might be more complicated.)

msg180014 - (view)

Author: Richard Oudkerk (sbt) * (Python committer)

Date: 2013-01-15 12:33

New patch reflecting Amaury's comments.

msg180043 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2013-01-15 19:31

The current patch does not support overlapped IO, but that could be added easily enough. (Overlapped IO for normal files might be more complicated.)

That could be cool. Wouldn't it belong in the fabled winapi module?

msg180102 - (view)

Author: Guido van Rossum (gvanrossum) * (Python committer)

Date: 2013-01-16 19:04

Just a note of support for Richard -- having I/O use the native APIs directly rather than via emulation or other wrappers is a good idea, because the emulations / wrappers usually add restrictions that are not present in the native API. This is also the reason why we dropped going through stdio -- it did not give enough control over buffering and made integration with (UNIX native) file descriptors complex. Integration with native I/O primitives on Windows seems sense in the light of e.g. PEP 3156.

msg199413 - (view)

Author: Piotr Dobrogost (piotr.dobrogost)

Date: 2013-10-10 21:14

I guess extracting Richard's patch to a package and placing it on PyPI would be a good move. I recalled reading this bug after I saw "Does Python IO allow opened file to be deleted/renamed on Windows?" question on Stackoverflow (http://stackoverflow.com/q/19280836/95735)

msg222661 - (view)

Author: Mark Lawrence (BreamoreBoy) *

Date: 2014-07-10 12:32

It strikes me as far more sense to use the native API so how do we take this forward, formal patch review, put it on pypi, or what?

msg222663 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2014-07-10 12:51

Serhiy implemented the FileIO class in pure Python: see the issue #21859 (patch under review). Using thre Python class, it becomes easier to reimplement FileIO using the Windows API, at least to play with a prototype in pure Python.

msg252160 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2015-10-02 21:11

Lack of interest, I'm not convinced that it's really needed. We survived 8 years with the current io module in Python 3, it's probably enough. I close the issue.

msg252235 - (view)

Author: Марк Коренберг (socketpair) *

Date: 2015-10-03 20:11

Please reopen. I still have interest for that. Fact that we survive 8 years is not enough for closing bugs as "Won't fix".

This fact point only on that ther are no good specialists that can fix that bug, since it is Windows-only, actually.

msg252236 - (view)

Author: Марк Коренберг (socketpair) *

Date: 2015-10-03 20:12

Sorry, for the "there are no good specialist". I mean "There are no well motivated good specialist" :)

msg252241 - (view)

Author: R. David Murray (r.david.murray) * (Python committer)

Date: 2015-10-03 21:29

Since Guido voted in favor and there's a patch proposal, I think we should keep this open in the hopes that someone will come along who can move it forward. I don't know enough to know what moving it forward would look like, though.

(I know you opened the issue originally, Victor, and you aren't interested in it any more, but obviously others are.)

msg252247 - (view)

Author: Mark Lawrence (BreamoreBoy) *

Date: 2015-10-03 22:49

If Марк Коренберг (mmarkk) is interested, they should move it forward. If they're not interested, move it too "languishing", where it can sit happily for ever and a day. Pay your money, take your choice?

msg252261 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2015-10-04 07:49

I reopen the issue. The patch is outdated. Richard Oudkerk doens't seem to be active last weeks :-/

msg297130 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2017-06-28 01:41

While it might be a good idea, we failed to find anyone to implement it in 6 years, and so I close the issue. Sorry!

msg297178 - (view)

Author: R. David Murray (r.david.murray) * (Python committer)

Date: 2017-06-28 12:54

If it's a good idea, why close the issue? Maybe post it to core-mentorship instead? It's not an easy issue, but it also has the beginnings of a patch. So if there is anyone on core-mentorship with some windows knowledge (and I'm guessing their are), maybe they'd be interested in the challenge.

msg297183 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2017-06-28 13:33

R. David Murray: "If it's a good idea, why close the issue?"

Yesterday I tried to cleanup the list of issues that I opened. I reduced my list from 140 to around 100 issues. I'm happier :-) I don't like having a too long "TODO list".

Sometimes, closing an issue helps to shake up people and it can even unblock an old issue :-)

In this case, I already closed and then reopened the issue, and nothing happened.

The benefit doesn't seem worth it, compared to the risk of backward compatibility issue and the cost of maintaining this new code.

"Maybe post it to core-mentorship instead? It's not an easy issue, but it also has the beginnings of a patch."

Sorry, but it's very far from an easy issue. It seems like even our existing Windows experts failed to implement the feature in 6 years. I don't expect that any newcomer will success to fix the technical issues, especially if nobody is available to answer to the newcomer questions...

It's not because an issue is closed that the data that it contains is definitevely lost. If someone wants to work on that issue, it will be easy to find this issue using a Google search.

I see open issues as "bugs that must be fixed" or "important missing features", not as an unlimited wishlist. I know that each developer uses a bug tracker differently ;-)

At least, I don't want to the author of such wishlist issue anymore, and I don't want how to change the author of an issue. So I will continue to close it regulary to reduce my list of open issues (that I opened). Again, it's important for me to keep this list as short as possible.

msg297201 - (view)

Author: R. David Murray (r.david.murray) * (Python committer)

Date: 2017-06-28 17:28

Given that background, closing it seems reasonable to me :)

History

Date

User

Action

Args

2022-04-11 14:57:21

admin

set

github: 57148

2017-06-28 17:28:38

r.david.murray

set

messages: +

2017-06-28 13:33:43

vstinner

set

messages: +

2017-06-28 12:54:54

r.david.murray

set

messages: +

2017-06-28 01:41:16

vstinner

set

status: open -> closed
resolution: out of date
messages: +

stage: needs patch -> resolved

2015-10-11 17:20:05

davin

set

nosy: + davin

2015-10-09 17:38:42

steve.dower

set

nosy: + steve.dower

2015-10-04 07:49:51

vstinner

set

status: closed -> open
resolution: out of date -> (no value)
messages: +

2015-10-03 22:49:41

BreamoreBoy

set

messages: +

2015-10-03 21:29:10

r.david.murray

set

nosy: + r.david.murray

messages: +
versions: + Python 3.6, - Python 3.5

2015-10-03 20:12:25

socketpair

set

messages: +

2015-10-03 20:11:10

socketpair

set

messages: +

2015-10-02 21:11:42

vstinner

set

status: open -> closed
resolution: out of date
messages: +

2014-11-01 20:35:07

rpetrov

set

nosy: + rpetrov

2014-07-10 12:51:18

vstinner

set

nosy: + serhiy.storchaka
messages: +

2014-07-10 12:32:56

BreamoreBoy

set

nosy: + BreamoreBoy

messages: +
versions: + Python 3.5, - Python 3.4

2013-10-10 21:14:49

piotr.dobrogost

set

messages: +

2013-08-13 21:29:09

piotr.dobrogost

set

nosy: + piotr.dobrogost

2013-01-16 19:04:21

gvanrossum

set

nosy: + gvanrossum
messages: +

2013-01-15 19:31:13

pitrou

set

messages: +

2013-01-15 12:34:12

sbt

set

files: - winfileio.patch

2013-01-15 12:34:01

sbt

set

files: + winfileio.patch

messages: +

2013-01-14 20:17:11

sbt

set

messages: +

2013-01-14 19:55:51

sbt

set

messages: +

2013-01-14 14:42:27

pitrou

set

messages: +

2013-01-14 14:36:10

amaury.forgeotdarc

set

messages: +

2013-01-12 15:19:58

sbt

set

messages: +

2013-01-12 15:13:59

sbt

set

files: - winfileio.patch

2013-01-12 15:13:50

sbt

set

files: - test_winfileio.py

2013-01-12 15:13:44

sbt

set

files: - winfileio.c

2013-01-12 15:13:31

sbt

set

files: + winfileio.patch

messages: +

2013-01-07 16:01:55

vstinner

set

messages: +

2013-01-06 21:43:02

sbt

set

messages: +

2013-01-06 21:30:46

vstinner

set

messages: +

2013-01-06 13:59:18

sbt

set

files: + winfileio.patch
keywords: + patch
messages: +

2013-01-03 17:36:21

sbt

set

files: + test_winfileio.py

2013-01-03 17:36:03

sbt

set

files: + winfileio.c

messages: +

2013-01-03 13:11:57

sbt

set

messages: +

2013-01-03 09:54:20

serhiy.storchaka

set

versions: + Python 3.4, - Python 3.3
nosy: + ezio.melotti

components: + Windows
type: enhancement
stage: needs patch

2013-01-03 08:13:37

socketpair

set

messages: +

2013-01-03 07:50:32

pitrou

set

nosy: + sbt

2013-01-03 02:12:33

vstinner

set

messages: +

2011-11-02 12:54:22

vstinner

set

messages: +

2011-11-01 17:11:09

pitrou

set

messages: +

2011-11-01 17:02:44

socketpair

set

messages: +

2011-11-01 16:56:43

socketpair

set

messages: +

2011-11-01 16:49:26

amaury.forgeotdarc

set

messages: +

2011-11-01 16:33:08

pitrou

set

messages: +

2011-11-01 16:25:59

socketpair

set

messages: +

2011-11-01 12:12:35

pitrou

set

nosy: + pitrou
messages: +

2011-09-12 18:38:21

santoso.wijaya

set

nosy: + santoso.wijaya

2011-09-08 23:21:22

vstinner

set

messages: +

2011-09-08 23:19:00

vstinner

create