You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
is_chain_type, or the model-field path that bypasses it, accepts an annotation. The storage layer then cannot honour it, and the failure surfaces somewhere else — at write, at read, or only after a reload in a fresh process. Nothing checks that validation and storage agree about what is supported.
is_chain_type rejects an enum at the root, so output={"k": Species} and a top-level dict[Species, int] raise UdfSignatureError — while the same enum works as a model field. The same disagreement pointing the other way.
This list is very likely incomplete
That is the main reason for one ticket rather than eight.
Every instance was found one at a time, over four review rounds, and in three of those the newly-found case was one a previous fix had introduced. Each was discovered because somebody named a specific spelling — Key[str], Literal[1] | bool, type A0[T] = A1[T], a model defining __value__. None came from a systematic sweep, because there isn't one.
The surface is combinatorial: Annotated, NewType, PEP-695 aliases (bare, subscripted, defaulted, recursive), Literal (string, numeric, enum-valued, mixed), enums (str-mixin, int-mixin, plain, mixed-value), unions and Optional around any of those, nested in list/dict/tuple/a model, in key or value position, across four read routes and the write path.
Assume more instances exist. A change that ticks only the boxes above should be treated as incomplete.
What would actually close this
Not another round of point fixes:
one authority on "can this annotation be stored", consulted by is_chain_typeand by model-field validation, so the two cannot drift;
a round-trip property test over generated annotations — declare, write, read by every route, reload in a fresh process, compare. This is the only thing that finds the cases nobody has thought to name, and it is the part that matters most;
for anything storage cannot honour, rejection at schema-build time naming the field, instead of a TypeError from the SQL layer or a silent degradation to Any.
A ~12-line detector was prototyped that catches every exotic annotation above (28 cases, no false positives on anything we want to keep), if loud rejection is the preferred direction.
Umbrella for the validation/storage contract. Consolidates #1917, #1920, #1921, #1923, #1927, #1933, #1934 and #1935.
is_chain_type, or the model-field path that bypasses it, accepts an annotation. The storage layer then cannot honour it, and the failure surfaces somewhere else — at write, at read, or only after a reload in a fresh process. Nothing checks that validation and storage agree about what is supported.Use cases
Accepted, then the write fails
bytesinside a concretelist/dict— element, key or value, including nested (was is_chain_type accepts bytes inside concrete list/dict trees, but writing them fails #1921)list,typing.List,Sequence—TypeError/IndexErrorfrom the SQL layer, viaoutput=and via model fields, which never consultis_chain_type(was Unparameterized sequence annotations pass validation but fail in the SQL layer #1923)list[Enum]— likely fixed by Map enum signals by member value type instead of builtin str #1929; recheck when it lands (was list[Enum] model fields pass validation but fail to write #1934)Iterable[T]model fields — pydantic leaves aValidatorIteratorin the field, which the write refuses. Generic toT, not File-specific (was Iterable model fields fail to store; Iterable[File] setup values also miss catalog attachment #1920)dict[str, bytes]and other bytes-in-container shapesAccepted, then the read is wrong or impossible
Literalkeys with non-string members cannot be read back through the whole-model route at all (was Literal keys with non-string members cannot be read back through the whole-model route #1933)Iterable[File]setup values get no catalog, so the files are unreadable (was Iterable model fields fail to store; Iterable[File] setup values also miss catalog attachment #1920)Accepted, then it vanishes
Literal, enum and parameterised-alias specialisations are dropped from the persisted schema, so a clean-process reload degrades them toAny(was Literal, enum and parameterised-alias annotations do not survive a clean-process schema reload #1935)Accepted nowhere, though storage could manage it
is_chain_typerejects an enum at the root, sooutput={"k": Species}and a top-leveldict[Species, int]raiseUdfSignatureError— while the same enum works as a model field. The same disagreement pointing the other way.This list is very likely incomplete
That is the main reason for one ticket rather than eight.
Every instance was found one at a time, over four review rounds, and in three of those the newly-found case was one a previous fix had introduced. Each was discovered because somebody named a specific spelling —
Key[str],Literal[1] | bool,type A0[T] = A1[T], a model defining__value__. None came from a systematic sweep, because there isn't one.The surface is combinatorial:
Annotated,NewType, PEP-695 aliases (bare, subscripted, defaulted, recursive),Literal(string, numeric, enum-valued, mixed), enums (str-mixin,int-mixin, plain, mixed-value), unions andOptionalaround any of those, nested inlist/dict/tuple/a model, in key or value position, across four read routes and the write path.Assume more instances exist. A change that ticks only the boxes above should be treated as incomplete.
What would actually close this
Not another round of point fixes:
is_chain_typeand by model-field validation, so the two cannot drift;TypeErrorfrom the SQL layer or a silent degradation toAny.A ~12-line detector was prototyped that catches every exotic annotation above (28 cases, no false positives on anything we want to keep), if loud rejection is the preferred direction.
Related
🤖 AI-assisted (Claude Code) — verify before relying on it.