Repository navigation
Pathlib.rename isn't robust #90475
Description
Activity
Pathlib.rename will fail across file system with:
OSError: [Errno 18] Invalid cross-device link
e.g:
-> path_dict["current_path"].rename(path_dict["destination"])
(Pdb) n
OSError: [Errno 18] Invalid cross-device link: '/tmp/pipenv-k1m0oynt-yaml/PyYAML-6.0/lib/yaml' -> '/home/oz123/Software/pipenv/pipenv/patched/yaml3'This is because it uses os.rename under the hood:
https://github.com/python/cpython/blob/3.10/Lib/pathlib.py#L306One can either replace it with
shutil.movewhich works, or one could
add another method to Pathlib.move(...) with similar signature and return value, which callsshutil.moveunder the hood.Before submitting a patch for that, I would like to get feedback for that.
- added3.9 (EOL)end of lifeend of life3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Jan 9, 2022 Sounds good. Would you expose the
copy_functionargument in pathlib, or do something else (likemetadata=True)?@Barney, I am not sure that I understand your question.
I think adding another method
Pathlib.PathandPathlib._Accessoris my preferred way. The would be something like:class _NormalAccessor(_Accessor): ... self.move = shutil.move class Path: .... def move(self, src, dest): self._accessor.move(self, target) return self.__class__(target)
Now, this is hardly a patch. I need to submit a PR with proper docs, tests and NEWS entry... I will be glad to work on it. However, I guess I need someone to "sponsor" it and merge it.
shutil.move() accepts a
copy_functionargument:shutil.move(src, dst, copy_function=copy2)
It's possible to set
copy_function=copyto skip copying file metadata.Thanks for the answer, it makes sense now. Yes, I would adopt this.
Allowing users to usecopy2(or any other functio ...) using a keyword.Fair enough. Users who wanted to avoid copying file metadata would then do something like this, I suppose?
import pathlib import shutil path = pathlib.Path('foo') path.move('bar', copy_function=shutil.copy)
I guess the downside here is that users would still need to
import shutilto do this. But I see the utility of allowing any copy_function to be supplied!
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields: