Skip to content

List fields cannot be used with subparser fields #105

Open

Description

@lebrice

Describe the bug

Can't use fields with nargs="*" with a subparser field that comes after it. The values passed for the list field are incorrectly assumed to be values for the subparser, and so a "incorrect value for argument : Must be one of <A, B, C>"-like error is raised.

UPDATE: Seems like list fields aren't actually the issue: The problem only appeared when using Union[float, List[float]] as a type annotation. Changing the type annotation to List[float] solved the issue.

Activity

  1. johnatannvmd commented on Feb 1, 2022

    @johnatannvmd
    @dataclass
    class Train:
        """Example of a command to start a Training run."""
        # the training directory
        train_dir: Path = Path("~/train")
    
        def execute(self):
            print(f"Training in directory {self.train_dir}")
    
    
    @dataclass
    class Test:
        """Example of a command to start a Test run."""
        # the testing directory
        test_dir: Path = Path("~/train")
    
        def execute(self):
            print(f"Testing in directory {self.test_dir}")
    
    
    @dataclass
    class Program:
        """Available commands and common options"""
        command: Union[Train, Test]
        strlist: List[str] = field(default=None)  # list of the locations
    
        def execute(self):
            print(self.strlist)
            return self.command.execute()
    
    
    if __name__ == "__main__":
        parser = ArgumentParser()
        parser.add_arguments(Program, dest="prog")
        args = parser.parse_args()
        prog: Program = args.prog
        prog.execute()

    If you run this script with these parameters you will get those output where list does not parsed correctly

    $ python run.py --strlist='test2 tes2t' train
    ['test2 tes2t']
    Training in directory ~/train
    

    Running script like this:

    $ python run.py --strlist 'test2 tes2t' train
    

    Gives me an error run.py: error: the following arguments are required: prog.command

    How can I mix subparsers and list of string parameters:

    parser.add_argument("--strlist", nargs="+", type=str, required=True)
    
  2. MartinHowarth commented on Feb 2, 2023

    @MartinHowarth

    The same problem applies to combining the add_config_path_arg=True with subparsers.
    I'm adding as a comment under this issue (rather than a new issue) because under the covers the config flag is added as a nargs="*" option. Let me know if you'd rather I raised as a separate issue.

    The following invocation fails with RuntimeError: Unable to determine what function to use in order to load path deploy into a dictionary since the path's extension isn't registered in the extensions_to_loading_fn dictionary. That's because it's trying to parse subcommand as a filename and the extension ("") isn't recognised.

    python run.py --config config.yaml subcommand
    

    but this works:

    python run.py subcommand --config config.yaml 
    

    Example code:

    from dataclasses import dataclass
    
    from simple_parsing import ArgumentParser
    
    
    @dataclass
    class Dummy:
        value: str
    
    
    parser = ArgumentParser(add_config_path_arg=True)
    parser.add_arguments(Dummy, dest="config")
    subparsers = parser.add_subparsers()
    subcommand = subparsers.add_parser("subcommand")
    args = parser.parse_args()
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions