This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Support moving across filesystems in pathlib.Path, as shutil.move() does
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Laurent.Mazuel, brett.cannon, eric.smith, eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2017-03-13 21:03 by Laurent.Mazuel, last changed 2022-04-11 14:58 by admin.

Messages (6)
msg289549 - (view) Author: Laurent Mazuel (Laurent.Mazuel) Date: 2017-03-13 21:03
Trying to use Pathlib and Path.replace on Windows if drive are different leads to an issue:

  File "D:\myscript.py", line 184, in update
    client_generated_path.replace(destination_folder)
  File "c:\program files (x86)\python35-32\Lib\pathlib.py", line 1273, in replace
    self._accessor.replace(self, target)
  File "c:\program files (x86)\python35-32\Lib\pathlib.py", line 377, in wrapped
    return strfunc(str(pathobjA), str(pathobjB), *args)
OSError: [WinError 17] The system cannot move the file to a different disk drive: 'C:\\MyFolder' -> 'D:\\MyFolderNewName'

This is a known situation of os.rename, and workaround I found is to use shutil or to copy/delete manually in two steps (e.g. http://stackoverflow.com/questions/21116510/python-oserror-winerror-17-the-system-cannot-move-the-file-to-a-different-d)

When using Pathlib, it's not that easy to workaround using shutil (even if thanks to Brett Cannon now shutil accepts Path in Py3.6, not everybody has Py3.6). At least this should be documented with a recommendation for that situation. I love Pathlib and it's too bad my code becomes complicated when it was so simple :(
msg289552 - (view) Author: Laurent Mazuel (Laurent.Mazuel) Date: 2017-03-13 21:25
Just to confirm, I was able to workaround it with Py3.6:

    # client_generated_path.replace(destination_folder)
    shutil.move(client_generated_path, destination_folder)

It is reasonable to think about adding a similar feature to pathlib if it doesn't support it and just special-case the drive-to-drive scenario for Windows
msg289559 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2017-03-14 02:11
Moving a file across volumes isn't atomic. Getting an exception in this case can be useful. There could be a "strict" keyword-only parameter that defaults to False. If it's true, then replace() won't try to move the file.
msg289630 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-03-15 00:36
I agree this needs to be different from replace(), due to not being atomic. That makes it an enhancement, so I'm removing 3.5.

I'm +1 on Path supporting something like shutil.move().
msg289687 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2017-03-15 19:02
I also support the idea of getting something like shutil.move() into pathlib.
msg289688 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2017-03-15 19:05
I should also mention that rename() (https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename) and replace() (https://docs.python.org/3/library/pathlib.html#pathlib.Path.replace) already do exist, so it might be best to add a keyword-only flag to one of those for this use-case.
History
Date User Action Args
2022-04-11 14:58:44adminsetgithub: 73991
2021-03-15 21:26:30eryksunsettitle: Pathlib.replace cannot move file to a different drive on Windows if filename different -> Support moving across filesystems in pathlib.Path, as shutil.move() does
components: - Windows
versions: + Python 3.8, Python 3.9, Python 3.10, - Python 3.6
2017-03-15 19:05:42brett.cannonsetmessages: + msg289688
2017-03-15 19:02:01brett.cannonsetmessages: + msg289687
2017-03-15 00:36:50eric.smithsetversions: - Python 3.5
nosy: + eric.smith

messages: + msg289630

type: enhancement
2017-03-14 02:11:17eryksunsetnosy: + eryksun
messages: + msg289559
2017-03-13 21:25:27Laurent.Mazuelsetmessages: + msg289552
2017-03-13 21:04:51brett.cannonsetnosy: + brett.cannon
2017-03-13 21:04:45brett.cannonsetcomponents: + Library (Lib), - IO
2017-03-13 21:03:44Laurent.Mazuelcreate