Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitddb1a68

Browse files
authored
Allow callable discriminator to be applied on PEP 695 type aliases (#11941)
1 parent565cea9 commitddb1a68

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

‎pydantic/types.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,9 +3069,11 @@ def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaH
30693069
returnhandler(Annotated[source_type,Field(discriminator=self.discriminator)])
30703070
else:
30713071
original_schema=handler(source_type)
3072-
returnself._convert_schema(original_schema)
3072+
returnself._convert_schema(original_schema,handler)
30733073

3074-
def_convert_schema(self,original_schema:core_schema.CoreSchema)->core_schema.TaggedUnionSchema:
3074+
def_convert_schema(
3075+
self,original_schema:core_schema.CoreSchema,handler:GetCoreSchemaHandler|None=None
3076+
)->core_schema.TaggedUnionSchema:
30753077
iforiginal_schema['type']!='union':
30763078
# This likely indicates that the schema was a single-item union that was simplified.
30773079
# In this case, we do the same thing we do in
@@ -3088,10 +3090,23 @@ def _convert_schema(self, original_schema: core_schema.CoreSchema) -> core_schem
30883090
ifmetadataisnotNone:
30893091
tag=metadata.get('pydantic_internal_union_tag_key')ortag
30903092
iftagisNone:
3091-
raisePydanticUserError(
3092-
f'`Tag` not provided for choice{choice} used with `Discriminator`',
3093-
code='callable-discriminator-no-tag',
3094-
)
3093+
# `handler` is None when this method is called from `apply_discriminator()` (deferred discriminators)
3094+
ifhandlerisnotNoneandchoice['type']=='definition-ref':
3095+
# If choice was built from a PEP 695 type alias, try to resolve the def:
3096+
try:
3097+
choice=handler.resolve_ref_schema(choice)
3098+
exceptLookupError:
3099+
pass
3100+
else:
3101+
metadata=cast('CoreMetadata | None',choice.get('metadata'))
3102+
ifmetadataisnotNone:
3103+
tag=metadata.get('pydantic_internal_union_tag_key')
3104+
3105+
iftagisNone:
3106+
raisePydanticUserError(
3107+
f'`Tag` not provided for choice{choice} used with `Discriminator`',
3108+
code='callable-discriminator-no-tag',
3109+
)
30953110
tagged_union_choices[tag]=choice
30963111

30973112
# Have to do these verbose checks to ensure falsy values ('' and {}) don't get ignored

‎tests/test_discriminated_union.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,34 @@ class Reference(BaseModel):
22032203
assertBase.__pydantic_core_schema__==base_schema
22042204

22052205

2206+
deftest_tagged_discriminator_type_alias()->None:
2207+
"""https://github.com/pydantic/pydantic/issues/11930"""
2208+
2209+
classPie(BaseModel):
2210+
pass
2211+
2212+
classApplePie(Pie):
2213+
fruit:Literal['apple']='apple'
2214+
2215+
classPumpkinPie(Pie):
2216+
filling:Literal['pumpkin']='pumpkin'
2217+
2218+
defget_discriminator_value(v):
2219+
returnv.get('fruit',v.get('filling'))
2220+
2221+
TaggedApplePie=TypeAliasType('TaggedApplePie',Annotated[ApplePie,Tag('apple')])
2222+
2223+
classThanksgivingDinner(BaseModel):
2224+
dessert:Annotated[
2225+
Union[TaggedApplePie,Annotated[PumpkinPie,Tag('pumpkin')]],
2226+
Discriminator(get_discriminator_value),
2227+
]
2228+
2229+
inst=ThanksgivingDinner(dessert={'fruit':'apple'})
2230+
2231+
assertisinstance(inst.dessert,ApplePie)
2232+
2233+
22062234
deftest_discriminated_union_type_alias_type()->None:
22072235
"""https://github.com/pydantic/pydantic/issues/11661
22082236

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp