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
314 stars 42 forks source link

Overriding a config's argument makes everything else fall back to the base class #464

Closed carmocca closed 5 months ago

carmocca commented 6 months ago

🐛 Bug report

To reproduce

repro.py:

from dataclasses import dataclass
from typing import Optional

@dataclass
class Thing:
    foo: int = 1
    bar: int = 2

def fn(thing: Optional[Thing] = None):
    thing = Thing() if thing is None else thing
    print(thing)

from jsonargparse import CLI
CLI(fn)

repro.yaml:

thing:
  foo: 123
  bar: 321

python repro.py --config repro.yaml --thing.foo 9

Expected behavior

The above prints

Thing(foo=9, bar=2)

but I expected

Thing(foo=9, bar=321)

Context

A more real world example is that you have a trainer_config.yaml and you want to only modify the --train.max_epochs value without having everything else fall back to dataclass defaults

Environment

Version 4.275

carmocca commented 6 months ago

Given that

class Thing:
    def __init__(self, foo=1, bar=2):
        print(locals())

from jsonargparse import CLI
CLI(Thing)
foo: 123
bar: 321

python repro.py --config repro.yaml --foo 9

Works as expected, I would expect these two approaches to produce the same result

mauvilsa commented 5 months ago

Thank you for reporting! This is fixed with #471.