jsonargparse icon indicating copy to clipboard operation
jsonargparse copied to clipboard

Cannot parse a list of unions of two different dataclasses

Open mnidza opened this issue 1 year ago • 2 comments

🐛 Bug report

I am getting an error when parsing a list of objects whose type is the union of two different dataclasses.

To reproduce

In script.py

from dataclasses import dataclass
from jsonargparse import CLI

@dataclass
class A:
    a: int

@dataclass
class B:
    b: int

def f(c: list[A | B]):
    print(c)

CLI(f, as_positional=False)

In config.yaml

c:
  - a: 1
  - b: 2

In terminal

python script.py --config config.yaml

Expected behavior

Expected console output

[A(a=1), B(b=2)]

Actual console output

ValueError: Does not validate against any of the Union subtypes
Subtypes: (<class '__main__.A'>, <class '__main__.B'>)
Errors:
  - 'LazyInstance_B' object has no attribute 'b'
  - B.__init__() got an unexpected keyword argument 'a'
Given value type: <class 'jsonargparse._namespace.Namespace'>
Given value: Namespace(a=1)

Environment

  • jsonargparse version: 4.29.0
  • Python version: 3.11.4
  • How jsonargparse was installed: pip install jsonargparse[signatures]
  • OS: Windows 11 Enterprise, 10.0.22631

mnidza avatar Jun 12 '24 06:06 mnidza

Thank you for reporting! I will look at it.

mauvilsa avatar Jun 17 '24 04:06 mauvilsa

I think I'm encountering this or a similar bug when I try to parse a union of attrs classes. The attached testcase fails when I try to use the second type in a union, with the following output:

E argparse.ArgumentError: Validation failed: Parser key "data":
E Does not validate against any of the Union subtypes
E Subtypes: (<class 'jsonargparse_tests.test_dataclass_like.AttrsData'>, <class 'jsonargparse_tests.test_dataclass_like.AttrsData2'>)
E Errors:
E - No action for key "p4" to set its default.
E - No action for key "p1" to set its default.
E Given value type: <class 'jsonargparse._namespace.Namespace'>
E Given value: Namespace(p1=None, p2='-', p4=1)

jsonargparse/_core.py:1010: ArgumentError

nkrishnaswami avatar Aug 07 '24 18:08 nkrishnaswami

@mnidza just now I reran the reproduction script and it works as expected, giving [A(a=1), B(b=2)]. I am not sure in which change this was fixed. @nkrishnaswami also the TestAttrs::test_union test passes now. Please check and if you like, create a pull request to add your test case.

mauvilsa avatar Sep 20 '24 08:09 mauvilsa