Broken Symbolic Links Cause FileNotFoundError
If a broken symbolic link exists only in one directory, diffoscope fails with a FileNotFoundError
.
Minimal Test Case for Reproduction
Start from any empty directory and run the following to generate the minimal test case:
mkdir my-dir-1 my-dir-2
(cd my-dir-1/ && ln -s /my-non-existent-absolute-path my-non-existent-absolute-path)
Now run diffoscope without any arguments, i.e. diffoscope my-dir-1/ my-dir-2/
. Also attempted with --exclude-directory-metadata yes
, appears to make no difference.
Observed Behavior
Diffoscope terminates with exit code 1 and displays the following stack trace:
Traceback (most recent call last):######################################| 100% ETA: 0:00:00
File "/usr/local/bin/diffoscope", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.8/dist-packages/diffoscope/main.py", line 746, in main
sys.exit(run_diffoscope(parsed_args))
File "/usr/local/lib/python3.8/dist-packages/diffoscope/main.py", line 700, in run_diffoscope
difference = compare_root_paths(path1, path2)
File "/usr/local/lib/python3.8/dist-packages/diffoscope/comparators/utils/compare.py", line 63, in compare_root_paths
return compare_directories(path1, path2)
File "/usr/local/lib/python3.8/dist-packages/diffoscope/comparators/directory.py", line 222, in compare_directories
return FilesystemDirectory(path1).compare(FilesystemDirectory(path2))
File "/usr/local/lib/python3.8/dist-packages/diffoscope/comparators/directory.py", line 285, in compare
differences.extend(my_container.compare(other_container))
File "/usr/local/lib/python3.8/dist-packages/diffoscope/comparators/utils/container.py", line 164, in comparisons
for my_name, other_name, score in self.perform_fuzzy_matching(
File "/usr/local/lib/python3.8/dist-packages/diffoscope/comparators/utils/fuzzy.py", line 45, in perform_fuzzy_matching
if file1.is_directory() or not file1.fuzzy_hash:
File "/usr/local/lib/python3.8/dist-packages/diffoscope/comparators/utils/file.py", line 342, in fuzzy_hash
if os.stat(self.path).st_size >= 512:
FileNotFoundError: [Errno 2] No such file or directory: 'my-dir-1/my-non-existent-absolute-path'
Expected Behavior
Diffoscope should terminate normally and show the missing (from the perspective of my-dir-2
) symbolic link in the file list
.
This suggestion is based on the following observation: If we add an identical broken symbolic link to the second directory, i.e. by running (cd my-dir-2/ && ln -s /my-non-existent-absolute-path my-non-existent-absolute-path)
, diffoscope will simply report the difference of the stat calls of the symbolic links. In other words, it does not attempt to deference the links and thus does not care that they are broken.
Environment and Versions
This error occurred for us with the latest diffoscope version (177
as of writing), running python 3.8.10
on Ubuntu 20.04