From c8a65b085c10a17113bbd6c2b7121673f598b6f1 Mon Sep 17 00:00:00 2001 From: fan wu <336798967+FanWu-ai@users.noreply.github.com> Date: Sat, 3 Oct 2026 02:03:57 -0700 Subject: [PATCH] Fix DeepSearch reporting of excluded dictionary and attribute paths --- deepdiff/search.py | 2 ++ tests/test_search.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/deepdiff/search.py b/deepdiff/search.py index 9b1b11a1..87f78eb0 100644 --- a/deepdiff/search.py +++ b/deepdiff/search.py @@ -236,6 +236,8 @@ def __search_dict(self, parents_ids_added = add_to_frozen_set(parents_ids, item_id) new_parent = parent_text % (parent, item_key_str) + if self.__skip_this(obj_child, new_parent): + continue new_parent_cased = new_parent if self.case_sensitive else new_parent.lower() str_item = str(item) diff --git a/tests/test_search.py b/tests/test_search.py index 3984349a..487689e7 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -254,6 +254,37 @@ def test_skip_dictionary_path(self): result = {} assert ds == result + @pytest.mark.parametrize('verbose_level', [1, 2]) + @pytest.mark.parametrize('exclude', [ + {'exclude_paths': ["root['container']['needle']"]}, + {'exclude_paths': ["root[*]['needle']"]}, + {'exclude_regex_paths': [r"\['needle'\]$"]}, + ]) + def test_excluded_dictionary_key_is_not_reported(self, verbose_level, exclude): + obj = {'container': {'needle': {'nested': 'needle'}}, 'keep': 'needle'} + expected = {'matched_values': ( + {"root['keep']": 'needle'} if verbose_level == 2 else {"root['keep']"} + )} + + assert DeepSearch(obj, 'needle', verbose_level=verbose_level, **exclude) == expected + + @pytest.mark.parametrize('verbose_level', [1, 2]) + def test_excluded_attribute_name_is_not_reported(self, verbose_level): + obj = CustomClass('a', 'a') + expected = {'matched_values': ( + {'root.b': 'a'} if verbose_level == 2 else {'root.b'} + )} + + assert DeepSearch(obj, 'a', exclude_paths=['root.a'], verbose_level=verbose_level) == expected + + @pytest.mark.parametrize('verbose_level', [1, 2]) + def test_excluded_dictionary_value_type_does_not_report_key(self, verbose_level): + obj = {'needle': 1, 'needle_keep': 'needle'} + matches = {"root['needle_keep']": 'needle'} if verbose_level == 2 else {"root['needle_keep']"} + expected = {'matched_paths': matches, 'matched_values': matches} + + assert DeepSearch(obj, 'needle', exclude_types=[int], verbose_level=verbose_level) == expected + def test_skip_type_str(self): obj = "long string somewhere" result = {}