omni-us / jsonargparse

Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables
https://jsonargparse.readthedocs.io
MIT License
323 stars 48 forks source link

Dot syntax not working correctly for pydantic 2 models #604

Open findmyway opened 2 weeks ago

findmyway commented 2 weeks ago

🐛 Bug report

To reproduce

from jsonargparse import CLI
from pydantic import BaseModel, Field
from typing import Annotated, Literal, Union

class PingTask(BaseModel):
    type: Literal["ping"] = "ping"

class PongTask(BaseModel):
    type: Literal["pong"] = "pong"

Task = Annotated[
    Union[PingTask, PongTask],
    Field(discriminator="type"),
]

def train_func(model: Task) -> None:
    print(model)

if __name__ == '__main__':
    CLI(train_func, as_positional=False)

It works well when the model argument is specified as a json string:

$ python x.py --model '{"type": "ping"}'
type='ping'

However, it doesn't work using the dot syntax:

$ python x.py --model.type ping                                                                                                

usage: x.py [-h] [--config CONFIG] [--print_config[=flags]] --model MODEL
error: Parser key "model":
  1 validation error for tagged-union[PingTask,PongTask]
    Unable to extract tag using discriminator 'type' [type=union_tag_not_found, input_value=NestedArg(key='type', val='ping'), input_type=NestedArg]
      For further information visit https://errors.pydantic.dev/2.9/v/union_tag_not_found. Got value: NestedArg(key='type', val='ping')

Expected behavior

Environment

mauvilsa commented 2 weeks ago

Thank you for reporting! I took a quick look. Seems that this happens with pydantic 2 but works fine with pydantic 1. Not sure why. Will look in more detail later.