Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: support positional argument of type Sequence in additional to *args #96

Open
ickc opened this issue Dec 4, 2021 · 6 comments

Comments

@ickc
Copy link

ickc commented Dec 4, 2021

MWE

from dataclasses import dataclass

import defopt


def main(
    args: list[str],
):
    pass


def ok(
    *args: str,
):
    pass


@dataclass
class Main:
    args: list[str]


@dataclass
class Ok:
    arg: str


if __name__ == "__main__":
    defopt.run(
        (main, ok, Main, Ok),
        strict_kwonly=False,
    )

resulted in

❯ python example.py ok -h                          
usage: example.py ok [-h] [args ...]

positional arguments:
  args

optional arguments:
  -h, --help  show this help message and exit
❯ python example.py main -h
usage: example.py main [-h] -a [ARGS ...]

optional arguments:
  -h, --help            show this help message and exit
  -a [ARGS ...], --args [ARGS ...]
❯ python example.py Main -h
usage: example.py Main [-h] -a [ARGS ...]

Main(args: list)

optional arguments:
  -h, --help            show this help message and exit
  -a [ARGS ...], --args [ARGS ...]
❯ python example.py Ok -h  
usage: example.py Ok [-h] arg

Ok(arg: str)

positional arguments:
  arg

optional arguments:
  -h, --help  show this help message and exit

Notes

The feature request is to support main(args: list[TypeX], *, ...) to be equivalent in terms of defopt to main(*args: TypeX, ...).

In the function case, main, the user could have written it as the function ok instead.

In the dataclass case however, since Python's dataclass doesn't support variable positional arguments, one cannot defines *args. So the only sensible choice here is to define args: list instead.

@anntzer
Copy link
Owner

anntzer commented Dec 5, 2021

Thanks for the suggestion. Let's keep the discussion in #95 for now, as I think the two requests share some points.

@ickc
Copy link
Author

ickc commented Dec 6, 2021

? I think they are completely different issue? This one is about how positional arg: list[...] should be treated the same as *args: .... #95 is about allowing appending when the same keyword arg is repeated.

@ickc
Copy link
Author

ickc commented Dec 6, 2021

I read your comments in #95 and now I understand you're proposing using a similar solution to tackle 2 different issues.

@ickc
Copy link
Author

ickc commented Dec 7, 2021

Copied from #95:

This and #96 both seem reasonable to me, but adding a global option to defopt.run seems unsatisfying because sooner or later someone will request to be able to specify this only for some of the parameters, perhaps in some deeply nested subcommands hierarchy on top of that...

Off the top of my head, a possibly(?) better solution could be to exploit typing.Annotated here, e.g. Annotated[list[int], defopt.APPEND] here and Annotated[list[int], defopt.VARARGS] for #96. (Note that for the case here, the underlying type annotation should be list[int], not int, because that's what the type of foo would ultimately be in the program.) A PR would be welcome :-) It should also clarify how these options interact with cli_options, as introduced by #92 (which is generalizing strict_kwonly).

@ickc
Copy link
Author

ickc commented Dec 7, 2021

Sorry, giving up for now. I don't seem to understand the design of defopt.

For example,

#!/usr/bin/env python

from typing import Annotated
from inspect import Parameter

import defopt

def main(args: Annotated[list[str], Parameter.VAR_POSITIONAL]):
    pass

if __name__ == "__main__":
    defopt.run(main)

In _populate_parser, I get the following

param.annotation == typing.List[str]
getattr(param.annotation, "__metadata__", []) == []

It doesn't seem to be able to get the Annotated types and its metadata.

@anntzer
Copy link
Owner

anntzer commented Dec 7, 2021

Right now there is no support for Annotated at all, the suggestion is also to add such support.

@anntzer anntzer changed the title feature request: support positional argument of type Squence in additional to *args feature request: support positional argument of type Sequence in additional to *args Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants