Skip to content
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

Improve tkinter 'import *' situation #73632

Closed
terryjreedy opened this issue Feb 4, 2017 · 12 comments
Closed

Improve tkinter 'import *' situation #73632

terryjreedy opened this issue Feb 4, 2017 · 12 comments
Labels
3.9 only security fixes easy topic-tkinter type-bug An unexpected behavior, bug, or error

Comments

@terryjreedy
Copy link
Member

BPO 29446
Nosy @terryjreedy, @ericvsmith, @ethanfurman, @ceronman, @serhiy-storchaka, @mlouielu
PRs
  • bpo-29446: Improve tkinter 'import *' situation #14864
  • bpo-29446: IDLE -- add explicit imports #14919
  • [3.8] bpo-29446: IDLE -- add explicit imports (GH-14919) #14920
  • [3.7] bpo-29446: IDLE -- add explicit imports (GH-14919) #14921
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2019-07-26.01:36:33.217>
    created_at = <Date 2017-02-04.21:24:25.286>
    labels = ['easy', 'type-bug', 'expert-tkinter', '3.9']
    title = "Improve tkinter 'import *' situation"
    updated_at = <Date 2019-07-26.01:36:33.216>
    user = 'https://github.com/terryjreedy'

    bugs.python.org fields:

    activity = <Date 2019-07-26.01:36:33.216>
    actor = 'terry.reedy'
    assignee = 'none'
    closed = True
    closed_date = <Date 2019-07-26.01:36:33.217>
    closer = 'terry.reedy'
    components = ['Tkinter']
    creation = <Date 2017-02-04.21:24:25.286>
    creator = 'terry.reedy'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 29446
    keywords = ['patch', 'easy']
    message_count = 12.0
    messages = ['286996', '286997', '287028', '287041', '287049', '287052', '348188', '348199', '348350', '348351', '348353', '348461']
    nosy_count = 6.0
    nosy_names = ['terry.reedy', 'eric.smith', 'ethan.furman', 'ceronman', 'serhiy.storchaka', 'louielu']
    pr_nums = ['14864', '14919', '14920', '14921']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue29446'
    versions = ['Python 3.9']

    @terryjreedy
    Copy link
    Member Author

    Tkinter naming was designed so that 'from tkinter import *' can work, in the sense of not conflicting with built-in and stdlib module names. But there are currently two problems.

    1. The current doc

    ...to use Tkinter all you need is a simple import statement:
    import tkinter
    Or, more often:
    from tkinter import *

    over-promotes 'import *' as the common and therefore normal import (as opposed to a convenience for interactive use). It neglects the alternatives 'import tkinter as tk' or 'from tkinter import Tk, ...', and consequently makes no mention of the relative advantages.

    1. The current code does not define __all__. So the stdlib imports of enum, re, and sys get carried over with 'import *'. Guido recommends defining __all__ to prevent this.* Since tkinter defines about 160 names, and since there are only 3 names to block, and there are used pretty sparingly, I prefer the uglier alternative of renaming with underscores: 'import enum as _enum', etc.

    I will work on patches. Since the doc change can apply to all current versions while the code change might be restricted to 3.7, I will keep then separate.

    • From pydev thread 'Imports with underscores', 2017-1-9:

    "I would focus on changing habits to discourage "import *" rather than
    uglifying all new code with this "os as _os" pattern. Very occasionally
    one designs a module to explicitly support "import *", and that usually
    entails using __all__ (like it or not), making the problem go away
    without uglifying the code."

    @terryjreedy terryjreedy added 3.7 (EOL) end of life topic-tkinter type-bug An unexpected behavior, bug, or error labels Feb 4, 2017
    @serhiy-storchaka
    Copy link
    Member

    There is yet one name that doesn't make sense to import -- wantobjects. It can't be renamed.

    @terryjreedy
    Copy link
    Member Author

    This issue is spun-off from bpo-29162, which was about idlelib.pyshell depending on import * importing sys.

    'wantobjects' does not have the same bug potential as stdlib imports. But, Serhiy, if you care about it or otherwise prefer __all__,

    __all__ = [name for name in globals() if not name.startswith('_') and name not in {'enum', 're', 'sys', 'wantobjects'}]

    should work if placed near the end of the file, just before 'def _test'. Except for the exclusion set, I presume that 'import *' does essentially the same iteration

    @serhiy-storchaka
    Copy link
    Member

    LGTM.

    @ericvsmith
    Copy link
    Member

    Instead of:
    __all__ = [name for name in globals() if not name.startswith('_') and name not in {'enum', 're', 'sys', 'wantobjects'}]

    Maybe this would be less fragile:
    import types
    __all__ = [name for name, obj in globals().items() if not name.startswith('_') and not isinstance(obj, types.ModuleType) and name not in {'wantobjects'}]

    That is, exclude all modules. Admittedly, I had to import types, but there are other ways to do this test without that import.

    @serhiy-storchaka
    Copy link
    Member

    This also excludes "constants" implicitly added by importing names from tkinter.constants. I don't know whether this is good or bad.

    Interesting, but

        from tkinter import *
        import tkinter.ttk

    and

        import tkinter.ttk
        from tkinter import *

    have different effects.

    @serhiy-storchaka
    Copy link
    Member

    I prefer Eric's approach. It excludes tkinter submodules (like tkinter.ttk). Currently the result of the star import depends on what submodules were imported before. I think it would be better to make it more stable.

    @terryjreedy
    Copy link
    Member Author

    I agree that for python x.y, the names imported by 'import *' should be fixed and *not* depend on other imports.

    @terryjreedy terryjreedy added 3.9 only security fixes and removed 3.7 (EOL) end of life labels Jul 19, 2019
    @terryjreedy
    Copy link
    Member Author

    New changeset c6fd6c8 by Terry Jan Reedy in branch 'master':
    bpo-29446: IDLE -- add explicit imports (GH-14919)
    c6fd6c8

    @terryjreedy
    Copy link
    Member Author

    New changeset fc63d5a by Terry Jan Reedy (Miss Islington (bot)) in branch '3.8':
    bpo-29446: IDLE -- add explicit imports (GH-14919) (GH-14920)
    fc63d5a

    @terryjreedy
    Copy link
    Member Author

    New changeset aee260f by Terry Jan Reedy (Miss Islington (bot)) in branch '3.7':
    bpo-29446: IDLE -- add explicit imports (GH-14919) (bpo-14921)
    aee260f

    @terryjreedy
    Copy link
    Member Author

    New changeset 76b6451 by Terry Jan Reedy (Flavian Hautbois) in branch 'master':
    bpo-29446: tkinter 'import *' only imports what it should (GH-14864)
    76b6451

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.9 only security fixes easy topic-tkinter type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants