Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot manipulate dict #289

Closed
rob-hen opened this issue May 20, 2023 · 1 comment 路 Fixed by #290
Closed

Cannot manipulate dict #289

rob-hen opened this issue May 20, 2023 · 1 comment 路 Fixed by #290
Labels
bug Something isn't working

Comments

@rob-hen
Copy link

rob-hen commented May 20, 2023

馃悰 Bug report

To reproduce

python file mwe.py:

from jsonargparse import CLI
from typing import Any, Dict
from dataclasses import dataclass


@dataclass
class ModelConfig:
    data: Dict[str, Any] = None


def method(model: ModelConfig = None):

    print(model.data)


if __name__ == "__main__":
    CLI(method)

yaml file mwe.yaml:

model:
  class_path: ModelConfig
  init_args:
    data:
      A: 1
      B: 2

python mwe.py --config mwe.yaml outputs:
{'A': 1, 'B': 2}

However,

python mwe.py --config mwe.yaml --model.init_args.data.A=4 produces the error message:

usage: mwe.py [-h] [--config CONFIG] [--print_config[=flags]] [--model.help CLASS_PATH_OR_NAME] [--model MODEL]
mwe.py: error: Parser key "model":
  Does not validate against any of the Union subtypes
  Subtypes: (<class '__main__.ModelConfig'>, <class 'NoneType'>)
  Errors:
    - Problem with given class_path '__main__.ModelConfig':
      - Unrecognized arguments: --data.A=4
    - Expected a <class 'NoneType'>
  Given value type: <class 'jsonargparse.util.NestedArg'>
  Given value: NestedArg(key='data.A', val='4')

Expected behavior

The dictionary should have been modified to {'A': 4, 'B': 2}

Environment

  • jsonargparse version: 4.20.1:
  • Python version: 3.9:
  • How was jsonargparse installed: pip install jsonargparse.
  • OS (e.g., Linux): Linux
@mauvilsa
Copy link
Member

Thank you very much for reporting! Indeed there is a bug, though there are inconsistencies in the description. Thus, some clarifications are needed. Dataclasses don't behave like subclasses (see #287), so the config mwe.yaml should not have class_path and init_args. Similarly the command line should be --model.data.A=4 without init_args. And by using None as default, the type hint becomes optional, which is where the actual bug is. Support for dataclasses nested in a type was recently added (#267).

A slightly simpler reproduction which avoids using features unrelated to the bug is:

from jsonargparse import ArgumentParser
from typing import Any, Dict, Optional
from dataclasses import dataclass

@dataclass
class ModelConfig:
    data: Optional[Dict[str, Any]] = None

parser = ArgumentParser()
parser.add_argument("--model", type=Optional[ModelConfig], default=ModelConfig(data={"A": 1, "B": 2}))
parser.parse_args(["--model.data.A=4"])
print(cfg.model.data)

I have created pull request #290 with a fix. @rob-hen please have a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants