classification
Title: Docs: the difference between Path.rename() and Path.replace() is not obvious
Type: behavior Stage:
Components: Documentation, Library (Lib) Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: asvetlov, docs@python, eryksun, ezio.melotti, pitrou, r.david.murray
Priority: low Keywords: easy

Created on 2016-08-28 19:07 by asvetlov, last changed 2021-03-13 00:14 by eryksun.

Messages (5)
msg273836 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2016-08-28 19:07
Hi.

On reading the doc for pathlib I've stuck with `.rename()` and `.replace()` (https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename).

What's the difference?

Going to pathlib's source code I've figured out that methods are use different functions from `os` module: `os.rename()` and `os.replace()`.

But the documentation for `os` module is not obvious too: 
the docs for both functions are almost equal from my perspective, the only significant difference is that `os.rename()` suggests to use `os.replace()` for cross-compatibility.

Could anybody explain the difference?

Also, at least the doc for `pathlib.Path.rename` worth to have a sentence like borrowed from `os.rename`: "If you want cross-platform overwriting of the destination, use replace()."
msg273839 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-08-28 19:38
The existing docs are pretty clear on the difference: rename is only guaranteed to replace an existing file on unix (which I think means posix in this context), whereas replace always replaces the file, regardless of platform.

I'm actually surprised that rename is even part of the pathlib API, since its cross platform behavior is not consistent.  It also seems as though the replace docs are incorrect, since they imply directories are replaced, but the os docs say they are not.

The "this is a posix requirement" note in os.replace also seems imprecise.  Windows is not posix, so that note leaves me wondering if replace is atomic on Windows or not.  That should be clarified one way or another.

I think adding the cross platform note in the pathlib docs is reasonable, since it addresses the question of why there are two similar functions.
msg273840 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2016-08-28 20:03
Just keeping the reference to `os.rename()`: https://docs.python.org/3/library/os.html#os.rename

Aha, `os.rename` says: "On Unix, if dst exists and is a file, it will be replaced silently if the user has permission." and "On Windows, if dst already exists, OSError will be raised even if it is a file."

Sorry, I've missed this.

Maybe it worth to add `.. warning:` section for both `os.rename` and `pathlib.Path.rename`?
msg273841 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-08-28 20:05
No, we don't like to overuse warnings.
msg388570 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-03-13 00:14
The pathlib documentation of Path.rename() says "[o]n Unix, if target exists and is a file, it will be replaced silently if the user has permission". This leaves the behavior on Windows in question. The reader has to scroll down to the correspondence table to link to the documentation of os.rename() and presume that Path.rename() also raises FileExistsError for this case. The Path.rename() docs should just state upfront that "[o]n Windows, if target exists, FileExistsError will be raised".
History
Date User Action Args
2021-03-13 00:14:05eryksunsettitle: Docs: the difference between rename and replace is not obvious -> Docs: the difference between Path.rename() and Path.replace() is not obvious
messages: + msg388570
components: + Library (Lib)
versions: + Python 3.8, Python 3.9, Python 3.10, - Python 3.5, Python 3.6
2021-03-12 23:55:59eryksunsetmessages: - msg273845
2020-10-28 19:56:12ezio.melottisetnosy: + ezio.melotti
2016-08-28 22:56:53eryksunsetnosy: + eryksun
messages: + msg273845
2016-08-28 20:05:48r.david.murraysetmessages: + msg273841
2016-08-28 20:03:34asvetlovsetmessages: + msg273840
2016-08-28 19:38:47r.david.murraysetversions: - Python 3.4
2016-08-28 19:38:35r.david.murraysetnosy: + r.david.murray
messages: + msg273839
2016-08-28 19:07:12asvetlovcreate