OS: Ubuntu 22.04
Python: 3.13
send2trash: 1.8.3
When I try to send a file in my home directory to trash, send2trash does not find the trash directory in my home in /home/username/.local/share/Trash and tries to fall back to a device specific trash. My home directory /home/username is a symlink pointing to /home/ad/lxhome/x/username/Linux for enterprise reasons. The link is on a different filesystem device than my home directory.
Why this happens:
|
# Pull this out so it's easy to stub (to avoid stubbing lstat itself) |
|
def get_dev(path): |
|
return os.lstat(path).st_dev |
|
|
|
|
|
def send2trash(paths): |
|
paths = preprocess_paths(paths) |
|
for path in paths: |
|
if isinstance(path, text_type): |
|
path_b = fsencode(path) |
|
elif isinstance(path, bytes): |
|
path_b = path |
|
else: |
|
raise TypeError("str, bytes or PathLike expected, not %r" % type(path)) |
|
|
|
if not op.exists(path_b): |
|
raise OSError(errno.ENOENT, "File not found: %s" % path) |
|
# ...should check whether the user has the necessary permissions to delete |
|
# it, before starting the trashing operation itself. [2] |
|
if not os.access(path_b, os.W_OK): |
|
raise OSError(errno.EACCES, "Permission denied: %s" % path) |
|
|
|
path_dev = get_dev(path_b) |
|
# If XDG_DATA_HOME or HOMETRASH do not yet exist we need to stat the |
|
# home directory, and these paths will be created further on if needed. |
|
trash_dev = get_dev(op.expanduser(b"~")) |
|
|
|
# if the file to be trashed is on the same device as HOMETRASH we |
|
# want to move it there. |
|
if path_dev == trash_dev: |
|
topdir = XDG_DATA_HOME |
|
dest_trash = HOMETRASH_B |
|
else: |
|
topdir = find_mount_point(path_b) |
|
trash_dev = get_dev(topdir) |
|
if trash_dev != path_dev: |
|
raise OSError("Couldn't find mount point for %s" % path) |
|
dest_trash = find_ext_volume_trash(topdir) |
|
try: |
|
trash_move(path_b, dest_trash, topdir) |
|
except OSError as error: |
|
# Cross link errors default back to HOMETRASH |
|
if error.errno == errno.EXDEV: |
|
trash_move(path_b, HOMETRASH_B, XDG_DATA_HOME, cross_dev=True) |
|
else: |
|
raise |
Here on line 198 the code tries to determine if my home is on the same device as the file to be trashed. It expands ~ to /home/username and calls get_dev() on it. On line 175 it calls os.lstat().st_dev to find the device. lstat does not follow the symlink /home/username but returns the device where the link itself is located and incorrectly determines that my home is on a different device.
How to fix:
Use os.stat() instead to determine the device of the home directory, as it follows any symbolic links it encounters. Another option would be to find the device of ~/. instead of ~.
OS: Ubuntu 22.04
Python: 3.13
send2trash: 1.8.3
When I try to send a file in my home directory to trash, send2trash does not find the trash directory in my home in
/home/username/.local/share/Trashand tries to fall back to a device specific trash. My home directory/home/usernameis a symlink pointing to/home/ad/lxhome/x/username/Linuxfor enterprise reasons. The link is on a different filesystem device than my home directory.Why this happens:
send2trash/send2trash/plat_other.py
Lines 173 to 218 in 91d0698
Here on line 198 the code tries to determine if my home is on the same device as the file to be trashed. It expands
~to/home/usernameand callsget_dev()on it. On line 175 it callsos.lstat().st_devto find the device.lstatdoes not follow the symlink/home/usernamebut returns the device where the link itself is located and incorrectly determines that my home is on a different device.How to fix:
Use
os.stat()instead to determine the device of the home directory, as it follows any symbolic links it encounters. Another option would be to find the device of~/.instead of~.