From 58d4859542cbad2cadbb293b434a9240bbee8341 Mon Sep 17 00:00:00 2001 From: Seperman Date: Mon, 11 Sep 2023 22:38:15 -0700 Subject: [PATCH] Adding parse_path --- deepdiff/__init__.py | 2 +- deepdiff/path.py | 38 ++++++++++++++++++++++++++++++++++++++ docs/faq.rst | 19 +++++++++++++++++++ tests/test_path.py | 13 ++++++++++++- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/deepdiff/__init__.py b/deepdiff/__init__.py index 1398f17f..f786dc97 100644 --- a/deepdiff/__init__.py +++ b/deepdiff/__init__.py @@ -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/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/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