SyntaxUtils: Syntax Utilities#
- class my.utils.SyntaxUtils.SyntaxUtils#
Methods for syntax-y tasks (i.e. related to data’s form rather than its content).
I Normalization#
- classmethod SyntaxUtils.fill_tree(tree: dict[T, C]) None#
Recursively replace None values with empty dicts in a nested tree structure.
Modifies tree in-place.
- Parameters:
tree – Nested dictionary tree to fill.
Examples
Backfill empty leaves at any depth:
>>> from my import ut >>> tree = {'a': None, 'b': {'c': None}} >>> ut.fill_tree(tree) >>> tree {'a': {}, 'b': {'c': {}}}
- classmethod SyntaxUtils.tree_size(tree: object) int#
Calculate total number of leaf nodes in a nested tree structure.
- Parameters:
tree – Tree structure (dict of dicts, or leaf value).
- Returns:
Total count of leaf nodes (non-dict values).
Examples
Count the leaves, not the branches:
>>> from my import ut >>> ut.tree_size({'a': {'b': 1, 'c': 2}, 'd': 3}) 3
II Annotation#
- static SyntaxUtils.pyd_schemify(tvar: type) GetPydanticSchema#
Create Pydantic schema validator for instance type checking.
- Parameters:
tvar – Type to create validator for.
- Returns:
GetPydanticSchema validator for use with Annotated types.
Examples
Let a Pydantic model carry compiled patterns:
>>> from typing import Annotated >>> import pydantic, regex >>> from my import ut >>> class Cfg(pydantic.BaseModel): ... rgx: Annotated[regex.Pattern, ut.pyd_schemify(regex.Pattern)] >>> Cfg(rgx=regex.compile(r'\d+')).rgx.pattern '\\d+'
III Reflection#
- static SyntaxUtils.instance_fields(cls: type) dict[str, Any]#
Extract instance field names and annotations from a Pydantic model or typeddict.
- Parameters:
cls – Pydantic BaseModel class to inspect.
- Returns:
Dictionary mapping lowercase field names to their type annotations.
Examples
Inspect a model’s instance fields:
>>> import pydantic >>> from my import ut >>> class User(pydantic.BaseModel): ... name: str ... age: int = 0 >>> ut.instance_fields(User) {'name': <class 'str'>, 'age': <class 'int'>}
- SyntaxUtils.instance_aliases() dict[str, Any]#
Extract field aliases and types from a Pydantic model with caching.
Resolves field aliases including validation aliases and alias choices, converting AliasPath objects to string representations.
- Parameters:
cls – Pydantic BaseModel class to inspect.
- Returns:
Dictionary mapping field aliases to their type annotations.
Examples
Aliases replace raw field names where declared:
>>> import pydantic >>> from my import ut >>> class Row(pydantic.BaseModel): ... full_name: str = pydantic.Field(alias='fullName') >>> ut.instance_aliases(Row) {'fullName': <class 'str'>}
- classmethod SyntaxUtils.nested_replace(obj: Collection | BaseModel, old: Any, new: Any, depth: int = 0, max_depth: int = 10) bool#
Recursively search and replace a single value in nested data structures.
Supports sequences (list, tuple, deque, set), mappings (dict), and Pydantic models. Recursively traverses nested structures up to depth limit.
A tuple is immutable, so a value found directly among a tuple’s own elements cannot be replaced in place; that case reports
Falserather than a false success. Mutable containers (list, dict, model, …) nested inside a tuple are still replaced normally, since the tuple’s reference to them is untouched.- Parameters:
obj – Collection or Pydantic model to search within.
old – Value to find and replace.
new – Replacement value.
depth – Current recursion depth, up to a hard max of 100.
max_depth – Maximum recursion depth.
- Returns:
True if value was found and replaced, False otherwise.
Examples
Replace a value wherever it hides; immutable tuples report failure:
>>> from my import ut >>> data = {'a': [1, 2, {'b': 'old'}]} >>> ut.nested_replace(data, 'old', 'new') True >>> data {'a': [1, 2, {'b': 'new'}]} >>> ut.nested_replace(('x',), 'x', 'y') False
- static SyntaxUtils.import_module(file: Annotated[Path, PathType(path_type=file)], root: Annotated[Path, PathType(path_type=dir)]) ModuleType#
Dynamically import a Python module from a file path.
Converts file path to module dotted notation and imports it.
- Parameters:
file – Path to Python file to import.
root – Root directory for relative import path calculation.
- Returns:
Imported ModuleType object.
Examples
Import
src/pkg/mod.pyas the modulepkg.mod:>>> from pathlib import Path >>> from my import ut >>> ut.import_module(Path('src/pkg/mod.py'), Path('src')) <module 'pkg.mod' from 'src/pkg/mod.py'>
IV Caching#
- static SyntaxUtils.clear_cached_properties(inst: object, *properties: str) None#
Clear cached properties from an object instance.
If no properties specified, clears all properties listed in instance’s CACHED_PROPERTIES attribute.
- Parameters:
inst – Object instance to clear cached properties from.
*properties – Property names to clear. If empty, uses inst.CACHED_PROPERTIES.
Examples
Invalidate a
functools.cached_property:>>> import functools >>> from my import ut >>> class Report: ... @functools.cached_property ... def total(self): ... return sum(range(5)) >>> report = Report() >>> report.total 10 >>> ut.clear_cached_properties(report, 'total') >>> 'total' in report.__dict__ False