Skip to content

References in unions should use discriminated unions #36

@nkrishnaswami

Description

@nkrishnaswami

Hello,
I'm seeing some references in Union[Reference, Schema] (parameter schema field, eg) being parsed as Schema despite having a $ref, when they have too many siblings from Schema, perhaps from Smart Mode's considering having more matching fields better. This seems to break the requirement here that siblings of a $ref be ignored. Perhaps in the future you could use a discriminated tagged union?
E.g.,

def is_reference(value) -> bool:
    if isinstance(value, dict):
        return "$ref" in value
    return hasattr(value, "ref")

def tag_ref_or_other(value) -> str:
    if is_reference(x):
        return "ref"
    return "other"

T = TypeVar[T]

ReferenceOr = Annotated[
    Union[Annotated["Reference", Tag("ref")],
          Annotated[T, Tag("other")]],
    Discriminator(tag_ref_or_other)]
...
class Parameter(BaseModel)
    ...
    param_schema: Optional[ReferenceOr[Schema]] = Field(default=None, alias="schema")

(There was only one case where there were more than one other thing in the Union with a Reference, Schema's additionalProperties, which can be handled with Union[bool, ReferenceOr['Schema'])

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions