Skip to content

Add type annotations for **options in tkinter.messagebox functions #14341

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

Merged
merged 16 commits into from
Jun 30, 2025

Conversation

GameRoMan
Copy link
Contributor

Add explicit **options: Any to all tkinter.messagebox functions to remove "partially unknown type" warnings from type checkers like Pyright and Pylance

This comment has been minimized.

@Akuli
Copy link
Collaborator

Akuli commented Jun 26, 2025

Thanks. This is not quite right; it would be better to add individually all options that these functions accept and their types.

For example, like this:

def showinfo(
    title: str | None = None,
    message: str | None = None,
    *,
    detail: str = ...,
    icon: Literal["error", "info", "question", "warning"] = ...,
    parent: tkinter.Misc = ...,
) -> str: ...

To figure out what options exist, you can pass an invalid option and look at the error message. Try tkinter.messagebox.showinfo(asdf="") for example.

To figure out what each option does, you can try it, or look at the manual here: https://www.tcl-lang.org/man/tcl8.6/TkCmd/messageBox.htm

Let me know if anything is unclear. Tkinter stubs are more difficult than you'd expect :) Also, if this is more work than you want to do, you can just close this PR and wait for someone else (probably me) to do it.

@GameRoMan
Copy link
Contributor Author

Alright, I’ll check it out

This comment has been minimized.

@GameRoMan GameRoMan changed the title Add explicit Any type for **options in tkinter.messagebox functions Add type annotations for **options in tkinter.messagebox functions Jun 27, 2025

This comment has been minimized.

This comment has been minimized.

Copy link
Collaborator

@Akuli Akuli left a comment

Choose a reason for hiding this comment

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

This is much better! A couple things could still be improved.

def askretrycancel(title: str | None = None, message: str | None = None, **options) -> bool: ...
_Icon: TypeAlias = Literal["error", "info", "question", "warning"]
_Type: TypeAlias = Literal["abortretryignore", "ok", "okcancel", "retrycancel", "yesno", "yesnocancel"]
_Default: TypeAlias = Literal["abort", "retry", "ignore", "ok", "cancel", "yes", "no"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

In IDE autocompletions and such, seeing _Icon is less helpful than Literal["error", "info", "question", "warning"]. I'd suggest just copy/pasting these Literals to all the places that use them instead of type aliases.

An advantage of copy/pasting the Literals is that you can make them function-specific. For example, specifying default="retry" doesn't make sense if the dialog only has "yes" and "no" buttons, so the default parameter of askyesno() should be Literal["yes", "no"].

There are many existing type aliases in tkinter. For most of them, I would accept PRs that delete them.

*,
detail: str = ...,
icon: _Icon = ...,
type: _Type = ...,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Even though the type parameter works at runtime, I don't think including it in the stubs makes sense. If you call showinfo(), the type you want is obviously "info" and type checkers should complain if you specify anything else.

I'd suggest deleting all type: _Type parameters.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could define them as 1-element literals, that way redundantly specifying them works, and it'll avoid people thinking the parameter was forgotten. Might be slight noise in autocomplete though.

This comment has been minimized.

Copy link
Collaborator

@Akuli Akuli left a comment

Choose a reason for hiding this comment

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

Great, just one more thing.

*,
detail: str = ...,
icon: Literal["error", "info", "question", "warning"] = ...,
default: Literal["abort", "retry", "ignore", "ok", "cancel", "yes", "no"] = ...,
Copy link
Collaborator

Choose a reason for hiding this comment

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

For askokcancel(), only ok and cancel actually work, because it only has those two buttons. If you pass anything else, there will be an error.

Suggested change
default: Literal["abort", "retry", "ignore", "ok", "cancel", "yes", "no"] = ...,
default: Literal["ok", "cancel"] = ...,

Similarly for other functions. For example, showinfo() should have Literal["ok"] and askyesno() should have Literal["yes", "no"].

Co-authored-by: Akuli <akuviljanen17@gmail.com>

This comment has been minimized.

This comment has been minimized.

Copy link
Collaborator

@Akuli Akuli left a comment

Choose a reason for hiding this comment

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

It looks like you missed a few :)

GameRoMan and others added 3 commits June 30, 2025 16:44
Co-authored-by: Akuli <akuviljanen17@gmail.com>
Co-authored-by: Akuli <akuviljanen17@gmail.com>
Co-authored-by: Akuli <akuviljanen17@gmail.com>
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Copy link
Collaborator

@Akuli Akuli left a comment

Choose a reason for hiding this comment

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

Thanks for your patience. As I mentioned, tkinter stubs are often surprisingly difficult to get right :)

@Akuli Akuli merged commit 3f727b0 into python:main Jun 30, 2025
64 checks passed
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.

3 participants