Initial Checks
Description
If unionizing types on a RootModel, providing a discriminator seems to fail with a TypeError:
TypeError: 'definition-ref' is not a valid discriminated union variant; should be a `BaseModel` or `dataclass`
Moving the discriminator to an aggregate root model which has a list of the unionized variants seems to work just fine though.
In pydantic==2.0b2 the problematic code below worked. But now in pydantic==2.0b3 it does not.
Please let me know if this is expected for any reason. For now, I can work around it per the commented example code.
Example Code
# Usage:
# python -m venv .venv
# . .venv/bin/activate # or . .\.venv\Scripts\Activate.ps1
# pip install git+https://github.com/pydantic/pydantic.git#egg=pydantic
# pip freeze # confirm pydantic commit is current tip of main
# python union_root_discriminator_issues_pydv2b3.py
# pylint: disable=all
from typing import Literal
from pydantic import RootModel, BaseModel, Field
class IdBase(BaseModel):
kind: Literal["id"]
class IdVariant1(IdBase):
id_str: str
class IdVariant2(IdBase):
id_int: int
class Id(RootModel):
root: IdVariant1 | IdVariant2
class Name(BaseModel):
name: str
kind: Literal["name"]
# This doesn't work, yielding this error:
# TypeError: 'definition-ref' is not a valid discriminated union variant; should be a `BaseModel` or `dataclass`
class Item(RootModel):
root: Name | Id = Field(..., discriminator="kind")
class Items(RootModel):
root: list[Item]
# This does work though
# class Item(RootModel):
# root: Name | Id
#
#
# class Items(RootModel):
# root: list[Item] = Field(..., discriminator="kind")
def main():
items = Items.model_validate(
[
{"id_str": "id1", "kind": "id"},
{"id_int": 2, "kind": "id"},
{"name": "number-three", "kind": "name"},
]
)
print(items)
print(items.model_json_schema())
print(items.model_dump_json())
if __name__ == "__main__":
main()
Python, Pydantic & OS Version
Verified in 2 environments: The first being windows 11 with a direct install from the repo. The second being a WSL2 dev container with a direct install from pypi.
> .\.venv\Scripts\python.exe -c "import pydantic.version; print(pydantic.version.version_info())"
pydantic version: 2.0b3
pydantic-core version: 0.40.1 release build profile
install path: C:\Users\kevin.farley\Documents\my_src\pydanticv2\.venv\Lib\site-packages\pydantic
python version: 3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]
platform: Windows-10-10.0.22621-SP0
optional deps. installed: ['typing-extensions']
$ python -c 'import pydantic.version; print(pydantic.version.version_info())'
pydantic version: 2.0b3
pydantic-core version: 0.39.0 release build profile
install path: /home/vscode/.local/lib/python3.11/site-packages/pydantic
python version: 3.11.4 (main, Jun 13 2023, 15:08:32) [GCC 10.2.1 20210110]
platform: Linux-5.15.90.1-microsoft-standard-WSL2-x86_64-with-glibc2.31
optional deps. installed: ['typing-extensions']
Initial Checks
mainbranch, or equivalentDescription
If unionizing types on a RootModel, providing a discriminator seems to fail with a TypeError:
Moving the discriminator to an aggregate root model which has a list of the unionized variants seems to work just fine though.
In
pydantic==2.0b2the problematic code below worked. But now inpydantic==2.0b3it does not.Please let me know if this is expected for any reason. For now, I can work around it per the commented example code.
Example Code
Python, Pydantic & OS Version