SIGN IN SIGN UP

Embed __tname__ in models, support using it in model_validate (#918)

Gel supports inheritance much more than pydantic does, and so when we
have a link to a parent type, we need to be able to determine which of
its potential children type to create.

We do this by adding a `tname__` field to every generated class,
renamed to `__tname__` via the alias system, and update
`__gel_validate__` (which currently just directly calls
`model_validate`) to discriminate on it. The hard part here is
handling the case where there are linkprops, which are represented by
per-link subclasses of ProxyModel.  To deal with this, we dynamically
generate subclasses of the link class.

This mechanism also allows us to return correct types from the client
for links with link properties that point to subtypes, which we
previously weren't.

The other potential option was to use pydantic's discriminated unions,
either by directly generating them in the source or dynamically
mocking them up when creating models.  Getting this to play nicely
with everything we do seemed pretty nasty. (The linkprop situation in
particular scares me more.) The big potential advantage of doing it
that way, instead of having our own custom callbacks, is that it might
allow us to not lose track of the parameters of validation (like
strict mode and whether we are in JSON mode).

But it turns out we were already losing track of that due to
various ways we were interposing ourselves in validation, so
maybe it's fine. We can maybe fix this with contextvars later.
(Though the json situation is rough.)

Fixes #755.
M
Michael J. Sullivan committed
089d6dc2fd3adedbc63b357b85d2b6e46b02bdd8
Parent: 4b52b71
Committed by GitHub <noreply@github.com> on 9/23/2025, 3:59:50 PM