I propose that in Py3.0, the "and" and "or" operators be simplified to
always return a Boolean value instead of returning the last evaluated
1) The construct can be error-prone. When an error occurs it can be
invisible to the person who wrote it. I got bitten in published code
that had survived testing and code review:
'Return a vector with the real part of each input element'
# do not convert integer inputs to floats
return self.map(lambda z: type(z)==types.ComplexType and z.real or
The code fails silently when z is (0+4i). It took a good while to trace
down a user reported error (when Matlab results disagreed with my matrix
module results) and determine that the real() method contained an error.
Even when traced down, I found it hard to see the error in the code.
Now that I know what to look for, it has not happened again, but I do
always have to stare hard at any "and/or" group to mentally verify each
2) When going back and forth between languages, it is easy to forget
that only Python returns something other than a boolean.
3) Even when it isn't being used, the possibility of non-boolean return
value complicates the bytecode and parser. To allow for "and/or", the
conditional opcodes leave the tested value on the stack. In most cases
both branches go directly to a POP_TOP instruction. Since the POP_TOP
shouldn't be executed twice, the body of the positive branch has to
close with a jump over the other branch even when it is empty. For
instance, the simplest case:
1 0 LOAD_NAME 0 (a)
3 JUMP_IF_FALSE 8 (to 14)
2 7 LOAD_NAME 1 (b)
11 JUMP_FORWARD 1 (to 15)
>> 14 POP_TOP
>> 15 LOAD_CONST 0 (None)
this could be simpler and faster:
1 0 LOAD_NAME 0 (a)
3 JUMP_IF_FALSE 8 (to 10)
2 6 LOAD_NAME 1 (b)
>> 10 LOAD_CONST 0 (None)
Executive summary. Returning only Booleans reduces errors, makes the
code easier to review, follows other language norms, and
simplifies/speeds-up the generated code.
P.S. Simplifying "and" and "or" may create a need to introduce a
conditional operator but that is a discussion for another day.
On several occasions I have seen tracebacks in my code pointing to PIL's
__init__.py file. That is strange, because I have installed PIL but it
is used nowhere.
Finally I traced it down to a problem in the linecache code, which tries
to be smart in up updatecache function. When os.stat() on the filename
fails with os.error, it walks along sys.path and returns the first file
with a matching basename. This *may* make sense for toplevel modules,
but never for modules in packages.
So, if the traceback's stack contains an entry for a non-existing file
(for example because the .py file for a .pyc file is no longer present),
linecache returns absolute garbage.
Example, on my system (the \a\b\c\__init__.py file doesn't exist):
C:\>python -c "import linecache; print linecache.getlines(r'\a\b\c\__init__.py')"
['#\n', '# The Python Imaging Library.\n',
'# $Id: //modules/pil/PIL/__init__.py#2 $\n', '#\n',
'# package placeholder\n', '#\n', '# Copyright (c) 1999 by Secret Labs AB.\n',
'#\n', '# See the README file for information on usage and redistribution.\n',
'#\n', '\n', '# ;-)\n']
The bug is present in 2.3, 2.4, and current CVS.
The following Python script causes Python 2.3, 2.4 and the latest CVS
to crash with a Segmentation Fault:
x = u'<?xml version="1.0"?>\n<fran\xe7ais>Comment \xe7a va ? Tr\xe8s
dom = xml.dom.minidom.parseString( x.encode( 'latin_1' ) )
print repr( dom.childNodes.localName )
The problem is that this XML document does not specify an encoding. In
this case, minidom assumes that it is encoded in UTF-8. However, in
fact it is encoded in Latin-1. My two line patch, in the SourceForge
tracker at the URL below, causes this to raise a UnicodeDecodingError
Any chance that someone wants to commit this tiny two line fix? This
might be the kind of fix that might be elegible to be backported to
Python 2.4 as well. It passes "make test" on both my Linux system and
my Mac. I've also attached a patch that adds this test case to
Guido van Rossum wrote:
> Congratulations gracefully accepted.
Whilst I'm not personally fond of the syntax, congratulations. Whilst I
don't feel this is a big step in the evolution of the language, it shuts
up a *very* frequently asked question (and opens up a new one ;)
[ongoing discussion of conditional expressions]
I waited until I had caught up on my reading before saying anything. Now I'll
express my opinion in a single posting then keep quiet unless I actually find I
have something novel to contribute (difficult in a topic that's been talked to
death 3 or 4 times in the past few years).
* I am STRONGLY in favor of introducing a conditional expression in some
form. The use of the "and-or" trick is proof enough to me that there is
a need for it. I can marshall other arguments also, but they appear
* The syntax to use is a place where we need a BDFL decision. Make the
decision and we'll all agree and move on. Any decision would be better
than an eternity of re-discovering old ideas again and again.
* I think the two best options are
trueval if cond else falseval
if cond then trueval else falseval
The first has brevity in it's favor, and "cleverness" which might be
an advantage or disadvantage depending on your point of view. The
second has order-of-arguments in its favor. In either case, wise
programmers will use parenthesees when it aids clarity (imagine
"v1 if c else v2 + v3"). Whether we require parenthesees when the
parser could disambiguate on its own is really up to Guido.
* I prefer the second form ("if cond then trueval else falseval")
because it puzzles _nobody_ at the expense of being slightly
more wordy and less clever. But that's just one person's opinion.
Thanks Guido, for maintaining your patience in the face of this
-- Michael Chermside
At 09:49 AM 9/29/2005 -0400, Viren Shah wrote:
>[I sent this earlier without being a subscriber and it was sent to the
>moderation queue so I'm resending it after subscribing]
> I'm running a 64-bit Fedora Core 3 with python 2.3.4. I'm trying to
> install setuptools to use with Trac, and get the following error:
> [root@Mrdumpling ~]$ python ez_setup.py
>Traceback (most recent call last):
> File "ez_setup.py", line 206, in ?
> File "ez_setup.py", line 141, in main
> from setuptools.command.easy_install import main
>OverflowError: signed integer is greater than maximum
>I get the same type of error if I try installing setuptools manually. I
>figure this has to do with the 64-bit nature of the OS and python, but not
>being a python person, don't know what a workaround would be.
Hm. It sounds like perhaps the 64-bit Python in question isn't able to
read bytecode for Python from a 32-bit Python version. You'll need to
download the setuptools source archive from PyPI and install it using
"python setup.py install" instead.
In the meantime, I'm going to inquire on Python-Dev about whether a 64-bit
Python should be able to read 32-bit bytecode, as I was under the
impression Python's bytecode format was supposed to be cross-platform. See
Guido van Rossum wrote:
file = os.path.abspath(file) if file else '?'
These are all unreadable. In C "a ? b : c" is not used very often. A
quick check of the Python source found 476 occurences.
-1 to conditional expressions.
a general question. Consider:
def __setitem__(self, index, item):
# do something with index and item
return list.__setitem__(self, index, item)
lst = A([1,set()])
lst |= 1
lst |= set()
Do we want lst.__setitem__ to be called in the second inplace assignment?
A case where this matters is here: http://python.org/sf/1306777
Mail address is perfectly valid!