This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Remove import * recommendations and examples in doc?
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.4, Python 3.5, Python 2.7
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: docs@python, georg.brandl, mark.dickinson, rhettinger, terry.reedy, tshepang, willingc
Priority: normal Keywords:

Created on 2014-10-06 20:23 by terry.reedy, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg228734 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-10-06 20:23
PEP 8 recommends against 'from mod import *' because it makes reading harder and is bad for code analysis.  My experience with retrofitting tests to idlelib modules with tkinter * imports is that it also makes testing harder since the testing strategy depends on the specific tkinter objects actually used.  So either an explicit list ('from tkinter import x, y, z') or a searchable prefix ('tk.') makes testing easier.  

Some time ago, 'from tkinter import *' was changed to 'import tkinter as tk' in the tkinter doc examples, though *not* the text.  ##10031 changed the import section of the FAQ to "remove the advice to use "from ... import *" with some modules" (from the commit message).  Should we finish the job?  Or leave the issue to individual chapter authors?

Here is the edited result of grepping 'import *' in ...\py34\Doc\*.rst with Idle.

F:\Python\dev\4\py34\Doc\distutils\apiref.rst: 1289: This module is safe to use in ``from ... import *`` mode; it only exports
F:\Python\dev\4\py34\Doc\library\cmd.rst: 234:     from turtle import *
F:\Python\dev\4\py34\Doc\library\collections.abc.rst: 14:    from collections import *
F:\Python\dev\4\py34\Doc\library\collections.rst: 11:     from collections import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 54:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 86:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 320:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 562:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 671:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 695:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 714:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 914:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 1074:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\ctypes.rst: 1122:    >>> from ctypes import *
F:\Python\dev\4\py34\Doc\library\decimal.rst: 20:    from decimal import *
F:\Python\dev\4\py34\Doc\library\decimal.rst: 56:      >>> from decimal import *
F:\Python\dev\4\py34\Doc\library\decimal.rst: 125:    >>> from decimal import *
F:\Python\dev\4\py34\Doc\library\difflib.rst: 13:    from difflib import *
F:\Python\dev\4\py34\Doc\library\itertools.rst: 12:    from itertools import *
F:\Python\dev\4\py34\Doc\library\stat.rst: 104:    from stat import *
F:\Python\dev\4\py34\Doc\library\statistics.rst: 13:    from statistics import *
F:\Python\dev\4\py34\Doc\library\struct.rst: 313:    >>> from struct import *
F:\Python\dev\4\py34\Doc\library\tkinter.rst: 63:    from tkinter import *
F:\Python\dev\4\py34\Doc\library\tkinter.rst: 580:    from tkinter import *
F:\Python\dev\4\py34\Doc\library\tkinter.tix.rst: 60:       from tkinter.constants import *
F:\Python\dev\4\py34\Doc\library\tkinter.ttk.rst: 38:    from tkinter import *
F:\Python\dev\4\py34\Doc\library\tkinter.ttk.rst: 39:    from tkinter.ttk import *
F:\Python\dev\4\py34\Doc\library\turtle.rst: 11:    from turtle import *

F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 102:    >>> from fibo import *
F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 461: Now what happens when the user writes ``from sound.effects import *``?  Ideally,
F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 470: list of module names that should be imported when ``from package import *`` is
F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 479: This would mean that ``from sound.effects import *`` would import the three
F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 482: If ``__all__`` is not defined, the statement ``from sound.effects import *``
F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 493:    from sound.effects import *
F:\Python\dev\4\py34\Doc\tutorial\modules.rst: 501: patterns when you use ``import *``, it is still considered bad practise in
F:\Python\dev\4\py34\Doc\tutorial\stdlib2.rst: 372:    >>> from decimal import *

I removed the reference hits that simply explain.  I have not looked at whether the tutorial goes beyond explanation, but should this even be mentioned in so many places?
msg228756 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-07 08:40
I think it's fine to recommend using (for example) `>>> from decimal import *` at the command-line prompt when experimenting with a module.  It's a quick way to get yourself into a state where you can easily experiment with that module and its features.

That's not the same as recommending that scripts using the decimal module start with "from decimal import *", of course.
msg229123 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2014-10-12 07:19
Many of these (such as collections, collections.abc, decimal, and itertools) use import * as part of the doctest setup and are not part of the generated page shown to users.

Also, I don't think you should be aggressive about removing the other example that are visible users.   The "import *" construct is part of the language and will be encountered occasionally.

For similar reasons, the decimal module was specifically designed for be easily usable with "import *" because of the numerous exceptions and rounding flags and constants.

There are also some examples such the one in cmd.rst that I put there on-purpose.  Changing it would distract from the focus of the example.

With respect to Tkinter (and other gui toolkits as well), I believe that "import *" is a standard or common practice, in part because there are so many widget names names and widget options.  Changing the example might make it more pep8-ish but would result in a good deal of clutter that isn't the normal practice.


>  Should we finish the job?  Or leave the issue to
> individual chapter authors?

I vote for leaving any changes to the chapter authors who are in a better position to know that they were trying to communicate or who were just setting up the doctests.   As discussed above some of the import * are there for a reason.

We really need to start thinking of PEP 8 as something we do to our own code rather than something that gets inflicted on other people's code.
msg319740 - (view) Author: Carol Willing (willingc) * (Python committer) Date: 2018-06-16 14:34
Hi @terry.reedy @rhettinger,

I'm triaging the 'turtle' open issues. I'm wondering if we can close this issue with a resolution of "Remind". If there are '*' imports that folks feel strongly about changing, then those could be opened now or in the future as a new, more narrowly scoped issue(s) with cleared next actions for contributors.
msg319760 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2018-06-16 16:47
I am going to accept Raymond's rejection of a general change.  I will reconsider the tkinter doc should I ever work on it.

For IDLE code, I have settled on 'from tkinter import Tk, Text, ..., perhaps followed by 'from tkinter.ttk import Scrollbar, ...'.  But having alternate sources for many modules is a special case.  Listing each object is a bit more effort*, but I like knowing what is imported, from where after reading the module header. (* With complete tests, NameErrors quickly expose omissions.)

Carol, thank you for bumping this issue.
History
Date User Action Args
2022-04-11 14:58:08adminsetgithub: 66761
2018-06-16 16:47:27terry.reedysetstatus: open -> closed
type: enhancement
messages: + msg319760

resolution: rejected
stage: needs patch -> resolved
2018-06-16 14:34:45willingcsetnosy: + willingc
messages: + msg319740
2014-10-12 07:19:47rhettingersetassignee: docs@python -> rhettinger

messages: + msg229123
nosy: + rhettinger
2014-10-12 05:23:09tshepangsetnosy: + tshepang
2014-10-07 08:40:23mark.dickinsonsetnosy: + mark.dickinson
messages: + msg228756
2014-10-06 20:23:24terry.reedycreate