embody.util

Utility functions for embody: flattening, unflattening, and cycle detection.

This module provides helper functions for working with nested data structures, including path-based operations and cycle detection for safe traversal.

exception embody.util.CycleError[source]

Raised when a circular reference is detected in a data structure.

exception embody.util.PathNotFoundError[source]

Raised when a path doesn’t exist in a data structure.

embody.util.count_template_markers(obj: Any, syntax: str = 'dollar_brace') int[source]

Count the number of template markers in a nested structure.

Parameters:
  • obj – Object to count markers in

  • syntax – Template syntax to look for

Returns:

Number of template markers found

Examples

>>> count_template_markers({'a': '${x}', 'b': '${y}'})
2
>>> count_template_markers(['${a}', 'literal', '${b} and ${c}'])
3
embody.util.detect_cycle(obj: Any, visited: Set[int] = None, path: List[str] = None) None[source]

Detect cycles in a nested data structure.

Parameters:
  • obj – The object to check for cycles

  • visited – Set of object IDs already visited

  • path – Current path in the structure (for error reporting)

Raises:

CycleError – If a cycle is detected

Examples

>>> d = {'a': 1, 'b': [2, 3]}
>>> detect_cycle(d)  # No cycle, returns None
>>> circular = {'a': 1}
>>> circular['self'] = circular
>>> try:
...     detect_cycle(circular)
... except CycleError as e:
...     print("Cycle detected")
Cycle detected
embody.util.flatten_dict(nested_dict: Dict[str, Any], separator: str = '.', parent_key: str = '') Dict[str, Any][source]

Flatten a nested dictionary into a single-level dictionary with path keys.

Parameters:
  • nested_dict – Nested dictionary to flatten

  • separator – String to use for separating path components

  • parent_key – Key of the parent (used in recursion)

Returns:

Flattened dictionary with path keys

Examples

>>> d = {'a': {'b': {'c': 1}}, 'd': 2}
>>> flatten_dict(d)
{'a.b.c': 1, 'd': 2}
>>> d = {'user': {'name': 'Alice', 'age': 30}}
>>> flatten_dict(d)
{'user.name': 'Alice', 'user.age': 30}
>>> d = {'items': [1, 2, 3]}
>>> flatten_dict(d)
{'items.0': 1, 'items.1': 2, 'items.2': 3}
embody.util.flatten_to_tuples(obj: Any, parent_path: Tuple = ()) Dict[Tuple, Any][source]

Flatten a nested structure using tuple paths (unambiguous).

This avoids the ambiguity of string separators. A tuple path like (‘a’, ‘b’, 0) is unambiguous, while ‘a.b.0’ could mean multiple things if keys contain dots.

Parameters:
  • obj – Object to flatten

  • parent_path – Current path as tuple

Returns:

Dictionary mapping tuple paths to values

Examples

>>> d = {'a': {'b': [1, 2]}}
>>> flatten_to_tuples(d)
{('a', 'b', 0): 1, ('a', 'b', 1): 2}
embody.util.get_by_path(obj: Any, path: str | Tuple, separator: str = '.', default: Any = None) Any[source]

Get a value from a nested structure by path.

Parameters:
  • obj – Nested structure

  • path – Path as string or tuple

  • separator – Separator for string paths

  • default – Default value if path not found

Returns:

Value at the path, or default if not found

Examples

>>> d = {'a': {'b': {'c': 42}}}
>>> get_by_path(d, 'a.b.c')
42
>>> get_by_path(d, ('a', 'b', 'c'))
42
>>> get_by_path(d, 'a.b.x', default='not found')
'not found'
embody.util.max_depth(obj: Any, current_depth: int = 0) int[source]

Calculate the maximum depth of a nested structure.

Parameters:
  • obj – Object to measure

  • current_depth – Current depth (used in recursion)

Returns:

Maximum depth

Examples

>>> max_depth({'a': 1})
1
>>> max_depth({'a': {'b': {'c': 1}}})
3
>>> max_depth([1, [2, [3, 4]]])
3
embody.util.set_by_path(obj: Dict, path: str | Tuple, value: Any, separator: str = '.', create_intermediate: bool = True) None[source]

Set a value in a nested structure by path (modifies in place).

Parameters:
  • obj – Nested structure to modify

  • path – Path as string or tuple

  • value – Value to set

  • separator – Separator for string paths

  • create_intermediate – If True, create intermediate dicts/lists as needed

Examples

>>> d = {}
>>> set_by_path(d, 'a.b.c', 42)
>>> d
{'a': {'b': {'c': 42}}}
embody.util.unflatten_dict(flat_dict: Dict[str, Any], separator: str = '.') Dict[str, Any][source]

Unflatten a dictionary with path keys into a nested structure.

Parameters:
  • flat_dict – Flattened dictionary with path keys

  • separator – String used for separating path components

Returns:

Nested dictionary structure

Examples

>>> flat = {'a.b.c': 1, 'd': 2}
>>> unflatten_dict(flat)
{'a': {'b': {'c': 1}}, 'd': 2}
>>> flat = {'items.0': 'a', 'items.1': 'b'}
>>> unflatten_dict(flat)
{'items': ['a', 'b']}
embody.util.unflatten_from_tuples(flat_dict: Dict[Tuple, Any]) Any[source]

Unflatten a dictionary with tuple paths into a nested structure.

Parameters:

flat_dict – Dictionary with tuple paths as keys

Returns:

Nested structure (dict or list)

Examples

>>> flat = {('a', 'b', 0): 1, ('a', 'b', 1): 2}
>>> unflatten_from_tuples(flat)
{'a': {'b': [1, 2]}}