From what I observe filecmp.dircmp
is recursive, but inadequate for my needs, at least in py2. I want to compare two directories and all their contained files. Does this exist, or do I need to build (using os.walk
, for example). I prefer pre-built, where someone else has already done the unit-testing :)
The actual 'comparison' can be sloppy (ignore permissions, for example), if that helps.
I would like something boolean, and report_full_closure
is a printed report. It also only goes down common subdirs. AFIAC, if they have anything in the left or right dir only those are different dirs. I build this using os.walk
instead.
Here's an alternative implementation of the comparison function with filecmp
module. It uses a recursion instead of os.walk
, so it is a little simpler. However, it does not recurse simply by using common_dirs
and subdirs
attributes since in that case we would be implicitly using the default "shallow" implementation of files comparison, which is probably not what you want. In the implementation below, when comparing files with the same name, we're always comparing only their contents.
import filecmp
import os.pathdef are_dir_trees_equal(dir1, dir2):"""Compare two directories recursively. Files in each directory areassumed to be equal if their names and contents are equal.@param dir1: First directory path@param dir2: Second directory path@return: True if the directory trees are the same and there were no errors while accessing the directories or files, False otherwise."""dirs_cmp = filecmp.dircmp(dir1, dir2)if len(dirs_cmp.left_only)>0 or len(dirs_cmp.right_only)>0 or \len(dirs_cmp.funny_files)>0:return False(_, mismatch, errors) = filecmp.cmpfiles(dir1, dir2, dirs_cmp.common_files, shallow=False)if len(mismatch)>0 or len(errors)>0:return Falsefor common_dir in dirs_cmp.common_dirs:new_dir1 = os.path.join(dir1, common_dir)new_dir2 = os.path.join(dir2, common_dir)if not are_dir_trees_equal(new_dir1, new_dir2):return Falsereturn True