Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected errors if symlink in path with no existing files #35

Open
chrisvanrun opened this issue Dec 12, 2024 · 1 comment
Open

Unexpected errors if symlink in path with no existing files #35

chrisvanrun opened this issue Dec 12, 2024 · 1 comment

Comments

@chrisvanrun
Copy link

chrisvanrun commented Dec 12, 2024

def clean_path(path: Path) -> None:
for f in path.glob("*"):
if f.is_symlink() or f.is_file():
f.chmod(0o700)
f.unlink()
elif f.is_dir():
f.chmod(0o700)
clean_path(f)
f.rmdir()

By default, the chmod follows symlinks. This goes wrong if the targetable symlink no longer exists.

@chrisvanrun
Copy link
Author

Suggested fix:

def clean_path(path: Path) -> None:
    for f in path.glob("*"):
        if f.chmod in os.supports_follow_symlinks:
            f.chmod(0o700, follow_symlinks=False)
        elif not f.is_symlink():
            # Linux does not support setting permissions on symlinks.
            # Permissions of symlinks are never used in that OS.
            f.chmod(0o700)

        if f.is_symlink() or f.is_file():
            f.unlink()
        elif f.is_dir():
            clean_path(f)
            f.rmdir()

Test:

def test_folder_cleanup_with_symlinks(tmp_path):
    # Create the target directory
    target = tmp_path / "test"
    target.mkdir(parents=True)

    # Create the directories for symlinks
    symlinked_dir = tmp_path / "non_target_dir"
    symlinked_dir.mkdir(parents=True)

    symlinked_file = tmp_path / "non_target_file"
    symlinked_file.touch()

    # Create symlinks in the target directory
    target_symlink_dir = target / "symlinked_dir"
    os.symlink(symlinked_dir, target_symlink_dir)

    target_symlink_file = target / "symlinked_file"
    os.symlink(symlinked_file, target_symlink_file)

    clean_path(path=target)

    # Ensure the symlinks got claned but the target still exists
    assert not target_symlink_dir.exists(), "Symlink to directory did not get cleaned!"
    assert not target_symlink_file.exists(), "Symlink to file did not get cleaned!"

    assert symlinked_dir.exists(), "Symlinked directory got cleaned!"
    assert symlinked_file.exists(), "Symlinked file got cleaned!"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant