You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
check_values and check_keys config options no longer accept "auto" — the smart early-exit behavior is now always active when the option is True (default). The accepted values are simply True (default, with early exit when no constraints apply) and False (bypass entirely). Documentation and docstrings updated accordingly.
0.4.7
Changed
require_all config option now accepts "never" | "at_init" | "always" instead of bool. Default changed from False to "at_init": annotated fields without a default are now required at construction time but remain freely deletable afterwards. True/False still accepted for backward compat.
modict.field(required=...) follows the same three-level scale. The stronger constraint between field-level required and config-level require_all always wins.
Fixed
Deletion of declared fields is now only blocked when the effective required level is "always" — "at_init" fields can be freely removed after construction.
0.4.6
Added
QUICKSTART.md: a narrative, example-driven introduction to modict for new users
Changed
README intro rewritten for clarity and conciseness: tighter positioning, cleaner "Why modict" paragraph, richer use-case descriptions
Development section now includes full local setup instructions
Fixed
Protocol compatibility hardened on older Python versions (3.10/3.11)
Cross-version typing and JSONPath compatibility fixes
0.4.5
Added
A dedicated benchmarks/ directory with sequential runners for typechecker, modict core, path_utils, and collections_utils
Changed
typechecker and coercer now cache compiled hint/coercion plans more aggressively, with additional fast paths for trivial scalar/runtime checks
modict hot paths (__setitem__, update(), computed invalidation, key/value pipeline guards) were tightened to avoid repeated no-op work and repeated structural scans
path_utils now caches parsed JSONPath strings, making repeated path-based operations dramatically cheaper
collections_utils traversal and reconstruction paths (walk, unwalk, diff_nested, set_nested) now rely on lighter internal path/container handling for better deep-op throughput
Fixed
Runtime container helper fast paths now still respect explicit excluded=... overrides
Tests
Added regression coverage around performance-sensitive copy/translate/computed bookkeeping paths and the newer typechecker fast paths
0.4.4
Added
modict.attr(...) / Attribute for explicit runtime/class metadata that stays outside the payload instead of being collected as a field
modict.wrap(...) / __wrap_init__() for advanced constructor-time business context without polluting the native dict-like constructor signature
A new examples/ directory with practical end-to-end scripts covering webhook payloads, config rollouts, SDK object adaptation, redaction/export flows, and a React-like UI component tree
Changed
wrap(...) now resolves a single __wrap_init__ entry point on the target class; inheritance-time parameter routing is explicit inside user overrides instead of being inferred across the MRO
The root modict package now keeps a tighter convenience surface focused on the main entry points; advanced descriptor/config/runtime classes stay exposed from their dedicated submodules
The README now starts every Python snippet from explicit imports, routes readers more clearly toward submodule READMEs from the package tour, and keeps advanced payload/runtime patterns later in the narrative
Computed semantics are documented more explicitly: class-declared computeds participate in the model contract, while dynamic instance computeds remain runtime values unless they target an already-declared field
Fixed
Runtime attrs declared with modict.attr(...) now bypass field collection reliably, remain available through inheritance, and can be overridden or cleared on instances without conflicting with declared field names
wrap(...) behavior is now aligned between implementation, documentation, and tests for inheritance-heavy use cases
Tests
Added regression coverage for runtime attrs, wrapped construction, explicit wrap-parameter routing in inheritance scenarios, dynamic computed typing semantics, and the narrowed root public API
0.4.3
Fixed
clear() now respects frozen=True and computed-field protection invariants
Replacing a computed field now invalidates dependant computed caches consistently, and after model validators no longer bypass assignment/key policies
Config.copy() / Config.merge() now isolate mutable config payloads such as json_encoders
reset_global_typechecker() now resets the global coercer too, keeping the public helper singletons in sync
Path.__radd__() now treats str / int as single path keys, and PathNode reports stable errors for invalid containers
walk() is now cycle-safe, and deep_merge() no longer treats str / bytes / bytearray as mergeable deep sequences
modict.__or__() now works correctly on frozen instances without mutating the source object
convert() / unconvert() now handle self-referential structures safely while preserving the intended in-place container semantics
coerce() now handles PEP 604 optionals like int | None, and hostile iterables/mappings now fail with CoercionError instead of leaking raw runtime exceptions
Changed
Validator and model-validator signature errors are now detected at registration time, while runtime TypeErrors raised inside validator bodies are preserved as-is
Documentation now explicitly reflects the accepted relative Path(...) string forms
Tests
Expanded regression and edge-case coverage across core, path_utils, collections_utils, model_api, and typechecker, including cycles, alias preservation, hostile coercion inputs, and from_attributes failure modes
0.4.2
Removed
rename() from the public API; in-place key renaming was a poor fit for typed/model-like modicts and could break expected key structure
Added
translate() to return a plain modict with translated keys, intended for payload/header/schema projection without mutating the source object
Path ergonomics improvements: tuple(path) iteration on keys, readable repr(path), non-mutating with_root(), and relationship helpers starts_with(), is_ancestor_of(), relative_to()
unwalk(..., kind_resolver=...) and modict.unwalk(..., kind_resolver=...) to refine inferred mapping / sequence structure per container path
Changed
set_nested() is now strict by default: missing intermediate containers raise unless create_missing=True is passed explicitly
set_nested(..., create_missing=True) now uses a container_factory(path) hook instead of implicit container invention
unwalk() now reconstructs structural dict / list containers via an internal tree build/materialization pass instead of replaying every path through repeated nested writes
modict.unwalk() continues to recast the root mapping through the target class so model validation/coercion can re-establish the desired root type safely
Path no longer exposes a .keys property; the public sequence API is now tuple(path) / iteration on keys
ignore_types on unwalk() is now a legacy compatibility mode; structure selection is driven by the default or custom kind_resolver
repr(modict) now renders computed fields as Computed(current_value) instead of hiding their derived nature in console output
0.4.1
Added
GitHub Actions test workflow covering Python 3.10 through 3.14
Additional regression coverage for typechecker runtime semantics, recursion safety, and permissive interface-only checks
Changed
typechecker documentation now distinguishes strictly checked constructs from intentionally permissive runtime-only checks
Contribution guide now includes the focused typechecker test command and CI expectations
Fixed
Hardened typechecker and coercer around Callable[...] variance, Protocol member checking, TypedDict with Required[...] / NotRequired[...], type[T], explicit ForwardRef, and modern TypeAliasType
Recursive aliases and cyclic values now fail safely during coercion instead of recursing indefinitely
Remaining French comments/docstrings in the typechecker public surface were translated to English