Module adcp.types.variants
Schema-variant marker for cross-class entity overrides (#710).
When an adopter subclasses an auto-generated response type and assigns
a shape-compatible-but-distinct entity class to a parent field, mypy
flags the override as a Liskov violation. SchemaVariant[T] marks
the override as intentional — at runtime it collapses to T (Pydantic
validates against the wrapped type); with :mod:adcp.types.mypy_plugin
active it rewrites to Any for override-compat purposes, retiring
the # type: ignore[assignment] adopters used to stamp::
class GetMediaBuyDeliveryResponse(LibraryGetMediaBuyDeliveryResponse):
media_buy_deliveries: SchemaVariant[list[MediaBuyDeliveryData]]
Inside the override the field's mypy type is Any; cast to recover
inference::
for d in cast(list[MediaBuyDeliveryData], self.media_buy_deliveries):
d.local_method()
Don't use SchemaVariant for subclass overrides — those already
type-check via Sequence[T] covariance (PR #635) and the marker
would obscure that the override is sub-typing, not substitution.
Pyright / Pylance: the bundled mypy plugin doesn't affect pyright.
Adopters using Pylance in VSCode will still see the LSP override
flagged on SchemaVariant[T] fields even though their mypy CI
passes. The runtime contract holds either way; this is purely an
editor-warning asymmetry. A pyright-side suppression mechanism is
tracked as a follow-up.
Classes
class SchemaVariant-
Expand source code
class SchemaVariant(metaclass=_SchemaVariantMeta): """Marker for intentional cross-class entity overrides — see module docstring."""Marker for intentional cross-class entity overrides — see module docstring.