kislyuk / argcomplete

Python and tab completion, better together.
https://kislyuk.github.io/argcomplete/
Apache License 2.0
1.39k stars 129 forks source link

Typing support #443

Open aspfohl opened 12 months ago

aspfohl commented 12 months ago

Seeing typing issues in pyright:

error: Cannot assign member "completer" for type "Action"
    Member "completer" is unknown (reportGeneralTypeIssues)

with a set up like this:

class ExampleCompleter:

    def __init__(self):
        pass

    def __call__(sel, **kwargs):
        return {'foo', 'bar'}

parser.add_argument(
    '--arg',
    default=None,
).completer = ExampleCompleter()

Any pointers on calling completer in a type-safe way? This is with argcomplete==3.0.8 and Python 3.10.5

djungelorm commented 9 months ago

I get a similar issue with mypy:

error: "Action" has no attribute "completer"  [attr-defined]

I don't see any way around this other than to define a subclass of argparse.Action with the additional completer attribute, and then cast the result of parser.add_argument to it, for example:

import argparse
from collections.abc import Iterable
from typing import cast
from argcomplete.completers import BaseCompleter

class Action(argparse.Action):
    completer: BaseCompleter | None

class ExampleCompleter(BaseCompleter):
    def __call__(
        self,
        prefix: str,
        action: argparse.Action,
        parser: argparse.ArgumentParser,
        parsed_args: argparse.Namespace,
    ) -> Iterable[str]:
        return {"foo", "bar"}

class ExampleCompleterWithHelp(BaseCompleter):
    def __call__(
        self,
        prefix: str,
        action: argparse.Action,
        parser: argparse.ArgumentParser,
        parsed_args: argparse.Namespace,
    ) -> dict[str, str]:
        return {"foo": "foo help", "bar": "bar help"}

cast(Action, parser.add_argument("--arg1")).completer = ExampleCompleter()
cast(Action, parser.add_argument("--arg2")).completer = ExampleCompleterWithHelp()