From 975db98ec4ba932d1e475fd06423bfc15eeff003 Mon Sep 17 00:00:00 2001 From: mskhviyu Date: Wed, 25 May 2022 00:38:00 +0300 Subject: [PATCH] Add exclude_obj_callback_strict parameter for deepdiff --- deepdiff/diff.py | 7 +++++++ docs/ignore_types_or_values.rst | 12 ++++++++++++ tests/test_diff_text.py | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/deepdiff/diff.py b/deepdiff/diff.py index 5572c103..5cbd0b1e 100755 --- a/deepdiff/diff.py +++ b/deepdiff/diff.py @@ -94,6 +94,7 @@ def _report_progress(_stats, progress_logger, duration): 'ignore_type_subclasses', 'ignore_string_case', 'exclude_obj_callback', + 'exclude_obj_callback_strict', 'ignore_private_variables', 'encodings', 'ignore_encoding_errors', @@ -116,6 +117,7 @@ def __init__(self, cutoff_intersection_for_pairs=CUTOFF_INTERSECTION_FOR_PAIRS_DEFAULT, encodings=None, exclude_obj_callback=None, + exclude_obj_callback_strict=None, exclude_paths=None, exclude_regex_paths=None, exclude_types=None, @@ -194,6 +196,7 @@ def __init__(self, self.type_check_func = type_is_subclass_of_type_group if ignore_type_subclasses else type_in_type_group self.ignore_string_case = ignore_string_case self.exclude_obj_callback = exclude_obj_callback + self.exclude_obj_callback_strict = exclude_obj_callback_strict self.number_to_string = number_to_string_func or number_to_string self.iterable_compare_func = iterable_compare_func self.ignore_private_variables = ignore_private_variables @@ -429,6 +432,10 @@ def _skip_this(self, level): elif self.exclude_obj_callback and \ (self.exclude_obj_callback(level.t1, level.path()) or self.exclude_obj_callback(level.t2, level.path())): skip = True + elif self.exclude_obj_callback_strict and \ + (self.exclude_obj_callback_strict(level.t1, level.path()) and + self.exclude_obj_callback_strict(level.t2, level.path())): + skip = True return skip diff --git a/docs/ignore_types_or_values.rst b/docs/ignore_types_or_values.rst index 464b93ab..bd705107 100644 --- a/docs/ignore_types_or_values.rst +++ b/docs/ignore_types_or_values.rst @@ -272,6 +272,18 @@ exclude_obj_callback: function, default = None >>> DeepDiff(t1, t2, exclude_obj_callback=exclude_obj_callback) {} +exclude_obj_callback_strict: function, default = None + A function works the same way as exclude_obj_callback, but excludes elements from the result only if the function returns True for both elements + + >>> def exclude_obj_callback_strict(obj, path): + ... return True if isinstance(obj, int) and obj > 10 else False + ... + >>> t1 = {"x": 10, "y": "b", "z": "c"} + >>> t2 = {"x": 12, "y": "b", "z": "c"} + >>> DeepDiff(t1, t2, exclude_obj_callback=exclude_obj_callback_strict) + {} + >>> DeepDiff(t1, t2, exclude_obj_callback_strict=exclude_obj_callback_strict) + {'values_changed': {"root['x']": {'new_value': 12, 'old_value': 10}}} .. _truncate_datetime_label: diff --git a/tests/test_diff_text.py b/tests/test_diff_text.py index 2d28103b..03079d74 100755 --- a/tests/test_diff_text.py +++ b/tests/test_diff_text.py @@ -1394,6 +1394,16 @@ def exclude_obj_callback(obj, path): result = {} assert result == ddiff + def test_skip_exclude_obj_callback_strict(self): + def exclude_obj_callback_strict(obj, path): + return True if isinstance(obj, int) and obj > 10 else False + + t1 = {"x": 10, "y": "b", "z": "c"} + t2 = {"x": 12, "y": "b", "z": "c"} + ddiff = DeepDiff(t1, t2, exclude_obj_callback_strict=exclude_obj_callback_strict) + result = {'values_changed': {"root['x']": {'new_value': 12, 'old_value': 10}}} + assert result == ddiff + def test_skip_str_type_in_dictionary(self): t1 = {1: {2: "a"}} t2 = {1: {}}