Nesting has confusing, hidden, behaviour
See original GitHub issueDescribe the bug It took me a lot of experimentation to find out that parameters are only prefixed with their nested group name if the name of the nested parameter conflicts with another. I expected it to prefix it with the nested group name at all times, and I think it should do this.
It should do this because of the following situation:
- I have a dataclass of parameters I want to re-use in multiple places (lets call it A, with parameters
a
andb
) - If I use it in one place which only has a single nested group of type A, then I specify arguments as
--a asdf
and--b asdf
. - If I use it in a second place which has multiple nested groups then if those groups also specify parameters of
a
andb
then suddenly my API has silently changed from--a asdf
to--A.a asdf
without touching that bit of code
There is a second situation where this is useful as well: I define a dataclass with parameter names that make sense in the context of the name of the class they are defined under. However, if you take those names out of context without the name of the containing class, then they are ill-defined and therefore the resulting CLI is confusing. e.g.
@dataclass
class Bananas:
count: int
@dataclass
class MyCli:
bananas: Bananas
Gives the following CLI helptext:
usage: scratch_1.py [-h] --count int
scratch_1.py: error: the following arguments are required: --count
Note that count
is now completely meaningless. I can obviously add a docstring to explain it, but that means that every parameter docstring in Bananas
must make sure it references Bananas.
To Reproduce
Comment/uncomment out B
from MyCli
and see the output of --help
change.
from simple_parsing import ArgumentParser
from dataclasses import dataclass
from typing import *
@dataclass
class A:
a: str
b: str
@dataclass
class B:
a: str
b: str
@dataclass
class MyCli:
A: A
B: B # Comment/uncomment this.
parser = ArgumentParser()
parser.add_arguments(MyCli, dest="args")
args = parser.parse_args()
Expected behavior Subgroups should always include the group name when specifying their parameters.
I.e. in the above example, without B, you should get:
usage: scratch_1.py [-h] -a str -b str
scratch_1.py: error: the following arguments are required: -A.a/--A.a, -A.b/--A.b
whereas you currently get this:
usage: scratch_1.py [-h] -a str -b str
scratch_1.py: error: the following arguments are required: -a/--a, -b/--b
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (4 by maintainers)
Top GitHub Comments
Hi @lebrice, sorry for re-opening the issue. I think there was a misunderstanding (my fault). Passing the ConflictResolution.EXPLICIT value to the ArgumentParser constructor’s conflict_resolution argument is only used if there is a conflict. Instead, I want to force prefixing for all nested arguments, even if there is no potential for a conflict.
Hi, many thanks for the idea!