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

Nick Coghlan ncoghlan at gmail.com
Sat Oct 10 17:30:51 CEST 2009


Steven D'Aprano wrote:
>> while the third 
>> is a warning issued due to the fact that using "import *" inside a
>> function is a really bad idea (at the very least, it forces the
>> compiler to disable all of its normal local variable optimisations,
>> as it has no idea what local variable names are going to exist after
>> that import statement executes).
> 
> It's actually a warning that the functionality is in the process of 
> being removed.

<from other thread>
> `import *` inside a function is illegal in Python3. It's a warning in 
> Python2.x only because of backwards compatibility. This was the primary 
> use-case for the warning module in the first place: to warn when 
> functionality is being deprecated and will be removed in the future.

However, this particular warning has nothing to do with Py3k, as it has
been present at least since the AST branch was merged back in 2005.

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.

This was a case of generating a warning for legal syntax that the
compiler could handle because the developers considered it dubious. It
was just considered so dubious that the warning was upgraded to a
SyntaxError for Py3k.

> 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.

A visual grouping technique that can easily be handled with vertical
whitespace or comments isn't even close to being in the same league as
the legitimate use cases for import * at module level.

> Why single out always-true tuples for a warning, when other always-true 
> items are considered legitimate, even when there is no ambiguity about 
> what the programmer meant? This sort of inconsistency makes little 
> sense and should stand as a cautionary tale for people putting warnings 
> in the compiler: sometimes the warning is *bad advice*:

That's why it says "perhaps remove" rather than "remove". That hint also
indicates the developer error that it is actually trying to warn against:

assert (longAndComplicatedAssertionCondition,
        "My assertion message")

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). You have to either use a
backslash for the line continuation here, or else ensure the comma is
outside the parentheses:

assert longAndComplicatedAssertionCondition, \
        "My assertion message"

assert longAndComplicatedAssertionCondition, (
        "My assertion message")

In that context, the syntax warning turns what could be a very obscure
and hard to debug problem into something fairly obvious (as the only
parentheses present will be the ones that are causing the comma to be
misinterpreted).

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?

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). A SyntaxWarning
built directly into the compiler would hopefully give them the hint they
need in order to realise that they don't actually know what is going on.
("break? What does break have to do with using else on a loop? Hmm,
maybe I better look this up or ask someone about it...").

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------



More information about the Python-ideas mailing list