Summary
9.0 makes format_kind / format_kinds open strings everywhere and offers is_canonical_format_kind() for callers that need to be strict. That works, but a seller that serves only specific spec versions (where canonical_format_kind is a closed enum) has to restore the check on every inheriting model by hand.
The Embedded Sales Agent serves AdCP 3.1 and 3.2 and must refuse unknown kinds at the boundary. On 9.0.0b1 it needed a mixin with field_validator("format_kind", "format_kinds", check_fields=False) on seven subclasses: CreativeAsset, Creative, Package, PackageRequest, AffectedPackage, Format and ProductFilters. Missing one silently accepts free-form kinds on that path.
Ask
Ship the strict variant alongside the open one, for example:
- an
Annotated type (CanonicalFormatKindStr, optionally parameterized by vocabulary) adopters can use when they redeclare a field, and/or
- a mixin or validator factory (
require_canonical_format_kind(vocabulary=CanonicalFormatKind)) that applies to both field names and to lists.
That would answer the "where does the producer-side constraint belong" question from #1140 with a supported one-liner.
Summary
9.0 makes
format_kind/format_kindsopen strings everywhere and offersis_canonical_format_kind()for callers that need to be strict. That works, but a seller that serves only specific spec versions (wherecanonical_format_kindis a closed enum) has to restore the check on every inheriting model by hand.The Embedded Sales Agent serves AdCP 3.1 and 3.2 and must refuse unknown kinds at the boundary. On 9.0.0b1 it needed a mixin with
field_validator("format_kind", "format_kinds", check_fields=False)on seven subclasses:CreativeAsset,Creative,Package,PackageRequest,AffectedPackage,FormatandProductFilters. Missing one silently accepts free-form kinds on that path.Ask
Ship the strict variant alongside the open one, for example:
Annotatedtype (CanonicalFormatKindStr, optionally parameterized by vocabulary) adopters can use when they redeclare a field, and/orrequire_canonical_format_kind(vocabulary=CanonicalFormatKind)) that applies to both field names and to lists.That would answer the "where does the producer-side constraint belong" question from #1140 with a supported one-liner.