Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion send2trash/plat_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def send2trash(paths):
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"~"))
trash_dev = get_dev(op.realpath(op.expanduser(b"~")))

# if the file to be trashed is on the same device as HOMETRASH we
# want to move it there.
Expand Down
50 changes: 50 additions & 0 deletions tests/test_plat_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,56 @@ def test_trash(test_file):
assert op.exists(test_file) is False


@pytest.mark.parametrize("symlink_source", [False, True])
def test_trash_with_symlink_home(tmp_path, monkeypatch, symlink_source):
home = tmp_path / "real_home"
home.mkdir()
home_link = tmp_path / "home"
home_link.symlink_to(home, target_is_directory=True)
data_home = home_link / ".local" / "share"
trash = data_home / "Trash"
source = home_link / "file.txt"
target = home / "target.txt"
if symlink_source:
target.write_text("keep the target")
source.symlink_to(target)
else:
source.write_text("trash this file")

backend = send2trash.plat_other
original_expanduser = op.expanduser
original_get_dev = backend.get_dev

def expanduser(path):
return os.fsencode(home_link) if path == b"~" else original_expanduser(path)

def get_dev(path):
# Model a home symlink located on a different device from its target.
if os.fsencode(path) == os.fsencode(home_link):
return "symlink device"
return original_get_dev(path)

def unexpected_external_trash(path):
pytest.fail("a file on the home device should use the home trash")

monkeypatch.setattr(op, "expanduser", expanduser)
monkeypatch.setattr(backend, "get_dev", get_dev)
monkeypatch.setattr(backend, "XDG_DATA_HOME", os.fsencode(data_home))
monkeypatch.setattr(backend, "HOMETRASH_B", os.fsencode(trash))
monkeypatch.setattr(backend, "find_ext_volume_trash", unexpected_external_trash)

s2t(source)

assert not source.exists()
assert (trash / "info" / "file.txt.trashinfo").is_file()
trashed = trash / "files" / "file.txt"
if symlink_source:
assert trashed.is_symlink()
assert target.read_text() == "keep the target"
else:
assert trashed.read_text() == "trash this file"


def test_multitrash(test_files):
file_names = [file.name for file in test_files]
s2t(file_names)
Expand Down