Names changed to protect the guilty

John Machin sjmachin at lexicon.net
Sat Oct 7 08:06:54 CEST 2006


Aahz wrote:
> In article <1160182951.812677.178750 at i42g2000cwa.googlegroups.com>,
> MonkeeSage <MonkeeSage at gmail.com> wrote:
> >On Oct 6, 6:27 pm, a... at pythoncraft.com (Aahz) wrote:
> >>
> >> The following line of lightly munged code was found in a publicly
> >> available Python library...
> >
> >Yes, this violates the Holy, Inspired, Infallible Style Guide (pbuh),
> >which was written by the very finger of God when the world was still in
> >chaotic darkness.
>
> Did you actually analyze the line of code?  Particularly WRT the way it
> operates in different versions of Python?

A comment on the "style" issue, before we get into the real WTF
analysis: any function/method whose name begins with "has" or "is"
returns an honest-to-goodness actual bool (or what passed for one in
former times). IMHO, any comparison with [] being regarded as false and
[0] being regarded as true is irrelevant, and writing "has_something()
== False" or "has_something() is False" is utterly ludicrous.

Now back to the analysis. Empirical evidence, back as far as 2.1:

C:\junk>type isfalse.py
import sys
print sys.version
try:
    False
    print "False is defined; type: %r; value: %r" \
        % (type(False), False)
except NameError:
    print "defining: False = 0; True = 1"
    False = 0
    True = 1
adict = {1: 42}
v = adict.has_key(2)
print "'adict.has_key(2)' ->", v
print "'adict.has_key(2) == False' ->", v == False
print "'adict.has_key(2) is False' ->", v is False
try:
    1 in adict
    print "'key in adict' is available"
except TypeError, e:
    print "Need to use 'adict.has_key(key)'"
    print "'key in adict' -> %s" % e


C:\junk>for %1 in (5 4 3 2 1) do \python2%1\python isfalse.py

C:\junk>\python25\python isfalse.py
2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)]
False is defined; type: <type 'bool'>; value: False
'adict.has_key(2)' -> False
'adict.has_key(2) == False' -> True
'adict.has_key(2) is False' -> True
'key in adict' is available

C:\junk>\python24\python isfalse.py
2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)]
False is defined; type: <type 'bool'>; value: False
'adict.has_key(2)' -> False
'adict.has_key(2) == False' -> True
'adict.has_key(2) is False' -> True
'key in adict' is available

C:\junk>\python23\python isfalse.py
2.3.5 (#62, Feb  8 2005, 16:23:02) [MSC v.1200 32 bit (Intel)]
False is defined; type: <type 'bool'>; value: False
'adict.has_key(2)' -> False
'adict.has_key(2) == False' -> True
'adict.has_key(2) is False' -> True
'key in adict' is available

C:\junk>\python22\python isfalse.py
2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)]
False is defined; type: <type 'int'>; value: 0
'adict.has_key(2)' -> 0
'adict.has_key(2) == False' -> 1
'adict.has_key(2) is False' -> 0
'key in adict' is available

C:\junk>\python21\python isfalse.py
2.1.3 (#35, Apr  8 2002, 17:47:50) [MSC 32 bit (Intel)]
defining: False = 0; True = 1
'adict.has_key(2)' -> 0
'adict.has_key(2) == False' -> 1
'adict.has_key(2) is False' -> 1
Need to use 'adict.has_key(key)'
'key in adict' -> 'in' or 'not in' needs sequence right argument

Analysis depends on what range of Python versions the author purported
to be supporting:
(1) back to 2.3: bad style, no damage, but why not use "key in dict"?
(2) back to 2.2: bad style, *WRONG ANSWER*; why not use "key in dict"?
(3) back to 2.1: as above for 2.2; would not work in 2.1 without the
demonstrated band-aid. Note that the simple "if not
adict.has_key(key):" construct works happily (if a trifle slowly) in
all 5 versions.

HTH,
John




More information about the Python-list mailing list