Using dissect patterns in Pydantic models

You can use dissect patterns as fields in Pydantic models directly, by annotating a field with Pattern:

from __future__ import annotations

from pydantic import BaseModel

from dissec.patterns import Pattern


class MyModel(BaseModel):
    """My model including a pattern."""

    my_pattern: Pattern
    """Pattern included with the model."""


obj = MyModel(my_pattern="%{hello} - %{world}")
print(obj.model_dump_json())

The above script displays the following in the console:

{"my_pattern":"%{hello} - %{world}"}

This setup has the advantage of validating the pattern in the provided fields, and yielding exceptions in case of invalid patterns. For example:

from __future__ import annotations

from pydantic import BaseModel

from dissec.patterns import Pattern


class MyModel(BaseModel):
    """My model including a pattern."""

    fst: Pattern
    snd: Pattern
    thd: Pattern


MyModel(fst="hello, world", snd="%{*my_field}", thd="%{+}")

This script displays the following in the console:

Traceback (most recent call last):
  ...
pydantic_core._pydantic_core.ValidationError: 3 validation errors for MyModel
fst
  Value error, Unable to find any keys or delimiters. [type=value_error, input_value='hello, world', input_type=str]
    For further information visit https://errors.pydantic.dev/2.9/v/value_error
snd
  Value error, Found invalid key/reference associations: my_field. Please ensure each '*<key>' is matched with a matching '&<key>'. [type=value_error, input_value='%{*my_field}', input_type=str]
    For further information visit https://errors.pydantic.dev/2.9/v/value_error
thd
  Value error, At line 1, column 1: key name could not be determined. [type=value_error, input_value='%{+}', input_type=str]
    For further information visit https://errors.pydantic.dev/2.9/v/value_error