[Python-ideas] SyntaxWarning for for/while/else without break or return?

Steven D'Aprano steve at pearwood.info
Sun Oct 11 04:56:39 CEST 2009

On Sun, 11 Oct 2009 02:30:51 am Nick Coghlan wrote:

> import * at function level is genuinely harmful because of the effect
> it has on the compiler on top of the effect it has on readability. It
> makes sense to warn about it.

Right. It's so dangerous that it's becoming illegal. You can't just turn 
language features illegal overnight, you have to go through a period of 
deprecation. This makes perfect sense, and is the primary use-case for 
warnings in Python.

> > Even though `import *` at the module level is a frequent source of
> > bugs and confusion even for experienced coders, and the usual
> > advice is Just Don't Do It, Python does not generate a warning for
> > that case.
> Actually, we don't generate a warning for this because there are
> significant legitimate use cases for import * at the module level
> that can't be handled any other way (the two that immediately come to
> mind are for convenience at the interactive prompt and for bringing
> in methods and classes from an optional acceleration module as
> happens in a number of standard library modules). We can hardly
> generate a warning for constructs that we use ourselves.

Of course we can. But we shouldn't, it would be silly.

The point is that there are many language features that are pointless, 
silly or troublesome, and we don't -- and shouldn't -- raise warnings 
for them. I don't see for...else to be exceptional enough to deserve a 
language warning.

> That's not an assert statement using parentheses purely for line
> continuation - it's an assertion of a 2-tuple that will never fail,
> and a naive user may not realise what is happening (thus getting very
> confused when their assert statement appears to pass, but subsequent
> code relying on that assertion fails anyway).

I don't believe the language should be hand-holding the naive user to 
that extent. What do we do, fill the compiler up with a thousand 
warnings for things which might confuse some naive user? What ever 
happened to "We're all adults here"? The solution to naive users is for 
the user to learn more about the language and be less naive, not for 
the language to hold his hand. The compiler isn't your babysitter, and 
Python isn't meant to be a teaching language for kiddies.

The proliferation of warnings leads to complacently among naive users 
("I don't need to understand this feature to use it, the compiler will 
warn me if I do something wrong") and, much worse, overload among 
non-naive users ("it's just another damn warning, ignore it, the 
compiler is just complaining about nothing"). In my opinion, we've 
already taken too many steps down this path, lets not go any further.

> The warning could probably be refined such that it only triggers for
> a 2-tuple as the sole argument to an assert statement, but how often
> is such a false triggering actually going to happen in real code
> rather than dummy examples?

It's a bug -- it is output that is generated unnecessarily. Defending it 
on the basis that it's a rare bug is not a wise idea.

> For the loop else clauses, the users who are going to get themselves
> into trouble are the ones who *think* they know what it means, but
> actually don't (i.e. not the sort of people that are likely to be
> regularly running pylint or pychecker over their code).

You can't protect ignorant, naive and downright stupid users against 
themselves. It's a never-ending problem.

Perhaps we should raise a warning when the user says:

for in in range(len(sequence)):

SyntaxWarning: There's probably a better way to do this.

or for list.insert?

PerformanceWarning: This may be slow for large lists.

You may think I'm exaggerating, but Python already does something 
similar, only worse. The built-in sum() prohibits summing strings 
because it may be O(N**2) -- even though in recent versions of CPython, 
it may not be, even though for small numbers of small strings it makes 
no practical difference, and even though it allows O(N**2) summation of 
lists! A naive user will be lulled into a false sense of security that 
sum(list_of_lists, []) is fine, and an advanced user who wants to use 
sum() as a teaching aid to show how repeated string concatenation is 
slow is frustrated.

Steven D'Aprano

More information about the Python-ideas mailing list