-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
bpo-28356: Document os.rename() behavior on Windows for differing filesystems #27376
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
Doc/library/os.rst
Outdated
@@ -2292,6 +2292,8 @@ features: | |||
will fail with an :exc:`OSError` subclass in a number of cases: | |||
|
|||
On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. | |||
The operation will fail if *src* and *dst* are on different filesystems. Use |
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.
I'd say it "may" fail, and move this out of the "if dst exists" section (which is introduced in the preceding paragraph).
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.
Hi Zooba,
Thanks for the comment. The original (bpo-28356) talks about this, the main point of this documentation update is to alert users that it automatically will fail when moving across different disk drives (file systems).
This is something that is explained in errors in Python 3.8.10 but is missed in the documentation. See my terminal
As for the other point, I read it as being grouped together with Windows, as the next paragraph talks about Unix systems. I could rewrite the whole Windows paragraph, but I thought it better to tack it on to existing content.
I will leave it alone for now unless there is more discussion about this on either the bpo or in this thread.
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.
I am not a Windows dev, but @eryksun also said on the issue that it will always fail because of the specific Windows API call used in the implementation. On the other hand, perhaps we should say "may" so we can get away with changing the behavior in the future if we want.
As for the placement, the current docs (https://docs.python.org/3.10/library/os.html#os.rename) aren't very clear. The Unix paragraph has a bunch of other information beyond behavior if dst
already exists. I'd actually suggest removing the "If dst exists, the operation will fail with an OSError subclass in a number of cases:" sentence completely. That way, we just have one paragraph talking about Windows oddities and one talking about Unix oddities.
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.
The implementation of os.rename()
in Windows calls MoveFileExW()
without the flag MOVEFILE_COPY_ALLOWED
. The documentation states that "[i]f the destination is on another drive, you must [emphasis added] set the MOVEFILE_COPY_ALLOWED
flag in dwFlags
". This flag is not used by os.rename()
or os.replace()
because the destination is not supposed to be a copied file that has a new ID in the system.
POSIX rename()
allows a system to support links across file systems, but the inode number -- and presumably the (dev, ino)
tuple that uniquely identifies a file in the system -- must remain the same. I haven't seen this implemented. I've only ever seen rename fail with EXDEV
in this case.
That said, using "may fail" is fine. A new version of NTFS and the Windows I/O manager could implement a type of reparse point that uses the FILE_ID_INFO
, which in theory could be used to rename and hard link across two NTFS file systems.
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.
Yeah, there's a difference between "will always fail with the current implementation" and "will always fail for all time". This is the first case, but if we write it in the docs, we've made it the second case.
Better to leave ourselves open here, in case we (or Microsoft) decide to enable it later. Then we don't need to deprecate the function for two releases before changing it.
This PR is stale because it has been open for 30 days with no activity. |
@@ -0,0 +1 @@ | |||
The documentation about os.rename() used on Windows systems updated to reflect behavior about moving across filesystems. Patch by Ryan Ozawa |
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.
The documentation about os.rename() used on Windows systems updated to reflect behavior about moving across filesystems. Patch by Ryan Ozawa | |
Document the behavior of :func:`os.rename` when moving across filesystems on Windows. Patch by Ryan Ozawa. |
Shorter, and NEWS entries should be in the imperative
Doc/library/os.rst
Outdated
@@ -2292,6 +2292,8 @@ features: | |||
will fail with an :exc:`OSError` subclass in a number of cases: | |||
|
|||
On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. | |||
The operation will fail if *src* and *dst* are on different filesystems. Use |
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.
I am not a Windows dev, but @eryksun also said on the issue that it will always fail because of the specific Windows API call used in the implementation. On the other hand, perhaps we should say "may" so we can get away with changing the behavior in the future if we want.
As for the placement, the current docs (https://docs.python.org/3.10/library/os.html#os.rename) aren't very clear. The Unix paragraph has a bunch of other information beyond behavior if dst
already exists. I'd actually suggest removing the "If dst exists, the operation will fail with an OSError subclass in a number of cases:" sentence completely. That way, we just have one paragraph talking about Windows oddities and one talking about Unix oddities.
@rhyn0 Would you be interested in updating the PR per the reviews? |
This doesn't require a NEWS entry at all, it can be removed rather than updated. |
@@ -2292,6 +2292,8 @@ features: | |||
will fail with an :exc:`OSError` subclass in a number of cases: |
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.
I think it's better to keep this sentence since explicitly stating that all the related exceptions below are subclasses of OSError
could be helpful for easily catching the exceptions, but I can remove it nonetheless if wanted here.
@@ -2292,6 +2292,8 @@ features: | |||
will fail with an :exc:`OSError` subclass in a number of cases: | |||
|
|||
On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. | |||
The operation may fail if *src* and *dst* are on different filesystems. Use | |||
:func:`shutil.move` to support moves to a different filesystem. |
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.
I believe since this statement is Windows-specific, it's fine to keep it under the Windows section despite being slightly unrelated to the general case of dst existing. But let me know if it's preferred to open up a new paragraph above/below (or if removing the sentence on dst exists is preferred).
Thanks for all the changes! |
GH-100896 is a backport of this pull request to the 3.11 branch. |
GH-100897 is a backport of this pull request to the 3.10 branch. |
…umes (pythonGH-27376) (cherry picked from commit e098137) Co-authored-by: Ryan Ozawa <[email protected]>
…umes (pythonGH-27376) (cherry picked from commit e098137) Co-authored-by: Ryan Ozawa <[email protected]>
…umes (GH-27376) (cherry picked from commit e098137) Co-authored-by: Ryan Ozawa <[email protected]>
…umes (GH-27376) (cherry picked from commit e098137) Co-authored-by: Ryan Ozawa <[email protected]>
https://bugs.python.org/issue28356
https://bugs.python.org/issue28356