Skip to content

Commit

Permalink
Adding parse_path
Browse files Browse the repository at this point in the history
  • Loading branch information
seperman committed Sep 12, 2023
1 parent 888ca77 commit 58d4859
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
2 changes: 1 addition & 1 deletion deepdiff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
38 changes: 38 additions & 0 deletions deepdiff/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
19 changes: 19 additions & 0 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`
13 changes: 12 additions & 1 deletion tests/test_path.py
Original file line number Diff line number Diff line change
@@ -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', [
Expand Down Expand Up @@ -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

0 comments on commit 58d4859

Please sign in to comment.