SimpleParsing: Subgroups destination cannot be a substring of other destinations

Describe the bug I would like to have two subgroups with a different destinations, let’s say config and config2. However, if one of them is a substring of another, an exception is raised saying:

File ~/meaning3/env/lib/python3.10/site-packages/simple_parsing/parsing.py:713, in ArgumentParser._set_instances_in_namespace(self, parsed_args)
    710                 setattr_recursive(existing, path_from_parent_to_child, new_config)
    712         else:
--> 713             raise RuntimeError(
    714                 "Something went wrong while trying to update the value of a \n"
    715                 "subgroup in the args! Please report this bug by opening an issue!"
    716             )
RuntimeError: Something went wrong while trying to update the value of a 
subgroup in the args! Please report this bug by opening an issue!

To Reproduce

from __future__ import annotations
from dataclasses import dataclass
from simple_parsing import ArgumentParser, choice, subgroups
from pathlib import Path


@dataclass
class ModelConfig:
    ...


@dataclass
class ModelAConfig(ModelConfig):
    lr: float = 3e-4
    optimizer: str = "Adam"
    betas: tuple[float, float] = 0.9, 0.999


@dataclass
class ModelBConfig(ModelConfig):
    lr: float = 1e-3
    optimizer: str = "SGD"
    momentum: float = 1.234

@dataclass
class Config:

    # Which model to use
    model: ModelConfig = subgroups(
        {"model_a": ModelAConfig, "model_b": ModelBConfig},
        default=ModelAConfig(),
    )

parser = ArgumentParser()
parser.add_arguments(Config, dest="config")
parser.add_arguments(Config, dest="config2") # this produces and exception
# parser.add_arguments(Config, dest="something") # this works as expected 
args = parser.parse_args("")

config: Config = args.config

print(config)

Expected behavior Not to rise the exception 🙂

I am not sure, but maybe this condition https://github.com/lebrice/SimpleParsing/blob/545aa469defecba6d30da02199a1ea206740ad23/simple_parsing/parsing.py#L768-L771

should be changed to:

if not subgroup_dest.startswith(wrapper.dest + "."):
    continue

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (9 by maintainers)

Commits related to this issue

Most upvoted comments

In the case of my Partial feature, it would look like this:

# Dynamically create a dataclass that will be used for the above type:
# NOTE: We could use Partial[Adam] or Partial[Optimizer], however this would treat `params` as a
# required argument.
# AdamConfig = Partial[Adam]  # would treat 'params' as a required argument.
# SGDConfig = Partial[SGD]    # same here
AdamConfig: type[Partial[Adam]] = config_dataclass_for(Adam, ignore_args="params")
SGDConfig: type[Partial[SGD]] = config_dataclass_for(SGD, ignore_args="params")

@dataclass
class Config:

    # Which optimizer to use.
    optimizer: Partial[Optimizer] = subgroups(
        {
            "sgd": SGDConfig,
            "adam": AdamConfig,
        },
        default_factory=lambda: AdamConfig(lr=3e-4),
    )

https://github.com/lebrice/SimpleParsing/pull/156/files#diff-90a53367e3aa7a79a1ea7d7d9ab8ab940ccb3fb63fa59e37084c47a1384156e3R56-R70

Hi @Tomiinek , thanks for posting this.

Yes you’re right, I’ve temporarily restricted what can be passed to the subgroups function to only dataclass types. I’m working on this today.

By the way, your dynamic generated config classes look a lot like what I’ve been doing here: https://github.com/lebrice/SimpleParsing/pull/156

Just hang tight for now 😅 I’ll figure out a solution to this soon, and get back to you.

I hope it is the current master (5042cb4f863fbf5e1364871de0ecb8f766213e78) aka simple-parsing===0.0.21.post1.post4-g5042cb4 with python 3.10.8