Skip to content

Discriminative union helper and errors are hard to understand #695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
julien-blanchon opened this issue Mar 21, 2025 · 1 comment
Open
Labels
enhancement New feature or request pending author response A question was asked or some work is pending

Comments

@julien-blanchon
Copy link

I'm using a lot the following discriminative union pattern:

from dataclasses import dataclass
from typing import Annotated, Literal
from jsonargparse import auto_cli
from pydantic import Field

@dataclass
class DatasetImage:
    type: Literal["image"]
    path: str


@dataclass
class DatasetVideo:
    type: Literal["video"]
    path: str
    fps: int


@dataclass
class Config:
    dataset: Annotated[DatasetImage | DatasetVideo, Field(discriminator="type")]


def main(conf: Config):
    print(conf)


if __name__ == "__main__":
    auto_cli(main)

It's working with cyclopts (but still need pydantic for the discriminator field).

With jsonargparse it's working

❯ python main.py --conf.dataset.type="video" --conf.dataset.path="." --conf.dataset.fps=24 
Config(dataset=DatasetVideo(type='video', path='.', fps=24))

But the helper is not very helpful and the error message are very hard to understand

❯ python main.py --conf.dataset.type="video" --conf.dataset.path="."        
usage: main.py [-h] [--config CONFIG] [--print_config[=flags]] [--conf CONFIG] --conf.dataset DATASET
               [--print_shtab {bash,zsh,tcsh}]
error: Parser key "conf.dataset":
  Does not validate against any of the Union subtypes
  Subtypes: [<class '__main__.DatasetImage'>, <class '__main__.DatasetVideo'>]
  Errors:
    - No action for key "fps" to set its default.
    - Validation failed: Key "fps" is required but not included in config object or its value is None.
  Given value type: <class 'jsonargparse._namespace.Namespace'>
  Given value: Namespace(type='video', path='.', fps=None)


❯ python main.py --help              
usage: main.py [-h] [--config CONFIG] [--print_config[=flags]] [--conf CONFIG] --conf.dataset DATASET
               [--print_shtab {bash,zsh,tcsh}]

<function main at 0x10491d8a0>

options:
  -h, --help            Show this help message and exit.
  --config CONFIG       Path to a configuration file.
  --print_config[=flags]
                        Print the configuration after applying all other arguments and exit. The optional flags customizes the
                        output and are one or more keywords separated by comma. The supported flags are: comments, skip_default,
                        skip_null.
  --print_shtab {bash,zsh,tcsh}
                        Print shtab shell completion script.

Config(dataset: Annotated[__main__.DatasetImage | __main__.DatasetVideo, FieldInfo(annotation=NoneType, required=True, discriminator='type')]):
  --conf CONFIG         Path to a configuration file.
  --conf.dataset DATASET
                        (required, type: Annotated[DatasetImage | DatasetVideo, FieldInfo(annotation=null, required=True,
                        discriminator='type')])
@julien-blanchon julien-blanchon added the enhancement New feature or request label Mar 21, 2025
@mauvilsa
Copy link
Member

Thank you for reporting!

Note that the errors are intended to work in general with arbitrary levels of nesting and arbitrary complex type hints. Improvements should be proposed for all cases in general, and not for a specific case.

Could you please explain exactly why is the error hard to understand for you. And propose how you think it should be changed so that it is easier to understand.

@mauvilsa mauvilsa added the pending author response A question was asked or some work is pending label Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request pending author response A question was asked or some work is pending
Projects
None yet
Development

No branches or pull requests

2 participants