Skip to content

Commit 2b04c55

Browse files
authored
Merge pull request #240 from seperman/dev
DeepDiff 5.3.0
2 parents 5b66b96 + 8744539 commit 2b04c55

15 files changed

+178
-29
lines changed

AUTHORS.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ Authors in order of the contributions:
3535
- Florian Klien [flowolf](https://github.com/flowolf) for adding math_epsilon
3636
- Tim Klein [timjklein36](https://github.com/timjklein36) for retaining the order of multiple dictionary items added via Delta.
3737
- Wilhelm Schürmann[wbsch](https://github.com/wbsch) for fixing the typo with yml files.
38+
- [lyz-code](https://github.com/lyz-code) for adding support for regular expressions.

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# DeepDiff Change log
22

3+
- v5-3-0: add support for regular expressions
34
- v5-2-3: Retaining the order of multiple dictionary items added via Delta. Fixed the typo with yml files in deep cli. Fixing Grep RecursionError where using non UTF-8 character. Allowing kwargs to be passed to to_json method.
45
- v5-2-2: Fixed Delta serialization when None type is present.
56
- v5-2-0: Removed Murmur3 as the preferred hashing method. Using SHA256 by default now. Added commandline for deepdiff. Added group_by. Added math_epsilon. Improved ignoring of NoneType.

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2014 - 2020 Sep Dehpour (Seperman) and contributors
3+
Copyright (c) 2014 - 2021 Sep Dehpour (Seperman) and contributors
44
www.zepworks.com
55

66
Permission is hereby granted, free of charge, to any person obtaining a copy

README.md

+25-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# DeepDiff v 5.2.3
1+
# DeepDiff v 5.3.0
22

33
![Downloads](https://img.shields.io/pypi/dm/deepdiff.svg?style=flat)
44
![Python Versions](https://img.shields.io/pypi/pyversions/deepdiff.svg?style=flat)
@@ -18,8 +18,20 @@ Tested on Python 3.6+ and PyPy3.
1818

1919
**NOTE: The last version of DeepDiff to work on Python 3.5 was DeepDiff 5-0-2**
2020

21-
- [Documentation](https://zepworks.com/deepdiff/5.2.3/)
21+
- [Documentation](https://zepworks.com/deepdiff/5.3.0/)
2222

23+
## What is new?
24+
25+
Deepdiff 5.3.0 comes with regular expressions in the DeepSearch and grep modules:
26+
27+
```python
28+
>>> from deepdiff import grep
29+
>>> from pprint import pprint
30+
>>> obj = ["something here", {"long": "somewhere", "someone": 2, 0: 0, "somewhere": "around"}]
31+
>>> ds = obj | grep("some.*", use_regexp=True)
32+
{ 'matched_paths': ["root[1]['someone']", "root[1]['somewhere']"],
33+
'matched_values': ['root[0]', "root[1]['long']"]}
34+
```
2335

2436
## Installation
2537

@@ -54,13 +66,13 @@ Note: if you want to use DeepDiff via commandline, make sure to run `pip install
5466

5567
DeepDiff gets the difference of 2 objects.
5668

57-
> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.2.3/diff.html)
58-
> - The full documentation of all modules can be found on <https://zepworks.com/deepdiff/5.2.3/>
69+
> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.3.0/diff.html)
70+
> - The full documentation of all modules can be found on <https://zepworks.com/deepdiff/5.3.0/>
5971
> - Tutorials and posts about DeepDiff can be found on <https://zepworks.com/tags/deepdiff/>
6072
6173
## A few Examples
6274

63-
> Note: This is just a brief overview of what DeepDiff can do. Please visit <https://zepworks.com/deepdiff/5.2.3/> for full documentation.
75+
> Note: This is just a brief overview of what DeepDiff can do. Please visit <https://zepworks.com/deepdiff/5.3.0/> for full documentation.
6476
6577
### List difference ignoring order or duplicates
6678

@@ -264,8 +276,8 @@ Example:
264276
```
265277

266278

267-
> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.2.3/diff.html)
268-
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.2.3/>
279+
> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.3.0/diff.html)
280+
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.3.0/>
269281
270282

271283
# Deep Search
@@ -297,17 +309,17 @@ And you can pass all the same kwargs as DeepSearch to grep too:
297309
{'matched_paths': {"root['somewhere']": 'around'}, 'matched_values': {"root['long']": 'somewhere'}}
298310
```
299311

300-
> - Please take a look at the [DeepSearch docs](https://zepworks.com/deepdiff/5.2.3/dsearch.html)
301-
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.2.3/>
312+
> - Please take a look at the [DeepSearch docs](https://zepworks.com/deepdiff/5.3.0/dsearch.html)
313+
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.3.0/>
302314
303315
# Deep Hash
304316
(New in v4-0-0)
305317

306318
DeepHash is designed to give you hash of ANY python object based on its contents even if the object is not considered hashable!
307319
DeepHash is supposed to be deterministic in order to make sure 2 objects that contain the same data, produce the same hash.
308320

309-
> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.2.3/deephash.html)
310-
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.2.3/>
321+
> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.3.0/deephash.html)
322+
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.3.0/>
311323
312324
Let's say you have a dictionary object.
313325

@@ -355,8 +367,8 @@ Which you can write as:
355367
At first it might seem weird why DeepHash(obj)[obj] but remember that DeepHash(obj) is a dictionary of hashes of all other objects that obj contains too.
356368

357369

358-
> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.2.3/deephash.html)
359-
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.2.3/>
370+
> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.3.0/deephash.html)
371+
> - The full documentation can be found on <https://zepworks.com/deepdiff/5.3.0/>
360372
361373

362374
# Using DeepDiff in unit tests

deepdiff/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""This module offers the DeepDiff, DeepSearch, grep, Delta and DeepHash classes."""
22
# flake8: noqa
3-
__version__ = '5.2.3'
3+
__version__ = '5.3.0'
44
import logging
55

66
if __name__ == '__main__':

deepdiff/search.py

+20-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
from deepdiff.helper import OrderedSetPlus
55
import logging
66

7-
from deepdiff.helper import strings, numbers, add_to_frozen_set, get_doc, dict_
7+
from deepdiff.helper import (
8+
strings, numbers, add_to_frozen_set, get_doc, dict_, RE_COMPILED_TYPE
9+
)
810

911
logger = logging.getLogger(__name__)
1012

@@ -40,6 +42,8 @@ class DeepSearch(dict):
4042
If True, the value of the object or its children have to exactly match the item.
4143
If False, the value of the item can be a part of the value of the object or its children
4244
45+
use_regexp: Boolean, default = False
46+
4347
**Returns**
4448
4549
A DeepSearch object that has the matched paths and matched values.
@@ -83,6 +87,7 @@ def __init__(self,
8387
verbose_level=1,
8488
case_sensitive=False,
8589
match_string=False,
90+
use_regexp=False,
8691
**kwargs):
8792
if kwargs:
8893
raise ValueError((
@@ -104,6 +109,9 @@ def __init__(self,
104109
matched_paths=self.__set_or_dict(),
105110
matched_values=self.__set_or_dict(),
106111
unprocessed=[])
112+
self.use_regexp = use_regexp
113+
if self.use_regexp:
114+
item = re.compile(item)
107115

108116
# Cases where user wants to match exact string item
109117
self.match_string = match_string
@@ -135,7 +143,7 @@ def __search_obj(self,
135143
if obj == item:
136144
found = True
137145
# We report the match but also continue inside the match to see if there are
138-
# furthur matches inside the `looped` object.
146+
# further matches inside the `looped` object.
139147
self.__report(report_key='matched_values', key=parent, value=obj)
140148

141149
try:
@@ -205,7 +213,8 @@ def __search_dict(self,
205213

206214
str_item = str(item)
207215
if (self.match_string and str_item == new_parent_cased) or\
208-
(not self.match_string and str_item in new_parent_cased):
216+
(not self.match_string and str_item in new_parent_cased) or\
217+
(self.use_regexp and item.search(new_parent_cased)):
209218
self.__report(
210219
report_key='matched_paths',
211220
key=new_parent,
@@ -233,7 +242,7 @@ def __search_iterable(self,
233242
else:
234243
thing_cased = thing.lower()
235244

236-
if thing_cased == item:
245+
if not self.use_regexp and thing_cased == item:
237246
self.__report(
238247
report_key='matched_values', key=new_parent, value=thing)
239248
else:
@@ -248,7 +257,12 @@ def __search_str(self, obj, item, parent):
248257
"""Compare strings"""
249258
obj_text = obj if self.case_sensitive else obj.lower()
250259

251-
if (self.match_string and item == obj_text) or (not self.match_string and item in obj_text):
260+
is_matched = False
261+
if self.use_regexp:
262+
is_matched = item.search(obj_text)
263+
elif (self.match_string and item == obj_text) or (not self.match_string and item in obj_text):
264+
is_matched = True
265+
if is_matched:
252266
self.__report(report_key='matched_values', key=parent, value=obj)
253267

254268
def __search_numbers(self, obj, item, parent):
@@ -270,11 +284,10 @@ def __search_tuple(self, obj, item, parent, parents_ids):
270284

271285
def __search(self, obj, item, parent="root", parents_ids=frozenset()):
272286
"""The main search method"""
273-
# import pytest; pytest.set_trace()
274287
if self.__skip_this(item, parent):
275288
return
276289

277-
elif isinstance(obj, strings) and isinstance(item, strings):
290+
elif isinstance(obj, strings) and isinstance(item, (strings, RE_COMPILED_TYPE)):
278291
self.__search_str(obj, item, parent)
279292

280293
elif isinstance(obj, strings) and isinstance(item, numbers):

docs/authors.rst

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Thanks to the following people for their contributions:
4242
- Florian Klien `flowolf`_ for adding math_epsilon
4343
- Tim Klein `timjklein36`_ for retaining the order of multiple dictionary items added via Delta
4444
- Wilhelm Schürmann `wbsch`_ for fixing the typo with yml files.
45+
- `lyz_code`_ for adding support for regular expressions.
46+
4547

4648
.. _Sep Dehpour (Seperman): http://www.zepworks.com
4749
.. _Victor Hahn Castell: http://hahncastell.de
@@ -74,6 +76,7 @@ Thanks to the following people for their contributions:
7476
.. _flowolf: https://github.com/flowolf
7577
.. _timjklein36: https://github.com/timjklein36
7678
.. _wbsch: https://github.com/wbsch
79+
.. _lyz_code: https://github.com/lyz-code
7780

7881

7982
Back to :doc:`/index`

docs/changelog.rst

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changelog
55

66
DeepDiff Changelog
77

8+
- v5-3-0: add support for regular expressions
89
- v5-2-3: Retaining the order of multiple dictionary items added via Delta. Fixed the typo with yml files in deep cli. Fixing Grep RecursionError where using non UTF-8 character. Allowing kwargs to be passed to to_json method.
910
- v5-2-2: Fixed Delta serialization when None type is present.
1011
- v5-2-0: Removed Murmur3 as the preferred hashing method. Using SHA256 by default now. Added commandline for deepdiff. Added group_by. Added math_epsilon. Improved ignoring of NoneType.

docs/conf.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060
# built documents.
6161
#
6262
# The short X.Y version.
63-
version = '5.2.3'
63+
version = '5.3.0'
6464
# The full version, including alpha/beta/rc tags.
65-
release = '5.2.3'
65+
release = '5.3.0'
6666

6767
load_dotenv(override=True)
6868
DOC_VERSION = os.environ.get('DOC_VERSION', version)

docs/index.rst

+18-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
contain the root `toctree` directive.
55
66
7-
DeepDiff 5.2.3 documentation!
7+
DeepDiff 5.3.0 documentation!
88
=============================
99

1010
*****************
@@ -35,6 +35,23 @@ DeepDiff is rigorously tested against Python 3.6, 3.7, 3.8, 3.9 and Pypy3
3535

3636
NOTE: Python 2 is not supported any more. DeepDiff v3.3.0 was the last version to supprt Python 2.
3737

38+
***********
39+
What is New
40+
***********
41+
42+
Deepdiff 5.3.0 comes with regular expressions in the DeepSearch and grep modules:
43+
44+
45+
.. code:: python
46+
47+
>>> from deepdiff import grep
48+
>>> from pprint import pprint
49+
>>> obj = ["something here", {"long": "somewhere", "someone": 2, 0: 0, "somewhere": "around"}]
50+
>>> ds = obj | grep("some.*", use_regexp=True)
51+
{ 'matched_paths': ["root[1]['someone']", "root[1]['somewhere']"],
52+
'matched_values': ['root[0]', "root[1]['long']"]}
53+
54+
3855
*********
3956
Tutorials
4057
*********

docs/search_doc.rst

+6
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ Search in nested data for string
2222
{ 'matched_paths': {"root[1]['somewhere']": 'around'},
2323
'matched_values': { 'root[0]': 'something somewhere',
2424
"root[1]['long']": 'somewhere'}}
25+
26+
You can also use regular expressions
27+
>>> obj = ["something here", {"long": "somewhere", "someone": 2, 0: 0, "somewhere": "around"}]
28+
>>> ds = obj | grep("some.*", use_regexp=True)
29+
{ 'matched_paths': ["root[1]['someone']", "root[1]['somewhere']"],
30+
'matched_values': ['root[0]', "root[1]['long']"]}

requirements-cli.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
click==7.1.2
2-
pyyaml==5.3.1
2+
pyyaml==5.4
33
toml==0.10.2
4-
clevercsv==0.6.6
4+
clevercsv==0.6.7

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 5.2.3
2+
current_version = 5.3.0
33
commit = True
44
tag = True
55
tag_name = {new_version}

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
if os.environ.get('USER', '') == 'vagrant':
1111
del os.link
1212

13-
version = '5.2.3'
13+
version = '5.3.0'
1414

1515

1616
def get_reqs(filename):

0 commit comments

Comments
 (0)