Add `strict` parameter to Path.symlink_to()

Problem

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.

Demo

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 /no/such/file.py.

λ 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.

Solution

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?

Proposal

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 strict=False.

See Also