-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Checks
- I added a descriptive title to this issue
- I have searched (google, github) for similar issues and couldn't find anything
- I have read and followed the docs and still think this is a bug
Bug
Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.9.0
pydantic compiled: False
install path: /home/tom/reinfer/env/lib/python3.8/site-packages/pydantic
python version: 3.8.10 (default, Nov 26 2021, 20:14:08) [GCC 9.3.0]
platform: Linux-5.11.0-44-generic-x86_64-with-glibc2.29
optional deps. installed: ['dotenv', 'typing-extensions']
When a Union with only a single variant it tagged with a field as a discriminated union, a type error is thrown on defining the class. The below is a minimally reproducible example:
# repro.py
from typing import Literal, Union
from pydantic import BaseModel, Field
class DataAModel(BaseModel):
kind: Literal["a"]
class RequestModel(BaseModel):
data: Union[DataAModel] = Field(..., discriminator="kind")produces
$ python repro.py
Traceback (most recent call last):
File "repro.py", line 10, in <module>
class RequestModel(BaseModel):
File "/home/tom/r/env/lib/python3.8/site-packages/pydantic/main.py", line 204, in __new__
fields[ann_name] = ModelField.infer(
File "/home/tom/r/env/lib/python3.8/site-packages/pydantic/fields.py", line 488, in infer
return cls(
File "/home/tom/r/env/lib/python3.8/site-packages/pydantic/fields.py", line 419, in __init__
self.prepare()
File "/home/tom/r/env/lib/python3.8/site-packages/pydantic/fields.py", line 534, in prepare
self._type_analysis()
File "/home/tom/r/env/lib/python3.8/site-packages/pydantic/fields.py", line 605, in _type_analysis
raise TypeError('`discriminator` can only be used with `Union` type')
TypeError: `discriminator` can only be used with `Union` typeThe following code snippet works as intended. The only difference is I have introduced a second type in the discriminated union field. Note that simply repeating the existing type (such as Union[DataAModel, DataAModel]) still fails:
from typing import Literal, Union
from pydantic import BaseModel, Field
class DataAModel(BaseModel):
kind: Literal["a"]
class DataBModel(BaseModel):
kind: Literal["b"]
class RequestModel(BaseModel):
data: Union[DataAModel, DataBModel] = Field(..., discriminator="kind")After some poking, it looks like within _type_analysis, self.discriminator_key is set on the model DataAModel, rather than the parent field, Union[DataAModel]. I'm guessing there is a simplification step somewhere where singleton unions are simplified to their child type, which is no longer accurate?
Happy to submit a PR if you can point me further in the right approach.