diff --git a/cyclopts/bind.py b/cyclopts/bind.py index 0e900bed..18a4648c 100644 --- a/cyclopts/bind.py +++ b/cyclopts/bind.py @@ -68,9 +68,21 @@ def parameter2cli(f: Callable) -> Dict[inspect.Parameter, List[str]]: p2c = {} for cli, tup in c2p.items(): - parameter = tup[0] - p2c.setdefault(parameter, []) - p2c[parameter].append(cli) + iparam = tup[0] + p2c.setdefault(iparam, []) + p2c[iparam].append(cli) + + signature = inspect.signature(f) + for iparam in signature.parameters.values(): + annotation = str if iparam.annotation is iparam.empty else iparam.annotation + _, cparam = get_hint_parameter(annotation) + + if not cparam.parse: + continue + + # POSITIONAL_OR_KEYWORD and KEYWORD_ONLY already handled in cli2parameter + if iparam.kind in (iparam.POSITIONAL_ONLY, iparam.VAR_KEYWORD, iparam.VAR_POSITIONAL): + p2c[iparam] = get_names(iparam) return p2c diff --git a/tests/test_parameter2cli.py b/tests/test_parameter2cli.py new file mode 100644 index 00000000..9637657d --- /dev/null +++ b/tests/test_parameter2cli.py @@ -0,0 +1,51 @@ +import inspect + +from typing_extensions import Annotated + +from cyclopts.bind import parameter2cli +from cyclopts.parameter import Parameter + + +def test_parameter2cli_positional_or_keyword(): + def foo(a: Annotated[int, Parameter(negative=())]): + pass + + a_iparam = list(inspect.signature(foo).parameters.values())[0] + actual = parameter2cli(foo) + assert actual == {a_iparam: ["--a"]} + + +def test_parameter2cli_positional_only(): + def foo(a: Annotated[int, Parameter(negative=())], /): + pass + + a_iparam = list(inspect.signature(foo).parameters.values())[0] + actual = parameter2cli(foo) + assert actual == {a_iparam: ["A"]} + + +def test_parameter2cli_keyword_only(): + def foo(*, a: Annotated[int, Parameter(negative=())]): + pass + + a_iparam = list(inspect.signature(foo).parameters.values())[0] + actual = parameter2cli(foo) + assert actual == {a_iparam: ["--a"]} + + +def test_parameter2cli_var_keyword(): + def foo(**a: Annotated[int, Parameter(negative=())]): + pass + + a_iparam = list(inspect.signature(foo).parameters.values())[0] + actual = parameter2cli(foo) + assert actual == {a_iparam: ["--a"]} + + +def test_parameter2cli_var_positional(): + def foo(*a: Annotated[int, Parameter(negative=())]): + pass + + a_iparam = list(inspect.signature(foo).parameters.values())[0] + actual = parameter2cli(foo) + assert actual == {a_iparam: ["A"]}