diff --git a/README.md b/README.md index 52998db5..c4268718 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# DeepDiff v 6.4.1 +# DeepDiff v 6.5.0 ![Downloads](https://img.shields.io/pypi/dm/deepdiff.svg?style=flat) ![Python Versions](https://img.shields.io/pypi/pyversions/deepdiff.svg?style=flat) @@ -17,7 +17,7 @@ Tested on Python 3.7+ and PyPy3. -- **[Documentation](https://zepworks.com/deepdiff/6.4.1/)** +- **[Documentation](https://zepworks.com/deepdiff/6.5.0/)** ## What is new? @@ -82,11 +82,11 @@ Thank you! How to cite this library (APA style): - Dehpour, S. (2023). DeepDiff (Version 6.4.1) [Software]. Available from https://github.com/seperman/deepdiff. + Dehpour, S. (2023). DeepDiff (Version 6.5.0) [Software]. Available from https://github.com/seperman/deepdiff. How to cite this library (Chicago style): - Dehpour, Sep. 2023. DeepDiff (version 6.4.1). + Dehpour, Sep. 2023. DeepDiff (version 6.5.0). # Authors diff --git a/deepdiff/__init__.py b/deepdiff/__init__.py index 1398f17f..17fbb650 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__ = '6.4.1' +__version__ = '6.5.0' import logging if __name__ == '__main__': @@ -11,4 +11,4 @@ from .search import DeepSearch, grep from .deephash import DeepHash from .delta import Delta -from .path import extract +from .path import extract, parse_path diff --git a/deepdiff/path.py b/deepdiff/path.py index ad02b719..a228d0ab 100644 --- a/deepdiff/path.py +++ b/deepdiff/path.py @@ -185,3 +185,41 @@ def extract(obj, path): """ elements = _path_to_elements(path, root_element=None) return _get_nested_obj(obj, elements) + + +def parse_path(path, root_element=DEFAULT_FIRST_ELEMENT, include_actions=False): + """ + Parse a path to a format that is machine readable + + **Parameters** + + path : A string + The path string such as "root[1][2]['age']" + + root_element: string, default='root' + What the root is called in the path. + + include_actions: boolean, default=False + If True, we return the action required to retrieve the item at each element of the path. + + **Examples** + + >>> from deepdiff import parse_path + >>> parse_path("root[1][2]['age']") + [1, 2, 'age'] + >>> parse_path("root[1][2]['age']", include_actions=True) + [{'element': 1, 'action': 'GET'}, {'element': 2, 'action': 'GET'}, {'element': 'age', 'action': 'GET'}] + >>> + >>> parse_path("root['joe'].age") + ['joe', 'age'] + >>> parse_path("root['joe'].age", include_actions=True) + [{'element': 'joe', 'action': 'GET'}, {'element': 'age', 'action': 'GETATTR'}] + + """ + + result = _path_to_elements(path, root_element=root_element) + result = iter(result) + next(result) # We don't want the root item + if include_actions is False: + return [i[0] for i in result] + return [{'element': i[0], 'action': i[1]} for i in result] diff --git a/docs/conf.py b/docs/conf.py index b8f4ee49..ff6a46d3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -61,9 +61,9 @@ # built documents. # # The short X.Y version. -version = '6.4.1' +version = '6.5.0' # The full version, including alpha/beta/rc tags. -release = '6.4.1' +release = '6.5.0' load_dotenv(override=True) DOC_VERSION = os.environ.get('DOC_VERSION', version) diff --git a/docs/faq.rst b/docs/faq.rst index cdd89a2f..0a63be85 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -88,4 +88,23 @@ In order to serialize DeepDiff results into json, use to_json() >>> diff.to_json() '{"type_changes": {"root": {"old_type": "int", "new_type": "str", "old_value": 1, "new_value": "a"}}}' + +Q: How do I parse DeepDiff result paths? +---------------------------------------- + +**Answer** + +Use parse_path: + + >>> from deepdiff import parse_path + >>> parse_path("root[1][2]['age']") + [1, 2, 'age'] + >>> parse_path("root[1][2]['age']", include_actions=True) + [{'element': 1, 'action': 'GET'}, {'element': 2, 'action': 'GET'}, {'element': 'age', 'action': 'GET'}] + >>> + >>> parse_path("root['joe'].age") + ['joe', 'age'] + >>> parse_path("root['joe'].age", include_actions=True) + [{'element': 'joe', 'action': 'GET'}, {'element': 'age', 'action': 'GETATTR'}] + Back to :doc:`/index` diff --git a/docs/index.rst b/docs/index.rst index a048ba7b..37486141 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ contain the root `toctree` directive. -DeepDiff 6.4.1 documentation! +DeepDiff 6.5.0 documentation! ============================= ******* diff --git a/setup.cfg b/setup.cfg index 0297900b..ac1829e9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 6.4.1 +current_version = 6.5.0 commit = True tag = True tag_name = {new_version} diff --git a/setup.py b/setup.py index d41765c9..3c1af24d 100755 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ if os.environ.get('USER', '') == 'vagrant': del os.link -version = '6.4.1' +version = '6.5.0' def get_reqs(filename): diff --git a/tests/test_path.py b/tests/test_path.py index b4883d17..ee65963d 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -1,5 +1,5 @@ import pytest -from deepdiff.path import _path_to_elements, GET, GETATTR, extract +from deepdiff.path import _path_to_elements, GET, GETATTR, extract, parse_path @pytest.mark.parametrize('path, expected', [ @@ -32,3 +32,14 @@ def test_path_to_elements(path, expected): def test_get_item(obj, path, expected): result = extract(obj, path) assert expected == result + + +def test_parse_path(): + result = parse_path("root[1][2]['age']") + assert [1, 2, 'age'] == result + result2 = parse_path("root[1][2]['age']", include_actions=True) + assert [{'element': 1, 'action': 'GET'}, {'element': 2, 'action': 'GET'}, {'element': 'age', 'action': 'GET'}] == result2 + result3 = parse_path("root['joe'].age") + assert ['joe', 'age'] == result3 + result4 = parse_path("root['joe'].age", include_actions=True) + assert [{'element': 'joe', 'action': 'GET'}, {'element': 'age', 'action': 'GETATTR'}] == result4