CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-dpath

Filesystem-like pathing and searching for dictionaries

Pending
Overview
Eval results
Files

path-access.mddocs/

Path Access Operations

Core functions for getting and setting values at specific paths in nested dictionaries. These operations support both exact paths and glob patterns, with robust handling of missing keys and type coercion.

Capabilities

Getting Values

Retrieve single values from nested dictionaries using path notation with support for default values and error handling.

def get(obj, glob, separator="/", default=_DEFAULT_SENTINEL):
    """
    Get single value matching glob pattern.
    
    Parameters:
    - obj (MutableMapping): Target dictionary to search
    - glob (Glob): Path pattern as string or sequence of path segments
    - separator (str): Path separator character (default "/")
    - default (Any): Default value if not found (raises KeyError if not provided)
    
    Returns:
    Any: The matched value
    
    Raises:
    - KeyError: If glob not found and no default provided
    - ValueError: If glob matches multiple values
    """

Usage Examples

import dpath

data = {
    "users": {
        "john": {"age": 30, "profile": {"city": "NYC"}},
        "jane": {"age": 25, "profile": {"city": "LA"}}
    }
}

# Get exact path
age = dpath.get(data, "users/john/age")  # Returns: 30

# Get with default value
phone = dpath.get(data, "users/john/phone", default="N/A")  # Returns: "N/A"

# Get root object
root = dpath.get(data, "/")  # Returns: entire data dict

# Use list-based paths (useful for keys containing separators)
city = dpath.get(data, ["users", "john", "profile", "city"])  # Returns: "NYC"

# Custom separator
dpath.get(data, "users.john.age", separator=".")  # Returns: 30

Creating New Paths

Create new paths in dictionaries, automatically generating missing intermediate dictionaries or lists as needed.

def new(obj, path, value, separator="/", creator=None):
    """
    Create new path and set value, creating missing intermediate keys.
    
    Parameters:
    - obj (MutableMapping): Target dictionary to modify
    - path (Path): Path as string or sequence (NOT treated as glob)
    - value (Any): Value to set at the path
    - separator (str): Path separator character (default "/")
    - creator (Creator): Optional function to create missing path components
    
    Returns:
    MutableMapping: The modified input object
    
    Note:
    Path is treated literally - globbing characters become part of key names.
    """

Usage Examples

import dpath

data = {}

# Create nested structure automatically
dpath.new(data, "config/database/host", "localhost")
# Result: {'config': {'database': {'host': 'localhost'}}}

# Create with numeric keys (creates lists)
dpath.new(data, "items/0/name", "first item")
# Result: {'items': [{'name': 'first item'}]}

# Mix of dict and list creation
dpath.new(data, "users/0/contacts/email", "john@example.com")
# Result: {'users': [{'contacts': {'email': 'john@example.com'}}]}

# Custom creator function
def list_creator(current, segments, i, hints=()):
    """Always create lists instead of dicts"""
    segment = segments[i]
    current[segment] = []

dpath.new(data, "always_list/key", "value", creator=list_creator)

# Globbing characters become literal keys
dpath.new(data, "weird/*/key", "value")  # Creates key literally named "*"

Setting Existing Values

Update values at paths that already exist, with support for glob patterns to update multiple locations simultaneously.

def set(obj, glob, value, separator="/", afilter=None):
    """
    Set value for all existing elements matching glob.
    
    Parameters:
    - obj (MutableMapping): Target dictionary to modify
    - glob (Glob): Path pattern as string or sequence
    - value (Any): Value to set at matching paths
    - separator (str): Path separator character (default "/")
    - afilter (Filter): Optional function to filter which values to set
    
    Returns:
    int: Number of elements changed
    
    Note:
    Only modifies existing paths - does not create new ones.
    """

Usage Examples

import dpath

data = {
    "users": {
        "john": {"age": 30, "active": True},
        "jane": {"age": 25, "active": False},
        "bob": {"age": 35, "active": True}
    }
}

# Set all user ages to same value
count = dpath.set(data, "users/*/age", 999)  # Returns: 3
# Result: All users now have age 999

# Set with filter - only update active users
def active_filter(value):
    return isinstance(value, dict) and value.get("active", False)

# First search for active users, then update their ages  
count = dpath.set(data, "users/*", {"age": 100, "active": True}, 
                  afilter=lambda user: user.get("active", False))

# Set single exact path
count = dpath.set(data, "users/john/age", 31)  # Returns: 1

# Use custom separator
count = dpath.set(data, "users.*.active", False, separator=".")

# Returns 0 if no existing paths match
count = dpath.set(data, "nonexistent/*/field", "value")  # Returns: 0

Path Format Support

All path access functions support multiple path formats:

String Paths

  • "users/john/age" - Standard slash-separated paths
  • "users.john.age" - Custom separator paths
  • "users/*/age" - Glob patterns with wildcards
  • "users/**/age" - Recursive glob patterns

List Paths

  • ["users", "john", "age"] - Explicit path segments (separator ignored)
  • ["users", "*", "age"] - Glob patterns in list format
  • Useful when keys contain separator characters

Numeric Indices

  • String indices: "items/0/name" - Automatically converted to int for sequences
  • Integer indices: ["items", 0, "name"] - Direct integer access
  • Negative indices: ["items", -1, "name"] - Supported for sequences

Error Handling

# KeyError for missing paths without default
try:
    value = dpath.get(data, "missing/path")
except KeyError as e:
    print(f"Path not found: {e}")

# ValueError for ambiguous gets
try:
    value = dpath.get(data, "users/*/age")  # Multiple matches
except ValueError as e:
    print(f"Ambiguous path: {e}")

# PathNotFound from dpath.exceptions
from dpath.exceptions import PathNotFound
try:
    # Some operations may raise PathNotFound instead of KeyError
    pass
except PathNotFound as e:
    print(f"Path operation failed: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-dpath

docs

advanced-operations.md

data-manipulation.md

index.md

path-access.md

search-operations.md

tile.json