Skip to content

tkinter: type hints for Menu add_foo and insert_foo methods #4903

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 3 commits into from
Jan 6, 2021

Conversation

Akuli
Copy link
Collaborator

@Akuli Akuli commented Jan 5, 2021

Generated with script:

import re
import tkinter

main_menu = tkinter.Menu()

hints = {
    # "MENU ENTRY OPTIONS" in menu man page
    'activebackground': "_Color",
    'activeforeground': "_Color",
    'accelerator': "str",
    'background': "_Color",
    'bitmap': "_Bitmap",
    'columnbreak': "int",
    'command': "Union[Callable[[], Any], str]",
    'compound': "_Compound",
    'font': "_FontDescription",
    'foreground': "_Color",
    'hidemargin': "bool",
    'image': "_ImageSpec",
    'indicatoron': "bool",
    'label': "str",
    'menu': "Menu",
    'offvalue': "Any",
    'onvalue': "Any",
    'selectcolor': "_Color",
    'selectimage': "_ImageSpec",
    'state': "Literal['normal', 'active', 'disabled']",
    'underline': "int",
    'value': "Any",
    'variable': "Variable",
}

kw = {
    'activebackground': 'black',
    'activeforeground': 'black',
    'accelerator': 'Ctrl+N',
    'background': 'black',
    'bitmap': 'gray50',
    'columnbreak': 1,
    'command': print,
    'compound': 'left',
    'font': 'Helvetica 16 bold',
    'foreground': 'black',
    'hidemargin': True,
    'image': main_menu.image_names()[0],
    'indicatoron': True,
    'label': 'hello',
    'menu': tkinter.Menu(main_menu),
    'offvalue': 'lol',
    'onvalue': 'wat',
    'selectcolor': 'black',
    'selectimage': main_menu.image_names()[0],
    'state': 'normal',
    'underline': 1,
    'value': 123,
    'variable': tkinter.StringVar(),
}


def print_opts(method):
    opts = sorted(kw.keys())
    if method.__name__.startswith('insert'):
        args_string = 'index:_MenuIndex,'
        method_args = [0]
    else:
        args_string = ''
        method_args = []

    while True:
        try:
            method(*method_args, **{opt: kw[opt] for opt in opts})
            break
        except tkinter.TclError as e:
            opts.remove(re.fullmatch(r'unknown option "-(.*)"', str(e)).group(1))

    print(f'    def {method.__name__}(self,{args_string} cnf: Optional[Dict[str, Any]] = ..., *,')
    for opt in opts:
        print(f'        {opt}: {hints[opt]} = ...,')
    print('    )-> None:...')


print_opts(main_menu.add_cascade)
print_opts(main_menu.add_checkbutton)
print_opts(main_menu.add_command)
print_opts(main_menu.add_radiobutton)
print_opts(main_menu.add_separator)
print_opts(main_menu.insert_cascade)
print_opts(main_menu.insert_checkbutton)
print_opts(main_menu.insert_command)
print_opts(main_menu.insert_radiobutton)
print_opts(main_menu.insert_separator)

@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 2021

Diff from mypy_primer, showing the effect of this PR on open source code:

porcupine (https://github.com/Akuli/porcupine.git)
+ porcupine/plugins/reload.py:35: error: Argument 1 to "insert_command" of "Menu" has incompatible type "object"; expected "Union[str, int]"  [arg-type]

@Akuli
Copy link
Collaborator Author

Akuli commented Jan 5, 2021

In the mypy_primer diff, the argument comes from int if condition else 'end', which mypy treats as object. Should I change this PR or the project that the error comes from? (It's my project.)

Edit: To clarify, the type is Union[int, str] in this PR.

Akuli added a commit to Akuli/porcupine that referenced this pull request Jan 5, 2021
@srittau
Copy link
Collaborator

srittau commented Jan 5, 2021

The annotation seems fine to me. I think it's better to add an explicit annotation in porcupine. I think this should work:

index: Union[int, str] = separator_locations[0] if separator_locations else 'end'

@Akuli
Copy link
Collaborator Author

Akuli commented Jan 5, 2021

The Porcupine commit that shows up above adds that

@Akuli
Copy link
Collaborator Author

Akuli commented Jan 5, 2021

I cherry-picked it to porcupine master which is what mypy_primer uses. Should no longer cause error

Akuli added a commit to Akuli/porcupine that referenced this pull request Jan 5, 2021
@srittau srittau merged commit eaf2945 into python:master Jan 6, 2021
@Akuli Akuli deleted the menu branch January 8, 2021 13:54
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.

2 participants