Validation Kit¶
The Validation Kit is the rule-enforcement layer of django-mindoff. It provides a single validation surface (mo_validation_kit) used across runtime components to enforce conditions, classify failures, and return predictable error structures.
It is designed to support three execution styles from the same API: immediate native exceptions, framework-structured validation errors, and aggregated multi-error validation.
For endpoint-level validation authoring, refer to Developer Guide - Validations.
Validation Kit is not an isolated utility. It is part of core runtime behavior:
- API Kit uses it for request/config guards.
- Payload schema validation (
validate_schema) depends on aggregate mode. - Response Kit CSV loading uses it for dictionary contract checks.
- CRUD/Polars flows use it for operational guardrails.
- Queue/runtime exception normalization relies on
MindoffValidationErrorshape (code,message,data).
Core Runtime Components¶
| Component | Responsibility | Notes |
|---|---|---|
MindoffValidator |
Public validation surface and aggregate-state owner. | Exposed as singleton mo_validation_kit. |
MindoffValidationError |
Structured framework validation exception. | Carries message, code, category, data. |
ValidationError |
Generic fallback exception type. | Used by ensure(...) and aggregate exception mode. |
_ErrorItem |
Internal buffered error record for aggregate mode. | Stores function name, type, code, message, context, traceback. |
_record_or_raise(...) |
Central decision engine for pass/fail behavior. | Used by all validator methods. |
Validator Surface Map¶
Validation methods are grouped into consistent families.
Equality & Comparison¶
ensure_equalensure_not_equalensure_sameensure_not_sameensure_greaterensure_greater_equalensure_lesserensure_lesser_equalensure_in_rangeensure_not_in_rangeensure_almost_equalensure_not_almost_equal
Truthiness¶
ensure_falseyensure_truthy
Types & Class Relationships¶
ensure_typeensure_not_typeensure_subclassensure_not_subclass
Containers & Collection Semantics¶
ensure_inensure_not_inensure_count_equalensure_count_not_equal
Numeric / Regex / Filesystem¶
ensure_finiteensure_regexensure_not_regexensure_pathensure_not_path
Custom Predicate¶
ensure(boolean or callable checks; configurableexc_type)
Aggregate Lifecycle¶
finalizereset
Unified Execution Model¶
Every ensure_* method delegates failure handling to _record_or_raise(...).
Decision Flow¶
- Method computes
okand method-specific failure metadata (exc_type,message,context). - If
ok=True, returnsTrue. - If
ok=False, an_ErrorItemis created with traceback snapshot (mo_helper_kit.get_exact_traceback(skip=3)). - If
is_aggregate=True, error is buffered and method returnsNone. - Else if
is_exception=True, method-specific native exception is raised (with.codeattribute attached). - Else,
MindoffValidationErroris raised with structureddata.
Priority is intentional: aggregate mode takes precedence over immediate exception mode.
Error Contract Semantics¶
MindoffValidationError¶
Structured exception with runtime-friendly fields:
message(human-readable)code(defaultVALIDATION_ERR, customizable per call)category(defaultdanger)data(must bedictorlist)
If data is not dict|list, constructor raises TypeError.
Native Exception Mode¶
When is_exception=True, each validator raises its method-specific exception class (for example ValueError, TypeError, LookupError, KeyError, FileNotFoundError, FileExistsError, or custom exc_type for ensure).
Custom Code Propagation¶
All modes preserve caller-provided code:
- Attached to native raised exception as
.code - Included in
MindoffValidationError.code - Stored per buffered
_ErrorItemin aggregate mode
Aggregate Mode Architecture¶
Aggregate mode supports collecting multiple failures before emitting one result.
Buffering¶
- Any
ensure_*call withis_aggregate=Trueappends_ErrorItemto internal_errors. - Calls continue; no exception is raised at point of failure.
Finalization¶
finalize(...) drains _errors using return_mode:
list: returns list of normalized error dicts (type,code,message,context)error(default): raisesMindoffValidationErrorwith aggregatedataexception: raisesValidationErrorwith combined formatted text (includes traceback snapshots)
Reset Semantics¶
finalize(...) always resets internal aggregate state in finally, including when it raises.
reset() can also be called explicitly to clear state.
Method Family Behavior Details¶
Comparison Helpers¶
- Comparison operators are guarded; operator failures are treated as invalid comparisons and mapped to
TypeErrorpaths. ensure_equalhas iterable-aware comparison behavior for non-string/non-bytes/non-dict iterables by normalizing tolist(...)before comparison.
Type/Class Helpers¶
ensure_type/ensure_not_typeuseisinstance.ensure_subclass/ensure_not_subclasscatch invalid-subclass inputs and route them through failure paths (TypeErrorsemantics).
Membership Helpers¶
ensure_in/ensure_not_inuse membership checks.- Dict membership failures are keyed to
KeyError; non-dict containers useLookupError. - Non-iterable membership targets fall back to
TypeError.
Count Helpers¶
ensure_count_equal/ensure_count_not_equalusecollections.Counter.- Unhashable elements or broken iterables route to
TypeErrorpaths.
Numeric/Regex/Path Helpers¶
ensure_finiterequires numeric input andmath.isfinite.- Regex helpers require string input and use full-match semantics.
- Path helpers validate filesystem existence/non-existence via
pathlib.Path.exists().
Custom ensure(...)¶
- Accepts boolean or callable.
- Callable exceptions are captured and converted into failure state.
- Uses configurable
exc_type(defaultValidationError) whenis_exception=True.
Integration Across Runtime Layers¶
Validation Kit is embedded in multiple internal flows:
- API Kit: method checks, auth/payload limits, request guardrails.
- Schema Validation (
_helper_kit/validate_schema.py): runs aggregate checks across nested payload structures, then callsfinalize(code="INVALID_PAYLOAD"). - Response Kit: validates
responses.csvstructure and values during load. - CRUD/Polars flows: enforces operational preconditions (types, ranges, table/column assumptions).
- TDD Kit and tests: resets aggregate state between runs to avoid stale buffered errors.
Operational Caveats¶
mo_validation_kitis a singleton with mutable aggregate buffer (_errors); aggregate usage should be scoped carefully per execution path.- Forgetting to call
finalize(...)after aggregate checks means failures remain buffered and unreported for that flow. - Mixing aggregate and immediate-exception patterns in one branch can create unclear failure contracts.
- In aggregate mode,
is_exceptiondoes not trigger immediate raises; buffering behavior wins by design.
Troubleshooting the Kit¶
- Missing aggregate errors in output: ensure all aggregate checks are followed by
finalize(...). - Unexpected exception class: verify method-specific exception semantics and whether
is_exception=Truewas used. - Custom error code not visible: confirm code was passed to each failing check or to
finalize(...)(for top-level aggregate error mode). - Intermittent aggregate contamination: ensure
reset()/finalize()runs on every aggregate path, including early exits. - Schema validation output seems partial: check
validate_schema(...)mode/depth inputs and confirm aggregate errors are finalized.