fix: access discriminator field on BaseModel instance using key (#3847)

When validating a discriminated union where the union value has been
passed as a Pydantic model instance, we should access the discriminator
field value using the field name and not the field alias (whether one is
set or not).
This commit is contained in:
Charlie Hornsby
2022-08-08 16:43:23 +03:00
committed by GitHub
parent e92f12efac
commit cd439a4e8d
3 changed files with 20 additions and 1 deletions
+1
View File
@@ -0,0 +1 @@
Fix validation of discriminated union fields with an alias when passing a model instance
+1 -1
View File
@@ -1105,7 +1105,7 @@ class ModelField(Representation):
except TypeError:
try:
# BaseModel or dataclass
discriminator_value = getattr(v, self.discriminator_alias)
discriminator_value = getattr(v, self.discriminator_key)
except (AttributeError, TypeError):
return v, ErrorWrapper(MissingDiscriminator(discriminator_key=self.discriminator_key), loc)
+18
View File
@@ -267,6 +267,24 @@ def test_discriminated_union_basemodel_instance_value():
assert isinstance(t, Top)
def test_discriminated_union_basemodel_instance_value_with_alias():
class A(BaseModel):
literal: Literal['a'] = Field(alias='lit')
class B(BaseModel):
literal: Literal['b'] = Field(alias='lit')
class Config:
allow_population_by_field_name = True
class Top(BaseModel):
sub: Union[A, B] = Field(..., discriminator='literal')
assert Top(sub=A(lit='a')).sub.literal == 'a'
assert Top(sub=B(lit='b')).sub.literal == 'b'
assert Top(sub=B(literal='b')).sub.literal == 'b'
def test_discriminated_union_int():
class A(BaseModel):
l: Literal[1]