Post-parse validation

After parse() or formatparse.FormatParser.parse(), you can run validators in several ways:

ValidationPipeline supports ordered per-field validators (add_validator()), whole-result hooks (add_hook()), and validation_mode of "strict", "collect", or "lenient". Field keys are field names (str) or fixed indices (int). In lenient mode, failures are reported with warnings.warn() and the parse result is still returned.

Built-ins in_range(), non_empty_str(), is_valid_email(), and is_valid_url() cover common checks. Email and URL checks are heuristic, not full RFC compliance or a security audit.

from formatparse import ValidationPipeline, parse, in_range

pipe = ValidationPipeline().add_validator("age", in_range(0, 150))
r = parse("{name} {age:d}", "Ada 42", pipeline=pipe)
assert r.named["age"] == 42

See Validation for the full API and issues #10, #11.