Validation

ValidationPipeline

class formatparse.ValidationPipeline[source]

Ordered registry of per-field validators and whole-result hooks (issue #11).

Build with add_validator() and/or add_hook(), then apply() on a ParseResult. Per-field keys follow apply_validators() (str for named fields, int for fixed indices). If the same field is registered twice, the last registration wins. Hooks run in registration order after the per-field validator pass completes (on success, or in lenient mode after every field validator has been attempted).

Async validators and inline {...:validator(...)} syntax remain deferred (see issue #11).

__init__()[source]
add_validator(field, fn)[source]

Register fn for field; returns self for chaining.

Return type:

ValidationPipeline

add_hook(fn)[source]

Register a whole-result hook; runs after per-field validators. Chainable.

Return type:

ValidationPipeline

as_mapping()[source]

Last registration per field wins (dict built in add_validator order).

Return type:

Dict[Union[str, int], Callable[..., Any]]

apply(result, *, mode='strict')[source]

Run per-field validators, then registered hooks.

If result is None, returns None immediately (no validators or hooks).

Hooks receive the full ParseResult and use the same raise-based contract as apply_validators(). Failures are ValidationError (field preserved when the raised error had one; otherwise None for generic hook failures). Other exceptions become ValidationError with field=None.

mode matches apply_validators(): strict stops on the first failure (field or hook). collect runs all per-field validators and all hooks, then raises a single MultipleValidationErrors listing field failures first (same key order as apply_validators()), then hook failures in hook registration order. lenient runs all field validators (warning on each failure), then all hooks (warning on each failure), and returns result without raising validation exceptions.

Return type:

Optional[ParseResult]

apply_validators

formatparse.apply_validators(result, validators, *, mode='strict')[source]

Run post-parse validators on named / fixed values.

Validators are raise-based: on success the callable returns (typically None). On failure raise ValidationError (recommended) or any exception (wrapped in ValidationError). Replacing values in fixed slots is not supported; use named fields or mutate result.named yourself after validation if you need coercion.

Parameters:
  • result (Optional[ParseResult]) – Output of parse() / FormatParser.parse(), or None.

  • validators (Optional[Mapping[Union[str, int], Callable[..., Any]]]) – Map from field key to validator. Keys are str field names for ParseResult.named or int indices for ParseResult.fixed.

  • mode (Literal['strict', 'collect', 'lenient']) – "strict" — stop on first error. "collect" — run all validators, then raise MultipleValidationErrors if any failed. "lenient" — run all validators, emit ValidationWarning for each failure, and always return result.

Return type:

Optional[ParseResult]

Returns:

The same result reference after validation (including lenient runs with failures).

Raises:

validator

formatparse.validator(func)[source]

Mark a function as a post-parse validator (metadata for tooling / docs).

Validators are invoked with the parsed value for one field; they should raise ValidationError on failure or return normally on success.

Parameters:

func (Callable[..., Any]) – Callable taking the parsed value (and optional extra args if you wrap it yourself before passing to apply_validators()).

Return type:

Callable[..., Any]

Built-in validators

formatparse.in_range(min_value=None, max_value=None)[source]

Return a validator that accepts numeric value within [min_value, max_value].

Return type:

Callable[[Union[int, float]], None]

formatparse.non_empty_str(value)[source]

Reject None, non-strings, or blank/whitespace-only strings.

Return type:

None

formatparse.is_valid_email(value)[source]

Reject values that are not plausible user@domain mailbox strings.

Uses a simple ASCII pattern suitable for post-parse validation only. It does not implement full RFC 5322 (no quoted-string local parts, no comments) and is not a deliverability or security check.

Raises:

ValidationError – If value is not a non-empty string matching the pattern.

Return type:

None

formatparse.is_valid_url(value)[source]

Reject values that are not http or https URLs with a non-empty host.

Uses urllib.parse.urlparse(). This does not verify reachability, TLS, or that the resource exists.

Raises:

ValidationError – If the string is empty, the scheme is not http/https, or the parsed URL has no network location (host).

Return type:

None

Type aliases

formatparse.ValidationMode

alias of Literal[‘strict’, ‘collect’, ‘lenient’]

formatparse.ValidatorMap

alias of Mapping[str | int, Callable[[…], Any]]