On Sat, Sep 05, 2020 at 04:00:40PM +0900, Stephen J. Turnbull wrote:
Jeffrey Kintscher writes:
"from foo import *" is a really lazy programming practice
However much corporate policies and educators may deprecate widely adopted coding practices, complaining about them will get you disliked, and nothing else.
*scratches head in confusion*
Since when did `from foo import *` suddenly become a widely adopted coding practice?
Everyone I know agrees that (with very few exceptions) we should avoid star imports. I don't know anyone who argues in favour of star imports in the general case. It is permitted, but not encouraged.
PEP 8 strongly discourages it:
Google bans it, allowing only imports of modules:
(Some conditions apply, but nothing that would allow wildcard imports.)
Linters warn about it:
The community seems to be in agreement that, for the most part, wildcard imports should be avoided, e.g.
and people have written tools to replace them:
Of course it is right and proper that people should be permitted to use wildcard imports. Consenting Adults applies.
But I am perplexed that people seem to be arguing that we can't add new names to modules because that would break code that does a wildcard import from that module. When did that become a thing?
I'm perplexed because, firstly, we have never guaranteed that modules won't add new names to their namespace. *Removing* names is a backwards- incompatible change. *Adding* names is not.
Python 3.9 added numerous new names to modules, including:
- ast.unparse - four new functions to the curses module - two new constants to fcntl - math.nextafter and .ulp
Secondly, in practice people do their wildcard imports at the start of the module, so they can make use of those names in their script or application:
from tkinter import * window = Tk()
If the module adds a new name that you aren't expecting and aren't using, it just sits there harmlessly in your application's namespace. It doesn't prevent you using that name for your own purposes, so it can't break your code unless you do the star import after other imports or definitions.
Sure, you can do that star import in the middle of your code. But consenting adults applies. If you do that, you're supposed to know what you are doing.
So we seem to be worrying about a non-problem here. Adding a new Infinity name to builtins, or some other module, won't break backwards compatibility.
But what will break backwards compatibility is either:
- making Infinity a keyword, like None;
- or changing the repr of math.inf to 'Infinity'.
Also someone needs to explain how to avoid the debacle that was the the name collisions with True and False when the bool type was introduced.
What debacle are you referring to? Are you referring to the addition of the bools in the 2.2.1 bugfix release?
If so, we avoid that these days by just not adding new features to bugfix releases.
I don't know what name collisions you are referring to. In 2.2.1, new builtins bool (a function), True (the int 1) and False (the int 0) where added to allow people to backport code written for 2.3 which contained the proper bool type and special True/False singletons.
Adding these didn't cause name collisions. If your module already included globals
False = 0 True = not False
they would quitely and harmlessly shadow the builtins and all was well.
The whole transition was remarkable smooth:
- PEP 285 introduced a new builtin bool type, with two named singletons True and False;
- a bool *function*, with two named values True=1 and False=0, were retroactively added to 2.2.1 (adding these to a bugfix release was an annoyance, but hardly a debacle);
- and the True and False names didn't become keywords until Python 3.
See here for more background on it: