From fcf830caeddbdd8cee55fbd1f515da53f1cdecc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Mar 2021 00:39:14 +0000 Subject: [PATCH 1/9] Bump pyyaml from 5.3.1 to 5.4 Bumps [pyyaml](https://github.com/yaml/pyyaml) from 5.3.1 to 5.4. - [Release notes](https://github.com/yaml/pyyaml/releases) - [Changelog](https://github.com/yaml/pyyaml/blob/master/CHANGES) - [Commits](https://github.com/yaml/pyyaml/compare/5.3.1...5.4) Signed-off-by: dependabot[bot] --- requirements-cli.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-cli.txt b/requirements-cli.txt index 16e2df7e..361b58ba 100644 --- a/requirements-cli.txt +++ b/requirements-cli.txt @@ -1,4 +1,4 @@ click==7.1.2 -pyyaml==5.3.1 +pyyaml==5.4 toml==0.10.2 clevercsv==0.6.6 From 767beadf8ef566cc64e7b90d1ae23341a6273a06 Mon Sep 17 00:00:00 2001 From: Lyz Date: Tue, 6 Apr 2021 15:48:09 +0200 Subject: [PATCH 2/9] feat: add support for regular expressions --- deepdiff/search.py | 11 ++++--- tests/test_search.py | 77 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/deepdiff/search.py b/deepdiff/search.py index 4226a6a4..e839ce55 100644 --- a/deepdiff/search.py +++ b/deepdiff/search.py @@ -135,7 +135,7 @@ def __search_obj(self, if obj == item: found = True # We report the match but also continue inside the match to see if there are - # furthur matches inside the `looped` object. + # further matches inside the `looped` object. self.__report(report_key='matched_values', key=parent, value=obj) try: @@ -205,7 +205,7 @@ def __search_dict(self, str_item = str(item) if (self.match_string and str_item == new_parent_cased) or\ - (not self.match_string and str_item in new_parent_cased): + (not self.match_string and re.search(str_item, new_parent_cased)): self.__report( report_key='matched_paths', key=new_parent, @@ -233,7 +233,9 @@ def __search_iterable(self, else: thing_cased = thing.lower() - if thing_cased == item: + if thing_cased == item or \ + (isinstance(thing_cased, str) and isinstance(item, str) and \ + re.search(item, thing_cased)): self.__report( report_key='matched_values', key=new_parent, value=thing) else: @@ -248,7 +250,8 @@ def __search_str(self, obj, item, parent): """Compare strings""" obj_text = obj if self.case_sensitive else obj.lower() - if (self.match_string and item == obj_text) or (not self.match_string and item in obj_text): + if (self.match_string and item == obj_text) or \ + (not self.match_string and re.search(item, obj_text)): self.__report(report_key='matched_values', key=parent, value=obj) def __search_numbers(self, obj, item, parent): diff --git a/tests/test_search.py b/tests/test_search.py index 247e648e..c302a2eb 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -336,6 +336,83 @@ class Child(Parent): result = {'matched_values': {'root.a'}} assert DeepSearch(obj, item, verbose_level=1) == result + def test_regex_in_string(self): + obj = "long string somewhere" + item = "some.*" + result = {"matched_values": {"root"}} + assert DeepSearch(obj, item, verbose_level=1) == result + + def test_regex_in_string_in_tuple(self): + obj = ("long", "string", 0, "somewhere") + item = "some.*" + result = {"matched_values": {"root[3]"}} + assert DeepSearch(obj, item, verbose_level=1) == result + + def test_regex_in_string_in_list(self): + obj = ["long", "string", 0, "somewhere"] + item = "some.*" + result = {"matched_values": {"root[3]"}} + assert DeepSearch(obj, item, verbose_level=1) == result + + def test_regex_in_string_in_dictionary(self): + obj = {"long": "somewhere", "string": 2, 0: 0, "somewhere": "around"} + result = { + "matched_paths": {"root['somewhere']"}, + "matched_values": {"root['long']"}, + } + item = "some.*" + ds = DeepSearch(obj, item, verbose_level=1) + assert ds == result + + def test_regex_in_string_in_dictionary_in_list_verbose(self): + obj = [ + "something somewhere", + {"long": "somewhere", "string": 2, 0: 0, "somewhere": "around"}, + ] + result = { + "matched_paths": {"root[1]['somewhere']": "around"}, + "matched_values": { + "root[1]['long']": "somewhere", + "root[0]": "something somewhere", + }, + } + item = "some.*" + ds = DeepSearch(obj, item, verbose_level=2) + assert ds == result + + def test_regex_in_custom_object(self): + obj = CustomClass("here, something", "somewhere") + result = {"matched_values": {"root.b"}} + item = "somew.*" + ds = DeepSearch(obj, item, verbose_level=1) + assert ds == result + + def test_regex_in_custom_object_in_dictionary_verbose(self): + obj = {1: CustomClass("here, something", "somewhere out there")} + result = {"matched_values": {"root[1].b": "somewhere out there"}} + item = "somew.*" + ds = DeepSearch(obj, item, verbose_level=2) + assert ds == result + + def test_regex_in_named_tuples_verbose(self): + from collections import namedtuple + + Point = namedtuple("Point", ["x", "somewhere_good"]) + obj = Point(x="my keys are somewhere", somewhere_good=22) + item = "some.*" + ds = DeepSearch(obj, item, verbose_level=2) + result = { + "matched_values": {"root.x": "my keys are somewhere"}, + "matched_paths": {"root.somewhere_good": 22}, + } + assert ds == result + + def test_regex_in_string_in_set_verbose(self): + obj = {"long", "string", 0, "somewhere"} + # result = {"matched_values": {'root[3]': "somewhere"}} + item = "some.*" + ds = DeepSearch(obj, item, verbose_level=2) + assert list(ds["matched_values"].values())[0] == "somewhere" class TestGrep: From 9594f390bde0cb543596f0734e7821e11bddfb1a Mon Sep 17 00:00:00 2001 From: Seperman Date: Tue, 13 Apr 2021 14:38:49 -0700 Subject: [PATCH 3/9] bumping clevercsv --- requirements-cli.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-cli.txt b/requirements-cli.txt index 361b58ba..7518df0d 100644 --- a/requirements-cli.txt +++ b/requirements-cli.txt @@ -1,4 +1,4 @@ click==7.1.2 pyyaml==5.4 toml==0.10.2 -clevercsv==0.6.6 +clevercsv==0.6.7 From baab71618c362d55f6fd59825c005145f3c914a1 Mon Sep 17 00:00:00 2001 From: Lyz Date: Thu, 15 Apr 2021 17:35:30 +0200 Subject: [PATCH 4/9] perf: make regular expression searching optional and disabled by default --- deepdiff/search.py | 14 +++++++++++--- tests/test_search.py | 24 +++++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/deepdiff/search.py b/deepdiff/search.py index e839ce55..5233b107 100644 --- a/deepdiff/search.py +++ b/deepdiff/search.py @@ -40,6 +40,8 @@ class DeepSearch(dict): If True, the value of the object or its children have to exactly match the item. If False, the value of the item can be a part of the value of the object or its children + use_regexp: Boolean, default = False + **Returns** A DeepSearch object that has the matched paths and matched values. @@ -83,6 +85,7 @@ def __init__(self, verbose_level=1, case_sensitive=False, match_string=False, + use_regexp=False, **kwargs): if kwargs: raise ValueError(( @@ -104,6 +107,9 @@ def __init__(self, matched_paths=self.__set_or_dict(), matched_values=self.__set_or_dict(), unprocessed=[]) + self.use_regexp = use_regexp + if self.use_regexp: + self.search_regexp = re.compile(item) # Cases where user wants to match exact string item self.match_string = match_string @@ -205,7 +211,8 @@ def __search_dict(self, str_item = str(item) if (self.match_string and str_item == new_parent_cased) or\ - (not self.match_string and re.search(str_item, new_parent_cased)): + (not self.match_string and str_item in new_parent_cased) or\ + (self.use_regexp and self.search_regexp.search(new_parent_cased)): self.__report( report_key='matched_paths', key=new_parent, @@ -235,7 +242,7 @@ def __search_iterable(self, if thing_cased == item or \ (isinstance(thing_cased, str) and isinstance(item, str) and \ - re.search(item, thing_cased)): + self.use_regexp and self.search_regexp.search(thing_cased)): self.__report( report_key='matched_values', key=new_parent, value=thing) else: @@ -251,7 +258,8 @@ def __search_str(self, obj, item, parent): obj_text = obj if self.case_sensitive else obj.lower() if (self.match_string and item == obj_text) or \ - (not self.match_string and re.search(item, obj_text)): + (not self.match_string and item in obj_text) or \ + (self.use_regexp and self.search_regexp.search(obj_text)): self.__report(report_key='matched_values', key=parent, value=obj) def __search_numbers(self, obj, item, parent): diff --git a/tests/test_search.py b/tests/test_search.py index c302a2eb..51150bbd 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -336,23 +336,29 @@ class Child(Parent): result = {'matched_values': {'root.a'}} assert DeepSearch(obj, item, verbose_level=1) == result + def test_dont_use_regex_by_default(self): + obj = "long string somewhere" + item = "some.*" + result = {} + assert DeepSearch(obj, item, verbose_level=1) == result + def test_regex_in_string(self): obj = "long string somewhere" item = "some.*" result = {"matched_values": {"root"}} - assert DeepSearch(obj, item, verbose_level=1) == result + assert DeepSearch(obj, item, verbose_level=1, use_regexp=True) == result def test_regex_in_string_in_tuple(self): obj = ("long", "string", 0, "somewhere") item = "some.*" result = {"matched_values": {"root[3]"}} - assert DeepSearch(obj, item, verbose_level=1) == result + assert DeepSearch(obj, item, verbose_level=1, use_regexp=True) == result def test_regex_in_string_in_list(self): obj = ["long", "string", 0, "somewhere"] item = "some.*" result = {"matched_values": {"root[3]"}} - assert DeepSearch(obj, item, verbose_level=1) == result + assert DeepSearch(obj, item, verbose_level=1, use_regexp=True) == result def test_regex_in_string_in_dictionary(self): obj = {"long": "somewhere", "string": 2, 0: 0, "somewhere": "around"} @@ -361,7 +367,7 @@ def test_regex_in_string_in_dictionary(self): "matched_values": {"root['long']"}, } item = "some.*" - ds = DeepSearch(obj, item, verbose_level=1) + ds = DeepSearch(obj, item, verbose_level=1, use_regexp=True) assert ds == result def test_regex_in_string_in_dictionary_in_list_verbose(self): @@ -377,21 +383,21 @@ def test_regex_in_string_in_dictionary_in_list_verbose(self): }, } item = "some.*" - ds = DeepSearch(obj, item, verbose_level=2) + ds = DeepSearch(obj, item, verbose_level=2, use_regexp=True) assert ds == result def test_regex_in_custom_object(self): obj = CustomClass("here, something", "somewhere") result = {"matched_values": {"root.b"}} item = "somew.*" - ds = DeepSearch(obj, item, verbose_level=1) + ds = DeepSearch(obj, item, verbose_level=1, use_regexp=True) assert ds == result def test_regex_in_custom_object_in_dictionary_verbose(self): obj = {1: CustomClass("here, something", "somewhere out there")} result = {"matched_values": {"root[1].b": "somewhere out there"}} item = "somew.*" - ds = DeepSearch(obj, item, verbose_level=2) + ds = DeepSearch(obj, item, verbose_level=2, use_regexp=True) assert ds == result def test_regex_in_named_tuples_verbose(self): @@ -400,7 +406,7 @@ def test_regex_in_named_tuples_verbose(self): Point = namedtuple("Point", ["x", "somewhere_good"]) obj = Point(x="my keys are somewhere", somewhere_good=22) item = "some.*" - ds = DeepSearch(obj, item, verbose_level=2) + ds = DeepSearch(obj, item, verbose_level=2, use_regexp=True) result = { "matched_values": {"root.x": "my keys are somewhere"}, "matched_paths": {"root.somewhere_good": 22}, @@ -411,7 +417,7 @@ def test_regex_in_string_in_set_verbose(self): obj = {"long", "string", 0, "somewhere"} # result = {"matched_values": {'root[3]': "somewhere"}} item = "some.*" - ds = DeepSearch(obj, item, verbose_level=2) + ds = DeepSearch(obj, item, verbose_level=2, use_regexp=True) assert list(ds["matched_values"].values())[0] == "somewhere" class TestGrep: From 27a892d4f6b42d4299a4ebcbb1e69b2f6c6e292f Mon Sep 17 00:00:00 2001 From: Seperman Date: Fri, 16 Apr 2021 11:44:58 -0700 Subject: [PATCH 5/9] fixing edge case where the string and regex were matches --- deepdiff/search.py | 24 +++++++++++++----------- tests/test_search.py | 14 +++++++++++++- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/deepdiff/search.py b/deepdiff/search.py index 5233b107..799db9e7 100644 --- a/deepdiff/search.py +++ b/deepdiff/search.py @@ -4,7 +4,9 @@ from deepdiff.helper import OrderedSetPlus import logging -from deepdiff.helper import strings, numbers, add_to_frozen_set, get_doc, dict_ +from deepdiff.helper import ( + strings, numbers, add_to_frozen_set, get_doc, dict_, RE_COMPILED_TYPE +) logger = logging.getLogger(__name__) @@ -109,7 +111,7 @@ def __init__(self, unprocessed=[]) self.use_regexp = use_regexp if self.use_regexp: - self.search_regexp = re.compile(item) + item = re.compile(item) # Cases where user wants to match exact string item self.match_string = match_string @@ -212,7 +214,7 @@ def __search_dict(self, str_item = str(item) if (self.match_string and str_item == new_parent_cased) or\ (not self.match_string and str_item in new_parent_cased) or\ - (self.use_regexp and self.search_regexp.search(new_parent_cased)): + (self.use_regexp and item.search(new_parent_cased)): self.__report( report_key='matched_paths', key=new_parent, @@ -240,9 +242,7 @@ def __search_iterable(self, else: thing_cased = thing.lower() - if thing_cased == item or \ - (isinstance(thing_cased, str) and isinstance(item, str) and \ - self.use_regexp and self.search_regexp.search(thing_cased)): + if not self.use_regexp and thing_cased == item: self.__report( report_key='matched_values', key=new_parent, value=thing) else: @@ -257,9 +257,12 @@ def __search_str(self, obj, item, parent): """Compare strings""" obj_text = obj if self.case_sensitive else obj.lower() - if (self.match_string and item == obj_text) or \ - (not self.match_string and item in obj_text) or \ - (self.use_regexp and self.search_regexp.search(obj_text)): + is_matched = False + if self.use_regexp: + is_matched = item.search(obj_text) + elif (self.match_string and item == obj_text) or (not self.match_string and item in obj_text): + is_matched = True + if is_matched: self.__report(report_key='matched_values', key=parent, value=obj) def __search_numbers(self, obj, item, parent): @@ -281,11 +284,10 @@ def __search_tuple(self, obj, item, parent, parents_ids): def __search(self, obj, item, parent="root", parents_ids=frozenset()): """The main search method""" - # import pytest; pytest.set_trace() if self.__skip_this(item, parent): return - elif isinstance(obj, strings) and isinstance(item, strings): + elif isinstance(obj, strings) and isinstance(item, (strings, RE_COMPILED_TYPE)): self.__search_str(obj, item, parent) elif isinstance(obj, strings) and isinstance(item, numbers): diff --git a/tests/test_search.py b/tests/test_search.py index 51150bbd..b97f15ac 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -348,6 +348,12 @@ def test_regex_in_string(self): result = {"matched_values": {"root"}} assert DeepSearch(obj, item, verbose_level=1, use_regexp=True) == result + def test_regex_does_not_match_the_regex_string_itself(self): + obj = ["We like python", "but not (?:p|t)ython"] + item = "(?:p|t)ython" + result = {'matched_values': ['root[0]']} + assert DeepSearch(obj, item, verbose_level=1, use_regexp=True) == result + def test_regex_in_string_in_tuple(self): obj = ("long", "string", 0, "somewhere") item = "some.*" @@ -415,11 +421,11 @@ def test_regex_in_named_tuples_verbose(self): def test_regex_in_string_in_set_verbose(self): obj = {"long", "string", 0, "somewhere"} - # result = {"matched_values": {'root[3]': "somewhere"}} item = "some.*" ds = DeepSearch(obj, item, verbose_level=2, use_regexp=True) assert list(ds["matched_values"].values())[0] == "somewhere" + class TestGrep: def test_grep_dict(self): @@ -448,3 +454,9 @@ def test_grep_with_non_utf8_chars(self): item = {"z": "z"} result = obj | grep(item) assert {} == result + + def test_grep_regex_in_string_in_tuple(self): + obj = ("long", "string", 0, "somewhere") + item = "some.*" + result = {"matched_values": {"root[3]"}} + assert obj | grep(item, verbose_level=1, use_regexp=True) == result From 72e8994bf4ffc401665ab683dd928838220cb629 Mon Sep 17 00:00:00 2001 From: Seperman Date: Fri, 16 Apr 2021 15:56:23 -0700 Subject: [PATCH 6/9] adding authors and other info --- AUTHORS.md | 1 + CHANGELOG.md | 1 + LICENSE | 2 +- README.md | 12 ++++++++++++ docs/authors.rst | 3 +++ docs/changelog.rst | 1 + docs/search_doc.rst | 6 ++++++ 7 files changed, 25 insertions(+), 1 deletion(-) diff --git a/AUTHORS.md b/AUTHORS.md index 4eeb0a88..18e340ef 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -35,3 +35,4 @@ Authors in order of the contributions: - Florian Klien [flowolf](https://github.com/flowolf) for adding math_epsilon - Tim Klein [timjklein36](https://github.com/timjklein36) for retaining the order of multiple dictionary items added via Delta. - Wilhelm Schürmann[wbsch](https://github.com/wbsch) for fixing the typo with yml files. +- [lyz-code](https://github.com/lyz-code) for adding support for regular expressions. diff --git a/CHANGELOG.md b/CHANGELOG.md index 5203babc..97d442fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # DeepDiff Change log +- v5-2-4: add support for regular expressions - 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. - v5-2-2: Fixed Delta serialization when None type is present. - 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. diff --git a/LICENSE b/LICENSE index 424242c7..e09c3d78 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 - 2020 Sep Dehpour (Seperman) and contributors +Copyright (c) 2014 - 2021 Sep Dehpour (Seperman) and contributors www.zepworks.com Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/README.md b/README.md index 9bd2956c..c888a7ff 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,18 @@ Tested on Python 3.6+ and PyPy3. - [Documentation](https://zepworks.com/deepdiff/5.2.3/) +## What is new? + +Deepdiff 5.2.4 comes with regular expressions in the DeepSearch and grep modules: + +```python +>>> from deepdiff import grep +>>> from pprint import pprint +>>> obj = ["something here", {"long": "somewhere", "someone": 2, 0: 0, "somewhere": "around"}] +>>> ds = obj | grep("some.*", use_regexp=True) +{ 'matched_paths': ["root[1]['someone']", "root[1]['somewhere']"], + 'matched_values': ['root[0]', "root[1]['long']"]} +``` ## Installation diff --git a/docs/authors.rst b/docs/authors.rst index ee86f776..8eb0c36c 100644 --- a/docs/authors.rst +++ b/docs/authors.rst @@ -42,6 +42,8 @@ Thanks to the following people for their contributions: - Florian Klien `flowolf`_ for adding math_epsilon - Tim Klein `timjklein36`_ for retaining the order of multiple dictionary items added via Delta - Wilhelm Schürmann `wbsch`_ for fixing the typo with yml files. +- `lyz_code`_ for adding support for regular expressions. + .. _Sep Dehpour (Seperman): http://www.zepworks.com .. _Victor Hahn Castell: http://hahncastell.de @@ -74,6 +76,7 @@ Thanks to the following people for their contributions: .. _flowolf: https://github.com/flowolf .. _timjklein36: https://github.com/timjklein36 .. _wbsch: https://github.com/wbsch +.. _lyz_code: https://github.com/lyz-code Back to :doc:`/index` diff --git a/docs/changelog.rst b/docs/changelog.rst index ba6274de..765addab 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,7 @@ Changelog DeepDiff Changelog +- v5-2-4: add support for regular expressions - 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. - v5-2-2: Fixed Delta serialization when None type is present. - 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. diff --git a/docs/search_doc.rst b/docs/search_doc.rst index 1f4117b7..cd8da261 100644 --- a/docs/search_doc.rst +++ b/docs/search_doc.rst @@ -22,3 +22,9 @@ Search in nested data for string { 'matched_paths': {"root[1]['somewhere']": 'around'}, 'matched_values': { 'root[0]': 'something somewhere', "root[1]['long']": 'somewhere'}} + +You can also use regular expressions + >>> obj = ["something here", {"long": "somewhere", "someone": 2, 0: 0, "somewhere": "around"}] + >>> ds = obj | grep("some.*", use_regexp=True) + { 'matched_paths': ["root[1]['someone']", "root[1]['somewhere']"], + 'matched_values': ['root[0]', "root[1]['long']"]} From 4d4116cd26a5c9466d65d761865cc123012f654f Mon Sep 17 00:00:00 2001 From: Seperman Date: Fri, 16 Apr 2021 15:59:40 -0700 Subject: [PATCH 7/9] version change --- CHANGELOG.md | 2 +- README.md | 2 +- docs/changelog.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97d442fb..582073d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # DeepDiff Change log -- v5-2-4: add support for regular expressions +- v5-3-0: add support for regular expressions - 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. - v5-2-2: Fixed Delta serialization when None type is present. - 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. diff --git a/README.md b/README.md index c888a7ff..3ea3d907 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Tested on Python 3.6+ and PyPy3. ## What is new? -Deepdiff 5.2.4 comes with regular expressions in the DeepSearch and grep modules: +Deepdiff 5.3.0 comes with regular expressions in the DeepSearch and grep modules: ```python >>> from deepdiff import grep diff --git a/docs/changelog.rst b/docs/changelog.rst index 765addab..0a80a639 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,7 +5,7 @@ Changelog DeepDiff Changelog -- v5-2-4: add support for regular expressions +- v5-3-0: add support for regular expressions - 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. - v5-2-2: Fixed Delta serialization when None type is present. - 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. From 77b9b581b11e1885c0a9b14ac301f318fa41233c Mon Sep 17 00:00:00 2001 From: Seperman Date: Fri, 16 Apr 2021 15:59:53 -0700 Subject: [PATCH 8/9] =?UTF-8?q?Bump=20version:=205.2.3=20=E2=86=92=205.3.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 +++++++++++++------------- deepdiff/__init__.py | 2 +- docs/conf.py | 4 ++-- docs/index.rst | 2 +- setup.cfg | 2 +- setup.py | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 3ea3d907..9bf7de2b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# DeepDiff v 5.2.3 +# DeepDiff v 5.3.0 ![Downloads](https://img.shields.io/pypi/dm/deepdiff.svg?style=flat) ![Python Versions](https://img.shields.io/pypi/pyversions/deepdiff.svg?style=flat) @@ -18,7 +18,7 @@ Tested on Python 3.6+ and PyPy3. **NOTE: The last version of DeepDiff to work on Python 3.5 was DeepDiff 5-0-2** -- [Documentation](https://zepworks.com/deepdiff/5.2.3/) +- [Documentation](https://zepworks.com/deepdiff/5.3.0/) ## What is new? @@ -66,13 +66,13 @@ Note: if you want to use DeepDiff via commandline, make sure to run `pip install DeepDiff gets the difference of 2 objects. -> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.2.3/diff.html) -> - The full documentation of all modules can be found on +> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.3.0/diff.html) +> - The full documentation of all modules can be found on > - Tutorials and posts about DeepDiff can be found on ## A few Examples -> Note: This is just a brief overview of what DeepDiff can do. Please visit for full documentation. +> Note: This is just a brief overview of what DeepDiff can do. Please visit for full documentation. ### List difference ignoring order or duplicates @@ -276,8 +276,8 @@ Example: ``` -> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.2.3/diff.html) -> - The full documentation can be found on +> - Please take a look at the [DeepDiff docs](https://zepworks.com/deepdiff/5.3.0/diff.html) +> - The full documentation can be found on # Deep Search @@ -309,8 +309,8 @@ And you can pass all the same kwargs as DeepSearch to grep too: {'matched_paths': {"root['somewhere']": 'around'}, 'matched_values': {"root['long']": 'somewhere'}} ``` -> - Please take a look at the [DeepSearch docs](https://zepworks.com/deepdiff/5.2.3/dsearch.html) -> - The full documentation can be found on +> - Please take a look at the [DeepSearch docs](https://zepworks.com/deepdiff/5.3.0/dsearch.html) +> - The full documentation can be found on # Deep Hash (New in v4-0-0) @@ -318,8 +318,8 @@ And you can pass all the same kwargs as DeepSearch to grep too: DeepHash is designed to give you hash of ANY python object based on its contents even if the object is not considered hashable! DeepHash is supposed to be deterministic in order to make sure 2 objects that contain the same data, produce the same hash. -> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.2.3/deephash.html) -> - The full documentation can be found on +> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.3.0/deephash.html) +> - The full documentation can be found on Let's say you have a dictionary object. @@ -367,8 +367,8 @@ Which you can write as: 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. -> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.2.3/deephash.html) -> - The full documentation can be found on +> - Please take a look at the [DeepHash docs](https://zepworks.com/deepdiff/5.3.0/deephash.html) +> - The full documentation can be found on # Using DeepDiff in unit tests diff --git a/deepdiff/__init__.py b/deepdiff/__init__.py index fcde3bc6..fe20a6ad 100644 --- a/deepdiff/__init__.py +++ b/deepdiff/__init__.py @@ -1,6 +1,6 @@ """This module offers the DeepDiff, DeepSearch, grep, Delta and DeepHash classes.""" # flake8: noqa -__version__ = '5.2.3' +__version__ = '5.3.0' import logging if __name__ == '__main__': diff --git a/docs/conf.py b/docs/conf.py index 9457fbd7..88153f38 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -60,9 +60,9 @@ # built documents. # # The short X.Y version. -version = '5.2.3' +version = '5.3.0' # The full version, including alpha/beta/rc tags. -release = '5.2.3' +release = '5.3.0' load_dotenv(override=True) DOC_VERSION = os.environ.get('DOC_VERSION', version) diff --git a/docs/index.rst b/docs/index.rst index 57b4277e..5a1b3941 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ contain the root `toctree` directive. -DeepDiff 5.2.3 documentation! +DeepDiff 5.3.0 documentation! ============================= ***************** diff --git a/setup.cfg b/setup.cfg index 2a0b0cf3..abc1f4a4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 5.2.3 +current_version = 5.3.0 commit = True tag = True tag_name = {new_version} diff --git a/setup.py b/setup.py index 50502c25..3eb90426 100755 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ if os.environ.get('USER', '') == 'vagrant': del os.link -version = '5.2.3' +version = '5.3.0' def get_reqs(filename): From 874453952fd4cbfe6d05aa08bbc0f9e6c2ebfe1e Mon Sep 17 00:00:00 2001 From: Seperman Date: Fri, 16 Apr 2021 16:14:59 -0700 Subject: [PATCH 9/9] adding what is new --- docs/index.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 5a1b3941..4378a786 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -35,6 +35,23 @@ DeepDiff is rigorously tested against Python 3.6, 3.7, 3.8, 3.9 and Pypy3 NOTE: Python 2 is not supported any more. DeepDiff v3.3.0 was the last version to supprt Python 2. +*********** +What is New +*********** + +Deepdiff 5.3.0 comes with regular expressions in the DeepSearch and grep modules: + + +.. code:: python + + >>> from deepdiff import grep + >>> from pprint import pprint + >>> obj = ["something here", {"long": "somewhere", "someone": 2, 0: 0, "somewhere": "around"}] + >>> ds = obj | grep("some.*", use_regexp=True) + { 'matched_paths': ["root[1]['someone']", "root[1]['somewhere']"], + 'matched_values': ['root[0]', "root[1]['long']"]} + + ********* Tutorials *********