fix: count exclude_regex_paths towards threshold_to_diff_deeper

The shortcut in _diff_dict that reports a whole dictionary as a single
values_changed entry compensates its key count for exclude_paths and
exclude_glob_paths, but never for exclude_regex_paths.

Regex-excluded keys are not removed from the key sets beforehand either,
since _skip_this_key only filters on include_paths and include_glob_paths.
They therefore inflate the key union, drag the ratio of shared keys under
the threshold and trigger the shortcut, so the exclusion is silently
ignored and the excluded keys leak into old_value and new_value.

Filter the key union by exclude_regex_paths as well, mirroring the
exclude_glob_paths branch and using search() to match how _skip_this
applies the same patterns.

Fixes #487
This commit is contained in:
dualfroz committed 2026-09-03 14:06:34 +02:00
1 parent aa2b15b1b3
commit 4179793c2b
2 files changed
+29 -1

No files matched your search

+4 -1
View File
@@ -753,13 +753,16 @@ class DeepDiff(ResultDict, SerializationMixin, DistanceMixin, DeepDiffProtocol,
t_keys_removed = t1_keys - t_keys_intersect
if self.threshold_to_diff_deeper:
if self.exclude_paths or self.exclude_glob_paths:
if self.exclude_paths or self.exclude_glob_paths or self.exclude_regex_paths:
t_keys_union = {f"{level.path()}[{repr(key)}]" for key in (t2_keys | t1_keys)}
if self.exclude_paths:
t_keys_union -= self.exclude_paths
if self.exclude_glob_paths:
t_keys_union = {k for k in t_keys_union
if not any(gp.match(k) for gp in self.exclude_glob_paths)}
if self.exclude_regex_paths:
t_keys_union = {k for k in t_keys_union
if not any(rp.search(k) for rp in self.exclude_regex_paths)}
t_keys_union_len = len(t_keys_union)
else:
t_keys_union_len = len(t2_keys | t1_keys)