swansonk14 / typed-argument-parser

Typed argument parser for Python
MIT License
494 stars 40 forks source link

[suggestion] `tapify` should create positional args for signatures w/ positional-only params #100

Closed baodrate closed 4 months ago

baodrate commented 1 year ago

Currently, the tapify interface creates "options"/flags (-- prefixed, position-agnostic arguments) for each parameter in the function signature. e.g.:

from tap import tapify
def foo(num1: int, num2: float, /, bar: str) -> None:
    ...

if __name__ == "__main__":
    tapify(foo)

produces:

usage: ... [-h] --num1 NUM1 --num2 NUM2 --bar BAR

options:
  -h, --help   show this help message and exit
  --num1 NUM1  (int, required)
  --num2 NUM2  (float, required)
  --bar BAR    (str, required)

Since parameters that follow / are positional-only, tapify should omit the -- prefix when it calls add_argument(...), so that argparse creates a positional argument.

kddubey commented 5 months ago

tapify currently doesn't work when there are positional-only arguments.

For example, try to run your script (instead of just -h)

$ python script.py --num1 1 --num2 2 --bar "bar"
Traceback (most recent call last):
  File "/Users/kdubey/projects/typed-argument-parser/script.py", line 16, in <module>
    tapify(foo)
  File "/Users/kdubey/projects/typed-argument-parser/tap/tapify.py", line 335, in tapify
    return class_or_function(**command_line_args_dict)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: foo() got some positional-only arguments passed as keyword arguments: 'num1, num2'

I'll fix this bug

martinjm97 commented 5 months ago

Hi @baod-rate,

I didn't know about this feature. Thank you for raising this issue. I agree that this is a bug and that it should be addressed. @kddubey thank you very much for offering to fix it!

--Jesse

martinjm97 commented 4 months ago

Thank you @kddubey for the fix!

--JK