Nesting and composition
Nested field patterns
When the substring after : in a field is a balanced nested brace pattern (for
example {outer:{inner:d}}), the inner pattern is compiled and matched as part of the
outer capture, then parsed again. Nested groups appear as ParseResult
objects under ParseResult.named. Maximum nesting depth when compiling is 10.
from formatparse import parse
r = parse("{outer:{inner:d}}", "42")
assert r.named["outer"].named["inner"] == 42
Brace-balanced scanning applies in the spec after :. Literal braces in the pattern
string still use {{ and }} for a single literal brace in pattern text.
Composition with composed_type
Use composed_type() to wrap a compiled FormatParser
and pass it in extra_types so one field is parsed by the child parser and returns a
nested ParseResult.
from formatparse import compile, composed_type
ts = compile("{year:d}-{month:02d}-{day:02d}")
log = compile(
"{ts:Timestamp} [{level}] {msg}",
extra_types={"Timestamp": composed_type(ts)},
)
r = log.parse("2024-01-15 [ERROR] oops")
inner = r.named["ts"]
assert inner.named["year"] == 2024
Pickling: a pickled FormatParser stores only the pattern string.
After pickle.loads, pass extra_types again when calling parse / search /
findall if your pattern uses custom types—including any composed child parsers.
See also Pattern Syntax (nested patterns section) and issues #7, #12.