-
-
Notifications
You must be signed in to change notification settings - Fork 62
Description
🚀 Feature request
Currently jsonargparse mark function parameters as arguments or options simply based on default value exists or not.
This behavior does not match community's expectation nowadays. So I suggest to adopt design which determines CLI arg is arg or option by inspect's kind and also default value.
Motivation
Following is design of typer, which is nearly same as jsonargparse. They separate argument and option based on whether default value exists or not.
import typer
def main(
poskeyword: int,
*,
kwarg: str,
kwarg_default: str = "default",
):
print(poskeyword, kwarg, kwarg_default)
if __name__ == "__main__":
typer.run(main)
Usage: typer_main.py [OPTIONS] POSKEYWORD KWARG
╭─ Arguments ─────────────────────────────────────────────────────────────────────╮
│ * poskeyword INTEGER [default: None] [required] │
│ * kwarg TEXT [default: None] [required] │
╰─────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ───────────────────────────────────────────────────────────────────────╮
│ --kwarg-default TEXT [default: default] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────╯
here we can check that kwarg, which is keyword argument and which user expected to be an option, is treated as arguments, not options.
Authors of https://github.com/BrianPugh/cyclopts argue that it is relic design, does not fit into modern python standards. You can check more details in https://cyclopts.readthedocs.io/en/latest/vs_typer/argument_vs_option/README.html
for same example as above cyclopts prints out following. They treat inspect's kind carefully and (1) let --poskeyword possible, (2) make --kwargs only possible.
Usage: main [ARGS] [OPTIONS]
╭─ Commands ──────────────────────────────────────────────────────────────────────╮
│ --help -h Display this message and exit. │
│ --version Display application version. │
╰─────────────────────────────────────────────────────────────────────────────────╯
╭─ Parameters ────────────────────────────────────────────────────────────────────╮
│ * POSKEYWORD --poskeyword [required] │
│ * --kwarg [required] │
│ --kwarg-default [default: default] │
╰─────────────────────────────────────────────────────────────────────────────────╯
And it's bit more minor, less-influential one. typer can't deal with positional only argument. And it's same for jsonargparse.
import typer
def main(poskeyword: int, /):
print(poskeyword)
if __name__ == "__main__":
typer.run(main)
TypeError: main() got some positional-only arguments passed as keyword arguments:
'poskeyword'
Of course, cyclopts can deal with this case well.
Usage: main [ARGS]
╭─ Commands ──────────────────────────────────────────────────────────────────────╮
│ --help -h Display this message and exit. │
│ --version Display application version. │
╰─────────────────────────────────────────────────────────────────────────────────╯
╭─ Arguments ─────────────────────────────────────────────────────────────────────╮
│ * POSONLY [required] │
╰─────────────────────────────────────────────────────────────────────────────────╯
Pitch
To introduce what I want in detail with example, I created PR #756. Have a look and give me any review in free time.
Alternatives
none.