Skip to content

Commit

Permalink
Move inner part of compare_trees() to compare_files()
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-berchet committed Jul 28, 2021
1 parent d639412 commit 3f45f4e
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 39 deletions.
89 changes: 65 additions & 24 deletions dir_content_diff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,59 @@ def unregister_comparator(ext, quiet=False):
return _COMPARATORS.pop(ext, None)


def compare_files(ref_file, comp_file, comparator, specific_args=None):
"""Compare 2 files and return the difference.
Args:
ref_file (str): Path to the reference file.
comp_file (str): Path to the compared file.
comparator (callable): The comparator to use.
specific_args (dict): A dict with the args/kwargs that should be given to the comparator.
This dict should be like the following:
.. code-block:: Python
{
args: [arg1, arg2, ...],
kwargs: {
kwarg_name_1: kwarg_value_1,
kwarg_name_2: kwarg_value_2,
}
}
Returns:
bool or str: True if the files are equal or a string with a message explaining the
differences if they are different.
"""
# Get the compared file
L.debug("Compare: %s and %s", ref_file, comp_file)

# Get specific args and kwargs
if specific_args is None:
specific_args = {}
args = specific_args.get("args", [])
kwargs = specific_args.get("kwargs", {})

if comparator is not None:
# If the suffix has an associated comparator, use this comparator
try:
return comparator(ref_file, comp_file, *args, **kwargs)
except Exception as exception: # pylint: disable=broad-except
return diff_msg_formatter(
ref_file,
comp_file,
reason="\n".join(exception.args),
args=args,
kwargs=kwargs,
)
else:
# If no comparator is known for this suffix, test with standard filecmp library
if not filecmp.cmp(ref_file, comp_file):
msg = diff_msg_formatter(ref_file, comp_file)
return msg
return True


def compare_trees(ref_path, comp_path, comparators=None, specific_args=None):
"""Compare all files from 2 different directory trees and return the differences.
Expand All @@ -85,7 +138,7 @@ def compare_trees(ref_path, comp_path, comparators=None, specific_args=None):
Args:
ref_path (str): Path to the reference directory.
comp_path (str): Path to the directory that must be compared against the reference.
comparator (dict): A dict to override the registered comparators.
comparators (dict): A dict to override the registered comparators.
specific_args (dict): A dict with the args/kwargs that should be given to the comparator
for a given file. This dict should be like the following:
Expand Down Expand Up @@ -121,31 +174,19 @@ def compare_trees(ref_path, comp_path, comparators=None, specific_args=None):
for ref_file in ref_path.glob("**/*"):
if ref_file.is_dir():
continue
suffix = ref_file.suffix

relative_path = ref_file.relative_to(ref_path).as_posix()
comp_file = comp_path / relative_path
L.debug("Compare: %s and %s", ref_file, comp_file)

if comp_file.exists():
args = specific_args.get(relative_path, {}).get("args", [])
kwargs = specific_args.get(relative_path, {}).get("kwargs", {})
if suffix in comparators:
try:
res = comparators[suffix](ref_file, comp_file, *args, **kwargs)
if res is not True:
different_files[relative_path] = res
except Exception as exception: # pylint: disable=broad-except
different_files[relative_path] = diff_msg_formatter(
ref_file,
comp_file,
reason="\n".join(exception.args),
args=args,
kwargs=kwargs,
)
else:
# If no comparator is given for this suffix, test with standard filecmp library
if not filecmp.cmp(ref_file, comp_file):
msg = diff_msg_formatter(ref_file, comp_file)
different_files[relative_path] = msg
res = compare_files(
ref_file,
comp_file,
comparator=comparators.get(ref_file.suffix),
specific_args=specific_args.get(relative_path),
)
if res is not True:
different_files[relative_path] = res
else:
msg = f"The file '{relative_path}' does not exist in '{comp_path}'."
different_files[relative_path] = msg
Expand All @@ -154,7 +195,7 @@ def compare_trees(ref_path, comp_path, comparators=None, specific_args=None):


def assert_equal_trees(*args, **kwargs):
"""Raises an :class:`AssertionError` if differences are found in the two directory trees.
"""Raise an :class:`AssertionError` if differences are found in the two directory trees.
See the :func:`compare_trees` function for details on arguments as this function just calls it.
"""
Expand Down
17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,20 @@ max-attributes=40
min-public-methods=0
# Maximum number of public methods for a class (see R0904).
max-public-methods=60

# PYDOCSTYLE
[tool.pydocstyle]
# ignore the following:
# - D105: Missing docstring in magic method
# - D107: Missing docstring in __init__
add-ignore = [
"D105",
"D107",
]
convention = "google"

# ISORT
[tool.isort]
line_length = 100
profile = "black"
force_single_line = true
19 changes: 4 additions & 15 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ deps =
commands =
pycodestyle {[base]files}
pydocstyle {[base]files}
isort --check-only --sl --diff {[base]files}
isort --check-only --diff {[base]files}
black --check {[base]files}
pylint {[base]files}
pylint -j 0 {[base]files}

[testenv:format]
basepython = python3.6
Expand All @@ -78,7 +78,7 @@ deps =
isort

commands =
isort --sl {[base]files}
isort {[base]files}
black {[base]files}

[testenv:docs]
Expand All @@ -89,19 +89,8 @@ allowlist_externals =
# set warnings as errors using the -W sphinx option
commands = make html SPHINXOPTS=-W

[pycodestyle]
# W503: line break after binary operator
# W504: line break before binary operator
[pycodestyle]
ignore = W503,W504,E203
max-line-length = 100

[pydocstyle]
# ignore the following
# - D105: Missing docstring in magic method
# - D107: Missing docstring in __init__
add-ignore = D105, D107
convention = google

[isort]
line_length=100
profile=black

0 comments on commit 3f45f4e

Please sign in to comment.