Skip to content

Static typing improvements in click.shell_completion#3460

Open
jorenham wants to merge 3 commits into
pallets:stablefrom
jorenham:typing/shell_completion/typed-dicts
Open

Static typing improvements in click.shell_completion#3460
jorenham wants to merge 3 commits into
pallets:stablefrom
jorenham:typing/shell_completion/typed-dicts

Conversation

@jorenham
Copy link
Copy Markdown
Contributor

@jorenham jorenham commented May 18, 2026

As promised in #3455, this improves several (static) types in click.shell_completion:

  • shell_complete narrowed return type
  • CompletionItem now has an optional (defaulting to Any for backcompat) generic type parameter for its .value. I did not update the other modules to use this type parameter to avoid merge conflicts, but because of the default=Any there's no downside to this.
  • ShellComplete.source_vars now returns a typed dict
  • add_completion_class is now parametrized on the cls instance type instead of the type type, so that it's easier to see by looking at the annotations that cls is supposed to be a type rather than an instance. If I remember correctly, now all type checkers support using it as class decorator otherwise, but don't quote me on this.
  • get_completion_class now has overloads for the builtin shell completion strings, so that get_completion_class("zsh") will now be inferred as type[ZshComplete] instead of type[ShellComplete] | None (the | None can be pretty annoying to deal with)

@kdeldycke kdeldycke requested a review from davidism May 22, 2026 12:16
@kdeldycke kdeldycke added this to the 8.4.2 milestone May 22, 2026
@kdeldycke kdeldycke changed the base branch from main to stable May 22, 2026 12:17
Copy link
Copy Markdown
Collaborator

@AndreasBackx AndreasBackx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the underscore, the reason for the Any, and I think this should be rebased on main, not stable? Otherwise looks like fine typing improvements. Someone else can confirm the stable vs main thing.

complete_var: str,
instruction: str,
) -> int:
) -> t.Literal[0, 1]:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should perhaps create a type for ExitCode, but at the same time, I'm not sure there's that much value. Kind of good to know the specific exit codes as well. 🤷️

from typing_extensions import TypeVar

# `Any` is used as default for backwards compatibility (instead of e.g. `str`)
_ValueT_co = TypeVar("_ValueT_co", covariant=True, default=t.Any)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need the underscore prefix, or at least I don't think we should as we don't do it elsewhere.

return args, incomplete

def format_completion(self, item: CompletionItem) -> str:
def format_completion(self, item: CompletionItem[t.Any]) -> str:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason it's Any here instead of str?

Comment thread CHANGES.rst
Unreleased


Version 8.4.1
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not include version changes I think?

@Rowlando13
Copy link
Copy Markdown
Collaborator

If the types tighten at all, then I think it needs to be put on main, but I don't know types too well. If I were running runtime type checking, I would not expect types to change on a bug fix release. @davidism @kdeldycke can you both weigh in so we have a clear answer.

@Rowlando13
Copy link
Copy Markdown
Collaborator

@jorenham sorry for the back and forth on branches. We have not accepted many types prs from outside contributors, so still figuring it out.

@kdeldycke
Copy link
Copy Markdown
Collaborator

If the types tighten at all, then I think it needs to be put on main, but I don't know types too well. If I were running runtime type checking, I would not expect types to change on a bug fix release. @davidism @kdeldycke can you both weigh in so we have a clear answer.

As I said earlier at #3463 (comment):

If typing improvements do not change the API or behavior, then I would consider them as I consider improved tests and bug fixes: OK for bug fix releases.

So to me it is OK to target stable and so the next 8.4.2.

@davidism
Copy link
Copy Markdown
Member

I'm fine with typing changes in fix releases.

@Rowlando13
Copy link
Copy Markdown
Collaborator

Okay fix releases it is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants