Skip to content

Implement suggestion for command typo#699

Merged
zhenchaoni merged 2 commits into
mainfrom
private/zhenni/typo_suggestion
May 22, 2026
Merged

Implement suggestion for command typo#699
zhenchaoni merged 2 commits into
mainfrom
private/zhenni/typo_suggestion

Conversation

@zhenchaoni
Copy link
Copy Markdown
Member

@zhenchaoni zhenchaoni commented May 21, 2026

Fix #508

Suggest closest subcommand on typos (fixes #508)

Before

$ winml exprt
Usage: winml [OPTIONS] COMMAND [ARGS]...
Try 'winml --help' for help.

Error: No such command 'exprt'.

The bare error gives no recourse — users had to re-read winml --help to find the intended name. This forced a round-trip for what is almost always a one-character typo.

After

$ winml exprt
Usage: winml [OPTIONS] COMMAND [ARGS]...
Try 'winml --help' for help.

Error: No such command 'exprt'. Did you mean 'export'?

Fix

Click 8.4 ships a built-in typo suggester: Group.resolve_command raises NoSuchCommand(cmd_name, possibilities=self.commands, ctx=ctx), and NoSuchCommand runs difflib.get_close_matches over the keys of possibilities to append Did you mean 'X'? to the error message.

The catch: LazyGroup discovers subcommands by scanning src/winml/modelkit/commands/*.py at runtime (via list_commands) and never eagerly populates self.commands. So Click had nothing to compare against.

This PR is a 3-line adapter on top of Click's built-in path:

def resolve_command(self, ctx: click.Context, args: list[str]):
    """Seed ``self.commands`` so Click can emit a did-you-mean hint on typos."""
    # Click's NoSuchCommand exception uses self.commands to find suggestions.
    for name in self.list_commands(ctx):
        self.commands.setdefault(name, None)  # type: ignore[arg-type]
    return super().resolve_command(ctx, args)

@zhenchaoni zhenchaoni requested a review from a team as a code owner May 21, 2026 09:12
Comment thread src/winml/modelkit/cli.py Outdated
Comment thread src/winml/modelkit/cli.py
@zhenchaoni zhenchaoni merged commit 5188f67 into main May 22, 2026
9 checks passed
@zhenchaoni zhenchaoni deleted the private/zhenni/typo_suggestion branch May 22, 2026 04:11
DingmaomaoBJTU pushed a commit that referenced this pull request May 22, 2026
Fix #508 

## Suggest closest subcommand on typos (fixes #508)

### Before

```
$ winml exprt
Usage: winml [OPTIONS] COMMAND [ARGS]...
Try 'winml --help' for help.

Error: No such command 'exprt'.
```

The bare error gives no recourse — users had to re-read `winml --help`
to find the intended name. This forced a round-trip for what is almost
always a one-character typo.

### After

```
$ winml exprt
Usage: winml [OPTIONS] COMMAND [ARGS]...
Try 'winml --help' for help.

Error: No such command 'exprt'. Did you mean 'export'?
```

### Fix

Click 8.4 ships a built-in typo suggester: `Group.resolve_command`
raises `NoSuchCommand(cmd_name, possibilities=self.commands, ctx=ctx)`,
and `NoSuchCommand` runs `difflib.get_close_matches` over the keys of
`possibilities` to append `Did you mean 'X'?` to the error message.

The catch: `LazyGroup` discovers subcommands by scanning
`src/winml/modelkit/commands/*.py` at runtime (via `list_commands`) and
never eagerly populates `self.commands`. So Click had nothing to compare
against.

This PR is a 3-line adapter on top of Click's built-in path:

```python
def resolve_command(self, ctx: click.Context, args: list[str]):
    """Seed ``self.commands`` so Click can emit a did-you-mean hint on typos."""
    # Click's NoSuchCommand exception uses self.commands to find suggestions.
    for name in self.list_commands(ctx):
        self.commands.setdefault(name, None)  # type: ignore[arg-type]
    return super().resolve_command(ctx, args)
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

Successfully merging this pull request may close these issues.

[winml] [P1] winml exprt (typo) returns "No such command" with no suggestion

2 participants