(*, union: type, meta_annotations: tuple[Any, ...])
| 755 | |
| 756 | |
| 757 | def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None: |
| 758 | cached = DISCRIMINATOR_CACHE.get(union) |
| 759 | if cached is not None: |
| 760 | return cached |
| 761 | |
| 762 | discriminator_field_name: str | None = None |
| 763 | |
| 764 | for annotation in meta_annotations: |
| 765 | if isinstance(annotation, PropertyInfo) and annotation.discriminator is not None: |
| 766 | discriminator_field_name = annotation.discriminator |
| 767 | break |
| 768 | |
| 769 | if not discriminator_field_name: |
| 770 | return None |
| 771 | |
| 772 | mapping: dict[str, type] = {} |
| 773 | discriminator_alias: str | None = None |
| 774 | |
| 775 | for variant in get_args(union): |
| 776 | variant = strip_annotated_type(variant) |
| 777 | if is_basemodel_type(variant): |
| 778 | if PYDANTIC_V1: |
| 779 | field_info = cast("dict[str, FieldInfo]", variant.__fields__).get(discriminator_field_name) # pyright: ignore[reportDeprecated, reportUnnecessaryCast] |
| 780 | if not field_info: |
| 781 | continue |
| 782 | |
| 783 | # Note: if one variant defines an alias then they all should |
| 784 | discriminator_alias = field_info.alias |
| 785 | |
| 786 | if (annotation := getattr(field_info, "annotation", None)) and is_literal_type(annotation): |
| 787 | for entry in get_args(annotation): |
| 788 | if isinstance(entry, str): |
| 789 | mapping[entry] = variant |
| 790 | else: |
| 791 | field = _extract_field_schema_pv2(variant, discriminator_field_name) |
| 792 | if not field: |
| 793 | continue |
| 794 | |
| 795 | # Note: if one variant defines an alias then they all should |
| 796 | discriminator_alias = field.get("serialization_alias") |
| 797 | |
| 798 | field_schema = field["schema"] |
| 799 | |
| 800 | if field_schema["type"] == "literal": |
| 801 | for entry in cast("LiteralSchema", field_schema)["expected"]: |
| 802 | if isinstance(entry, str): |
| 803 | mapping[entry] = variant |
| 804 | |
| 805 | if not mapping: |
| 806 | return None |
| 807 | |
| 808 | details = DiscriminatorDetails( |
| 809 | mapping=mapping, |
| 810 | discriminator_field=discriminator_field_name, |
| 811 | discriminator_alias=discriminator_alias, |
| 812 | ) |
| 813 | DISCRIMINATOR_CACHE.setdefault(union, details) |
| 814 | return details |
no test coverage detected