I have a script that creates symlinks from files to a directory. After some time, following a migration to another system, I realized dangling links were silently created.
To illustrate, the following code will run without exception on Python 3.8, 3.10:
>>> from pathlib import Path >>> src_filepath = Path("/no/such/file.py") >>> dest_filepath = Path("any_name_is_ok.py") >>> dest_filepath.symlink_to(src_filepath)
The result is a symlink that points to a non-existing target
λ ls -al any_names_ok.py lrwxrwxrwx 1 root root 16 Sep 3 09:26 any_name_is_ok.py -> /no/such/file.py
I would expect an immediate exception to prevent the link from being created altogether.
Thankfully, we can assert that symbolic links are made from existing paths:
>>> src_filepath = Path("/no/such/file.py") >>> dest_filepath = Path("any_names_ok.py") >>> assert src_filepath.exists(), "No file found." >>> dest_filepath.symlink_to(src_filepath) AssertionError: No file found.
Can this be simplified?
We could mitigate creation of dangling links through adding an explicit
strict=True parameter to
Path.symlink_to(...). If the source file/directory does not exist, throw a
FileNotFound error. Example:
# Pseudo-code >>> src_filepath = Path("/dotfiles/bashrc").expanduser() # missing ~ >>> dest_filepath = Path("~/.bashrc").expanduser() >>> dest_filepath.symlink_to(src_filepath, strict=True) FileNotFoundError: '/dotfiles/bashrc' does not exist. A dangling link was prevented.
If the traditional behavior is desired, the default parameter can be set