New submission from Luca Paganin <lucap...@gmail.com>:

Suppose you have two pathlib objects representing source and destination of a 
move:

src=pathlib.Path("foo/bar/barbar/myfile.txt")
dst=pathlib.Path("foodst/bardst/")

If you try to do the following

shutil.move(src, dst)

Then an AttributeError will be raised, saying that PosixPath objects do not 
have an rstrip attribute. The error is the following:

Traceback (most recent call last):
  File "mover.py", line 10, in <module>
    shutil.move(src, dst)
  File "/Users/lucapaganin/opt/anaconda3/lib/python3.7/shutil.py", line 562, in 
move
    real_dst = os.path.join(dst, _basename(src))
  File "/Users/lucapaganin/opt/anaconda3/lib/python3.7/shutil.py", line 526, in 
_basename
    return os.path.basename(path.rstrip(sep))
AttributeError: 'PosixPath' object has no attribute 'rstrip'

Looking into shutil code, line 526, I see that the problem happens when you try 
to strip the trailing slash using rstrip, which is a method for strings, while 
PosixPath objects do not have it. Moreover, pathlib.Path objects already manage 
for trailing slashes, correctly getting basenames even when these are present.
The following two workarounds work:

1) Explicit cast both src and dst as string using

shutil.move(str(src), str(dst))

This work for both the cases in which dst contains the destination filename or 
not.

2) Add the filename to the end of the PosixPath dst object:

dst=pathlib.Path("foodst/bardst/myfile.txt")

Then do 

shutil.move(src, dst)

Surely one could use the method pathlib.Path.replace for PosixPath objects, 
which does the job without problems, even if it requires for dst to contain the 
destination filename at the end, and lacks generality, since it bugs when one 
tries to move files between different filesystems. 
I think that you should account for the possibility for shutil.move to manage 
pathlib.Path objects even if one does not provide the destination filename, 
since the source of the bug is due to a safety measure which is not necessary 
for pathlib.Path objects, i.e. the managing of the trailing slash.
Do you think that is possible? Thank you in advance.

Luca Paganin

P.S.: I attach a tarball with the dirtree I used for the demonstration.

----------
files: mover.tgz
messages: 358891
nosy: Luca Paganin
priority: normal
severity: normal
status: open
title: shutil.move does not work properly with pathlib.Path objects
type: behavior
versions: Python 3.7
Added file: https://bugs.python.org/file48803/mover.tgz

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39140>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to