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

add_argument should not overwrite properties defined in class member. #131

Open
oren-hecht opened this issue Feb 4, 2024 · 1 comment
Open
Labels
enhancement New feature or request

Comments

@oren-hecht
Copy link

There is a very common practice in scripts, to allow both "long syntax" and shorter versions of some argument name. [The documentation] (https://github.com/swansonk14/typed-argument-parser?tab=readme-ov-file#adding-special-argument-behavior) suggests using add_argument to achieve this:

from tap import Tap

class MyTap(Tap):
    argument_with_really_long_name: int

    def configure(self):
        self.add_argument('-arg', '--argument_with_really_long_name')

However, In the case where I had defined properties on this argument, the operation will overwrite these

from tap import Tap

class MyTap(Tap):
    argument_with_really_long_name: int = 5  # A description for this long argument

    def configure(self):
        self.add_argument('-arg', '--argument_with_really_long_name')

In this case, the default value and the help description will be lost. In my project, we have many such arguments, sometimes defined with more complex properties such as list[Literal] types - it is a shame that the second we want to allow a shorter argument name, we lose all the powerful Tap features that allow defining argument properties. An example from our code:

from typing import Literal, get_args
from tap import Tap

DebugOptionsType = Literal["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"]


class CloudDebuggerOptions(Tap):
    aws_profile: str = "default"  # The AWS profile to use
    debug_levels: list[DebugOptionsType] = []  # A list of debug messages to receive

I want to allow shorter names here - and so have to add all the following lines

    def configure(self) -> None:
        self.add_argument("-a", "--aws-profile", dest="aws_profile", default="default", help="The AWS profile to use")
        self.add_argument(
            "-d",
            "--debug-levels",
            dest="debug_levels",
            nargs="+",
            choices=get_args(DebugOptionsType),
            default=[],
            help="A list of debug messages to receive",
        )

by the way, the same problem is present if we want to allow the CLI options to be in kebab-case (the linux standard) as opposed to snake_case, as can be seen above (since you cannot define class member names using kebab-case in python).

PROPOSAL

Only overwrite the specific add_argument options being used, and take the rest from the class member. Or, possible, make some simpler syntax that allows assigning an alternative argument name

@martinjm97 martinjm97 added the enhancement New feature or request label Mar 10, 2024
@martinjm97
Copy link
Collaborator

Hi @oren-hecht,

Thank you for raising this issue! Both of your suggestion make sense.

The first change would be to keep all of the information specified by the class variable and then have configure extend/overwrite it. We agree this would help eliminate redundancy.

Additionally, perhaps we could leverage Annotated to specify shortened arg names. For example, argument_with_really_long_name: Annotated[int, short_name=arg].

Thank you again for these ideas! We welcome any contributions.

Best,
JK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants