Overview
This PR contains a first pass at adding simple diff detection for precompiled regex. This fixes the bug referenced in #336. Questions/comments for @seperman in bold.
What this PR adds
deepdiff.DeepDiff now returns a diff if two re.Pattern objects consist of different patterns, flags, or groups.
>>> from deepdiff import DeepDiff
>>> from pprint import pp
>>> import re
>>> pattern_1 = re.compile('foo')
>>> pattern_2 = re.compile('foo')
>>> diff_12 = DeepDiff(pattern_1, pattern_2)
>>> pp(diff_12)
{}
>>> pattern_3 = re.compile('bar')
>>> diff_13 = DeepDiff(pattern_1, pattern_3)
>>> pp(diff_13)
{'values_changed': {'root': {'new_value': re.compile('bar'),
'old_value': re.compile('foo')}}}
>>> pattern_4 = re.compile('foo', flags=re.M)
>>> diff_14 = DeepDiff(pattern_1, pattern_4)
>>> pp(diff_14)
{'values_changed': {'root': {'new_value': re.compile('foo', re.MULTILINE),
'old_value': re.compile('foo')}}}
What this PR doesn't add
The diff doesn't provide any granular info on the specific difference(s), e.g., "the patterns + groups are the same and the flags are different".
I would like to implement this greater granularity, but perhaps you'd prefer to merge what this PR already does and just add that other stuff as a separate PR? Let me know.
Coverage report
---------- coverage: platform darwin, python 3.9.7-final-0 -----------
Name Stmts Miss Cover Missing
---------------------------------------------------------
deepdiff/anyset.py 47 0 100%
deepdiff/base.py 34 0 100%
deepdiff/commands.py 116 3 97% 115, 118-119
deepdiff/deephash.py 326 2 99% 352-353
deepdiff/delta.py 359 2 99% 176-177
deepdiff/diff.py 834 3 99% 472, 793, 1680
deepdiff/distance.py 141 0 100%
deepdiff/helper.py 323 6 98% 93-94, 656-657, 665-668
deepdiff/lfucache.py 154 6 96% 18-19, 74, 107, 142, 218
deepdiff/model.py 408 1 99% 638
deepdiff/operator.py 28 1 96% 27
deepdiff/path.py 102 7 93% 74, 92, 122-126
deepdiff/search.py 148 0 100%
deepdiff/serialization.py 243 11 95% 20, 31, 373, 486-488, 523, 583-586
---------------------------------------------------------
TOTAL 3263 42 99%
Note 1: _diff_booleans
One thing to note is that the precompiled regex detection relies on DeepDiff._diff_booleans. So now _diff_booleans acts more like a _diff_booleans_and_precompiled_regex.
At first I had created a dedicated DeepDiff._diff_precompiled_regex method, but then realized that it was identical to _diff_booleans which already exists. So I just reused _diff_booleans to avoid bloating the code base.
If you're okay with coopting _diff_booleans like this, we might as well collapse further and just do
if isinstance(level.t1, (booleans, Pattern)):
self._diff_booleans(level, local_tree=local_tree)
Otherwise, I can recreate my original _diff_precompiled_regex method, or entertain anything else you'd propose.
Note 2: Delta
JFYI, I did not touch the code in deepdiff/delta.py, because it seems to already work as is.
>>> from deepdiff import Delta
>>> diff_bool = DeepDiff(True, False)
>>> Delta(diff_bool)
<Delta: {'values_changed': {'root': {'new_value': False}}}>
>>> Delta(diff_13)
<Delta: {'values_changed': {'root': {'new_value': re.compile('bar')}}}>
If anything looks amiss there, let me know and I will update the PR.