Skip to content

Instantly share code, notes, and snippets.

@amorton
Created June 14, 2011 10:17
Show Gist options
  • Save amorton/1024636 to your computer and use it in GitHub Desktop.
Save amorton/1024636 to your computer and use it in GitHub Desktop.
Diff the files in a directory using Python
#used as part of a unit test
def _compare_directories(self, expected_dir, actual_dir, header=None):
"""Compares two directories and diffs any different files.
The file list of both directories must match and the files must match.
Sub directories are not considered as I don't need to in my case.
The diff will not show that a file was deleted from one side. It shows
that all the lines were removed.
:raises: AssertionError if there are differences. Error will
contain the diff as it's message.
:param expected_dir: directory of expected files
:param actual_dir: directory of actual files
:param header: Optional string header to prepend to the diff.
"""
if os.path.exists(expected_dir) and os.path.exists(actual_dir):
dir_diff = filecmp.dircmp(expected_dir, actual_dir)
diff_files = list(itertools.chain(dir_diff.diff_files,
dir_diff.left_only, dir_diff.right_only))
else:
try:
diff_files = os.listdir(actual_dir)
except (OSError):
diff_files = os.listdir(expected_dir)
if not diff_files:
return
sb = []
if header:
sb.append(header)
def safe_read_lines(path):
if not os.path.exists(path):
return []
f = open(path)
try:
return f.readlines()
finally:
f.close()
for diff_file in diff_files:
expected_file = os.path.join(expected_dir, diff_file)
actual_file = os.path.join(actual_dir, diff_file)
if os.path.isdir(expected_file) or os.path.isdir(actual_file):
raise RuntimeError("Unexpected sub dir")
diff = difflib.context_diff(
safe_read_lines(expected_file),
safe_read_lines(actual_file),
fromfile=expected_file,
tofile=actual_file)
sb.extend(diff)
self.fail(msg="".join(sb))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment