Checking against NULL will be eliminated?

C

Claudiu Popa

Hello Python-list,


I don't know how to call it, but the following Python 3.2 code seems to raise a
FutureWarning.

def func(root=None):
nonlocal arg
if root:
arg += 1
The warning is "FutureWarning: The behavior of this method will change
in future versions. Use specific 'len(elem)' or 'elem is not None' test instead."
Why is the reason for this idiom to be changed?
 
C

Carl Banks

Hello Python-list,

I  don't  know how to call it, but the following Python 3.2 code seems to raise a
FutureWarning.

def func(root=None):
    nonlocal arg
    if root:
       arg += 1
The  warning is "FutureWarning: The behavior of this method will change
in future versions.  Use specific 'len(elem)' or 'elem is not None' test instead."
Why is the reason for this idiom to be changed?

I'm guessing root is an ElementTree Element?

The reason for this is that some element tree functions will return
None if an element is not found, but an empty element will have a
boolean value of false because it acts like a container. Some people
who use ElementTree don't always have this behavior in mind when they
are testing to see if an element was found, and will use "if element:"
when they need to be using "if element is not None:".

The larger reason is that boolean evaluation in Python tries to be too
many things: for some types is means "not zero", for some types it
means "empty", and for some types it means "this is a value of this
type as opposed to None". That causes conflicts when more than one of
those tests makes sense for a given type, as it does with Elements.

This change is only for ElementTree as far as I know. (Incidentally,
Numpy arrays are another notable type that's disabled implicit
booleans, but it did it a long time ago.)


Carl Banks
 
T

Tom Zych

The larger reason is that boolean evaluation in Python tries to be too
many things: for some types is means "not zero", for some types it
means "empty", and for some types it means "this is a value of this
type as opposed to None". That causes conflicts when more than one of
those tests makes sense for a given type, as it does with Elements.

You're right.

PEP 4000:
Proposing a new, backwards-incompatible version of Python in which
boolean evaluation
is not so overloaded.

Hmm, no, I don't think that will fly. We're stuck with it :(

Fortunately there are work-arounds for the cases that matter, as we've
seen.
Yay Python :)
 
S

Steven Howe

Back at NCR, they stressed the axiom '90% of the time is spent fixing
10% of the code'.

How true that axiom is. Never more so then when faced with a programming
language fix like PEP 4000. Fortunately for me, I never trusted python's
complex, or should I say 'overloaded' Boolean usage.

If I want to know if a string or list dictionary is empty: if ( len(x)
== 0 ).

If an item is None: if ( type(x) == types.NoneType ):

if truly Boolean and want to 'do' something on False, then I use 'not'.

I really like 'types'. Helps error checking, helps making logic flows
cleaner and less error prone. And since 'pydev/Eclipse' is so good at
finding my from/imports and inserting them for me, I use types liberally.

I guess being an old C programmer makes one a bit more cautious; nothing
worse then compiler errors, accept runtime errors. And over course, I
still use lots of parentheses to group my logic. Hell, I still do a lot
of that when using bash.

So PEP 4000, go ahead, break some over indulgent code and coders; I'm
not bothered.

Steven
 
S

Steven D'Aprano

Back at NCR, they stressed the axiom '90% of the time is spent fixing
10% of the code'.

It's not an axiom, it's a platitude. Nor is it based on any objective
evidence I've ever seen.

How true that axiom is. Never more so then when faced with a programming
language fix like PEP 4000.

Do you realise that "PEP 4000" was Tom Zych being sarcastic? There is no
PEP 4000:

http://www.python.org/dev/peps/

Fortunately for me, I never trusted python's
complex, or should I say 'overloaded' Boolean usage.

That's your loss. Just because you choose to not trust something which
works deterministically and reliably, doesn't mean the rest of us
shouldn't.

If I want to know if a string or list dictionary is empty: if ( len(x)
== 0 ).

Apart from the unnecessary length and the pointless reliance on an
implementation detail, can you please explain how the above differs from
`if not x:`?

For starters, how about giving an example of a built-in string, list or
dictionary where `if len(x) == 0` and `if x` give different results?


If an item is None: if ( type(x) == types.NoneType ):

Good grief, now that truly is astoundingly unpythonic code!

`if x is None` is the right way to do it. It is also *guaranteed* to be
correct, rather than being subject to failure-modes like this:
.... print "And now your world comes crashing down in flames!"
....
And now your world comes crashing down in flames!


No rogue libraries or functions can override the `is` operator or the
None singleton. I think it is sad that you've been writing code which is
*less* safe, in the mistaken belief that it was more safe. Perhaps you
should stop writing C in Python, and learn to write Python.

nothing
worse then compiler errors, accept runtime errors.

"I find it amusing when novice programmers believe their main job is
preventing programs from crashing. ... More experienced programmers
realize that correct code is great, code that crashes could use
improvement, but incorrect code that doesn’t crash is a horrible
nightmare."
-- Chris Smith
http://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/
 
S

Steven D'Aprano

For starters, how about giving an example of a built-in string, list or
dictionary where `if len(x) == 0` and `if x` give different results?

Er, how embarrassment... of course I mean either len(x) != 0, or not x,
take your pick.
 
T

Tom Zych

Steven said:
Do you realise that "PEP 4000" was Tom Zych being sarcastic? There is no
PEP 4000:

Eh, well, maybe 10% sarcastic, 90% facetious. Wasn't trying to give
Carl a hard time.
 
C

Carl Banks

That's your loss. Just because you choose to not trust something which
works deterministically and reliably, doesn't mean the rest of us
shouldn't.

Perl works deterministically and reliably. In fact, pretty much every
language works deterministically and reliably. Total non-argument.


Carl Banks
 
J

Jean-Michel Pichavant

Steven said:
If an item is None: if ( type(x) == types.NoneType ):
Bye the way, the beauty of python is that "If an item is None"
translates into "If item is None".

JM
 
T

Tom Zych

Carl said:
Perl works deterministically and reliably. In fact, pretty much every
language works deterministically and reliably. Total non-argument.

Well, yes. I think the real issue is, how many surprises are
waiting to pounce on the unwary developer. C is deterministic
and reliable, but full of surprises. Python is generally low
in surprises. Using "if <identifier>" is one place where you
do have to think about unintended consequences.
 
N

Neil Cerutti

Well, yes. I think the real issue is, how many surprises are
waiting to pounce on the unwary developer. C is deterministic
and reliable, but full of surprises.

Point of order, for expediency, C and C++ both include lots and
lots of indeterminate stuff. A piece of specific C code can be
totally deterministic, but the language is full of undefined
corners.
Python is generally low in surprises. Using "if <identifier>"
is one place where you do have to think about unintended
consequences.

Python eschews undefined behavior.
 
J

Jean-Paul Calderone

Point of order, for expediency, C and C++ both include lots and
lots of indeterminate stuff. A piece of specific C code can be
totally deterministic, but the language is full of undefined
corners.


Python eschews undefined behavior.

C and C++ have standards, and the standards describe what they don't
define.

Python has implementations. The defined behavior is whatever the
implementation does. Until someone changes it to do something else.

It's not much of a comparison.

Jean-Paul
 
N

Neil Cerutti

C and C++ have standards, and the standards describe what they
don't define.

Python has implementations. The defined behavior is whatever
the implementation does. Until someone changes it to do
something else.

It's not much of a comparison.

In addition, you can tap into undefined behavior in Python, as
well, it's just harder. So what I should have said is that the
determinacy of a language is a degree, not an absolute. C is less
determinate than Python by design.
 
T

Terry Reedy

C and C++ have standards, and the standards describe what they don't
define.

Python has implementations.

Python also has standards, the language and library manuals.

The defined behavior is whatever the implementation does.

No, the defined behavior for a particular version of Python
is whatever the manuals for that version say.
Ambiguities are generally removed as discovered.
Some of the ambiguites have been pointed out by authors
of alternate implementations.

The docs have a few notes as to what is not defined or
what is behavior spedific to CPython, and therefore not
part of the *language* definition.
The intent is to have a rather complete definition.

Discrepancies between doc and implementation are bugs.
The usual resolution is a behavior change.
Until someone changes it to do something else.

At which point the change is documented with a note as to when the
change was made. But this is never intentionally done as casually as you
imply. Contributions to improve test coverage so as to prevent
unintended changes are welcome.
 
C

Carl Banks

Point of order, for expediency, C and C++ both include lots and
lots of indeterminate stuff.

It's besides the point, but I'll bite. Apart from interactions with
the environment (system timer and whatnot), when does C or C++ code
ever produce indeterminate behavior?
A piece of specific C code can be
totally deterministic, but the language is full of undefined
corners.

C and C++ have plenty of behaviors that are undefined, implementation
defined, etc. But that is not the same thing as indeterminate.
Determinate means when you compile/run the code it does the same thing
every time (more or less). When run a program and it does one thing,
then you run it again and it does something else, it's indeterminate.

I actually can think of one indeterminate behavior in C (although it's
not certain whether this qualifies as interaction with the
environment):

int main(void) {
int a;
printf("%d\n",a);
}

The C standard allows the memory a refers to to be uninitialized,

OTOH this

int main(void) {
a = 1;
 
C

Carl Banks

[snip]

Accidental post before I was done. To complete the thought:

I actually can think of one indeterminate behavior in C (although it's
not certain whether this qualifies as interaction with the
environment):

int main(void) {
    int a;
    printf("%d\n",a);
return 0;
}

The C standard allows the memory a refers to to be uninitialized,
meaning that a's value is whatever previously existed in that memory
slot, which could be anything.

OTOH this program:

int main(void) {
    int a = 1;
a = a++;
printf("%d\n",a);
return 0;
}

is undefined, which I guess technically could mean that compiler could
output an indeterminate result, but I doubt there are any compilers
that won't output the same value every time it's run.


Carl Banks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top