fastapi / typer

Typer, build great CLIs. Easy to code. Based on Python type hints.
https://typer.tiangolo.com/
MIT License
15.76k stars 671 forks source link

[BUG] MSYS2 Bash and Git Bash for Windows autocomplete get ^M between autocomplete options #202

Open aslakrin opened 3 years ago

aslakrin commented 3 years ago

Describe the bug

Somewhere along the line it seems an \r gets introduced between the available options in git bash on windows. This is also the case for MSYS2. Seems not to be for zsh under msys2.

To Reproduce

Steps to reproduce the behavior with a minimum self-contained file.

Replace each part with your own scenario:

import typer

app = typer.Typer()

@app.command()
def hello(name: str):
    typer.echo(f"Hello {name}")

@app.command()
def goodbye(name: str):
    typer.echo(f"Goodbye {name}")

if __name__ == "__main__":
    app()
typer main.py run <TAB><TAB>
goodbye^M  hello      
goodbye hello      

Expected behavior

I do not expect extra carriage returns to appear as control characters

Environment

Additional context

Operates normally when APP_COMPLETE=complete_bash $1 ) is changed to APP_COMPLETE=complete_bash $1 | tr -d '\r' ) in the completion file, but this is probably not a good fix.

Pack3tL0ss commented 2 years ago

Appreciate the great tools

I think this is the same as what I'm seeing. It appears to have started with click v8.0.0, if I pin to click v7.1.2 bash completion works as expected.

completion was refactored in click 8. I don't know if issue lies w/ typer or click, but ^M is always injected into the completion.

$ cencli show
^M          aps         clients     dhcp        gateways    interfaces  logs        sites       tokens      vlans       wlans
alerts      branch      config      events      groups      last        routes      switches    upgrade     webhooks
all         certs       devices     firmware    hook-proxy  lldp        run         templates   variables   wids

The ^M breaks completion you always have to type the full word. Again: click v7.1.2 works click >=8.0.0 exhibits the issue.

Expect this may be an issue with click upstream, but hopefully we can get it sorted out.

There was another impact to click 8.x re completion, and this appears to impact all shells. I have a ton of custom completion functions, all were setup like this:

# app.command defines custom completion func:
#  _group: str = typer.Option(None, "--group", autocompletion=cli.cache.group_completion,)

    def group_completion(
        self,
        incomplete: str,
        args: List[str] = None,
    ):
        match = self.get_group_identifier(
            incomplete,
            completion=True,
        )
        out = []
        if match:
            for m in sorted(match, key=lambda i: i.name):
                if m.name not in args:
                    out += [tuple([m.name, m.help_text])]

        for m in out:
            yield m[0], m[1]

prior to click 8 cencli move barn.3 --group <tab><tab> would provide ['move', 'barn.3', '--group'] as args to the completion function. Since click 8 args is always []

They all show up in the ctx.params (values()), but that's a lot of re-factoring.

Pack3tL0ss commented 2 years ago

@tiangolo do we need to open an issue (may already be one) with click? It was def something in click 8 that causes the behavior, but not sure if it's an issue with typers interaction or if click actually broke completion on bash with click 8?

Same for the args parameter in the completion functions. If click 8 is in use args is always an empty list as described above.

Thanks for the great work/tools!