Skip to content

bpo-29446: Improve tkinter 'import *' situation#14864

Merged
terryjreedy merged 5 commits into
python:masterfrom
flavianh:bpo-29446-from-tkinter-import-all
Jul 26, 2019
Merged

bpo-29446: Improve tkinter 'import *' situation#14864
terryjreedy merged 5 commits into
python:masterfrom
flavianh:bpo-29446-from-tkinter-import-all

Conversation

@flavianh

@flavianh flavianh commented Jul 19, 2019

Copy link
Copy Markdown

A pull request for this issue.

@ericvsmith recommended using __all__ = [name for name, obj in globals().items() if not name.startswith('_') and not isinstance(obj, types.ModuleType) and name not in {'wantobjects'}].

Also added all in submodules of tkinter.

Side note: Interestingly, idlelib/editor.py was using sys and re from tkinter instead of importing them. There may be more modules that use "from tkinter import *"

https://bugs.python.org/issue29446

@flavianh flavianh force-pushed the bpo-29446-from-tkinter-import-all branch 2 times, most recently from 55f563e to d3916dd Compare July 19, 2019 17:34
@flavianh flavianh requested a review from terryjreedy as a code owner July 19, 2019 17:34
@flavianh flavianh force-pushed the bpo-29446-from-tkinter-import-all branch from 7cf43f0 to 76c8d35 Compare July 19, 2019 17:41
Comment thread Lib/tkinter/__init__.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

_default_root should never be imported, neither implicitly, nor implicitly.

_cnfmerge should not be imported implicitly since it is an internal function.

@flavianh flavianh Jul 19, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

_default_root is already imported in tkinter.simpledialog and _cnfmerge is used in dialog.py

For _cnfmerge the change is straightforward: I just have to omit it in __all__ and the import in dialog.py will work just fine

For _default_root I don't know how to remove it from simpledialog.py without affecting the behaviour of _QueryDialog. I can't leave parent as None if no parent is passed because then the line if parent.winfo_viewable(): will fail.

Same in font.py.

I updated the PR to not export _cnfmerge and _default_root in __all__, but could not prevent _default_root from being used elsewhere.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No, it is not imported, but is accessed as an attribute of tkinter.

The difference is that its value is changed after importing. When you import the submodule, it is None. After creating a root widget it keeps a reference to it, which can be used as a default parent in _QueryDialog.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the clarification!

Comment thread Lib/tkinter/__init__.py Outdated
Comment thread Lib/tkinter/__init__.py Outdated
Comment thread Lib/tkinter/__init__.py Outdated
Comment thread Lib/tkinter/constants.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is an unrelated change.

@flavianh flavianh Jul 19, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

True, I dismissed those changes. Can I open a new PR to add this change?

Comment thread Lib/tkinter/dialog.py Outdated
Comment thread Lib/tkinter/filedialog.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could not this be written in one line?

@flavianh flavianh Jul 19, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I was unsure about the code style here. What's the standard?
I reworked the imports though, so there might not be any problem any more

Comment thread Lib/tkinter/tix.py Outdated

@terryjreedy terryjreedy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Flavian, thank you for making a start on this; As for changes, I pretty much agree with Serhiy.
1 Use Eric's suggestion for things defined in .__init__ and exclude submodules.
2. Make lists horizontal, with multiple items per line (this is pretty standard).
3. Put PEP 8 style changes in another PR, or even another issue; but only after asking Serhiy if he wants them, or at least would merge them.
4. I never wrote about submodules, but __all__ for each, except Tix (leave alone), would be nice.

@bedevere-bot

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Comment thread Misc/NEWS.d/next/Library/2019-07-19-16-06-48.bpo-29446.iXGuoi.rst Outdated
@terryjreedy

Copy link
Copy Markdown
Member

With respect to the list in your initial comment: The 'Var's are absolutely essential. Without checking idlelib, I presume the other non-underscore names you list there are used also.

@flavianh flavianh force-pushed the bpo-29446-from-tkinter-import-all branch from 94460f3 to 7037f85 Compare July 19, 2019 22:41
@flavianh

Copy link
Copy Markdown
Author

I have made the requested changes; please review again

@bedevere-bot

Copy link
Copy Markdown

Thanks for making the requested changes!

@terryjreedy: please review the changes made to this pull request.

Comment thread Lib/tkinter/__init__.py Outdated
Comment thread Lib/tkinter/colorchooser.py Outdated
Comment thread Lib/tkinter/commondialog.py Outdated
Comment thread Lib/tkinter/dnd.py Outdated
Comment thread Lib/tkinter/filedialog.py Outdated
Comment thread Lib/tkinter/scrolledtext.py Outdated
Comment thread Lib/tkinter/simpledialog.py Outdated
Comment thread Lib/tkinter/test/test_tkinter/test_misc.py Outdated
Comment thread Lib/tkinter/test/test_tkinter/test_misc.py Outdated
Comment thread Misc/ACKS Outdated
@flavianh flavianh force-pushed the bpo-29446-from-tkinter-import-all branch 2 times, most recently from 0cdd92a to 5180d87 Compare July 20, 2019 09:09
Comment thread Lib/tkinter/font.py Outdated

@flavianh flavianh Jul 20, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Had to move __version__ here to abide to PEP8 also

@flavianh

flavianh commented Jul 20, 2019

Copy link
Copy Markdown
Author

@serhiy-storchaka All your comments should now be addressed!

@flavianh

Copy link
Copy Markdown
Author

@terryjreedy @serhiy-storchaka Anything blocking?

@terryjreedy terryjreedy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Serhiy is responsible for final details of tkinter/* changes.

Comment thread Lib/idlelib/editor.py Outdated
Comment thread Lib/tkinter/filedialog.py Outdated
Flavian Hautbois and others added 2 commits July 24, 2019 11:11
The expression `from tkinter import *` actually imports re, enum, sys, as well as tkinter functions and classesreserved for internal use. This commit dismisses most of those names by defining the __all__ variable  in accordance with the documentation in tkinter and its submodules.
@flavianh flavianh force-pushed the bpo-29446-from-tkinter-import-all branch from 7ea2ce5 to 2345535 Compare July 24, 2019 09:13
@flavianh flavianh force-pushed the bpo-29446-from-tkinter-import-all branch from 2345535 to e9cae4f Compare July 24, 2019 09:36
@flavianh

Copy link
Copy Markdown
Author

@terryjreedy I had to remove your commit "Move editor.py changes to another PR for full backport" because it was undoing your own changes when I rebased on master ;)

@terryjreedy

Copy link
Copy Markdown
Member

Serhiy, as near as I can tell, this is ready to go. If you agree, it would be nice to get it into a3, due next Monday.

Comment thread Lib/tkinter/commondialog.py
Comment thread Lib/tkinter/font.py Outdated
import tkinter

__version__ = "0.9"
__all__ = ["NORMAL", "ROMAN", "BOLD", "ITALIC", "nametofont", "Font", "families",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would break a line after "ITALIC".

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sure thing. What is your rule for line breaks? I'd like to automate it in my IDE

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It is hard to automate. Semantically the first four names in this list are names of constants.

Comment thread Lib/tkinter/messagebox.py Outdated

from tkinter.commondialog import Dialog

__all__ = ["showinfo", "showwarning", "showerror", "askquestion", "askokcancel",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I suggest to break a line after "showerror".

Comment thread Lib/tkinter/filedialog.py Outdated
These interfaces were written by Fredrik Lundh, May 1997.
"""
__all__ = ["FileDialog", "LoadFileDialog", "SaveFileDialog", "Open", "SaveAs",
"Directory", "askopenfilename", "asksaveasfilename", "askopenfilenames",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This line is longer then PEP 8 limit. I would format the list like:

__all__ = ["FileDialog", "LoadFileDialog", "SaveFileDialog",
           "Open", "SaveAs", "Directory",
           "askopenfilename", "asksaveasfilename", "askopenfilenames",
           "askopenfile", "askopenfiles", "asksaveasfile", "askdirectory"]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added the 79-character line length to my IDE's configuration for cPython

@flavianh

Copy link
Copy Markdown
Author

@serhiy-storchaka Changes done ;)

@flavianh

Copy link
Copy Markdown
Author

@terryjreedy up to you :)

@terryjreedy terryjreedy merged commit 76b6451 into python:master Jul 26, 2019
@terryjreedy

terryjreedy commented Jul 26, 2019

Copy link
Copy Markdown
Member

It doesn't really matter which of us merges. I presume that this should not be backported to 3.8 because b3 is too late for new features, even all. There must be other code that will break with this change, just like IDLE did. Thank you for sticking with this.

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.

5 participants