Here's one final posting of PEP 285. I've read (or at least skimmed)
all feedback that was on our news server by 9:30am EST on April 2nd,
plus anything mailed directly to me or to python-dev until now.
There was a lot of negative feedback, but there was also a lot of
support for the PEP. The feedback made it easy to decide on most of
the smaller issues in the review section of the PEP as previously
posted: even reviewers who were against the PEP mostly supported my
preferences for the various details.
Despite the negative feedback, I've decided to accept the PEP. The
most important perceived problem is that newbies tend to write
if x == True: ...
where they should write
if x: ...
I believe this problem should be solved by education (the Zen master
hits the student on the head with a stick, and the student gets
enlightenment) rather than by holding back what I believe will be a
useful feature. You can expect the bool type in Python 2.3; it will
be in CVS tonight.
--Guido van Rossum (home page: http://www.python.org/~guido/)
Title: Adding a bool type
Version: $Revision: 1.20 $
Last-Modified: $Date: 2002/04/03 22:11:05 $
Author: guido(a)python.org (Guido van Rossum)
Type: Standards Track
Post-History: 8-Mar-2002, 30-Mar-2002, 3-Apr-2002
This PEP proposes the introduction of a new built-in type, bool,
with two constants, False and True. The bool type would be a
straightforward subtype (in C) of the int type, and the values
False and True would behave like 0 and 1 in most respects (for
example, False==0 and True==1 would be true) except repr() and
str(). All built-in operations that conceptually return a Boolean
result will be changed to return False or True instead of 0 or 1;
for example, comparisons, the "not" operator, and predicates like
I've collected enough feedback to last me a lifetime, so I declare
the review period officially OVER. I had Chinese food today; my
fortune cookie said "Strong and bitter words indicate a weak
cause." It reminded me of some of the posts against this
Anyway, here are my BDFL pronouncements. (Executive summary: I'm
not changing a thing; all variants are rejected.)
1) Should this PEP be accepted?
There have been many arguments against the PEP. Many of them
were based on misunderstandings. I've tried to clarify some of
the most common misunderstandings below in the main text of the
PEP. The only issue that weighs at all for me is the tendency
of newbies to write "if x == True" where "if x" would suffice.
More about that below too. I think this is not a sufficient
reason to reject the PEP.
2) Should str(True) return "True" or "1"? "1" might reduce
backwards compatibility problems, but looks strange.
(repr(True) would always return "True".)
Almost all reviewers agree with this.
3) Should the constants be called 'True' and 'False' (similar to
None) or 'true' and 'false' (as in C++, Java and C99)?
=> True and False.
Most reviewers agree that consistency within Python is more
important than consistency with other languages.
4) Should we strive to eliminate non-Boolean operations on bools
in the future, through suitable warnings, so that for example
True+1 would eventually (in Python 3000) be illegal?
There's a small but vocal minority that would prefer to see
"textbook" bools that don't support arithmetic operations at
all, but most reviewers agree with me that bools should always
allow arithmetic operations.
5) Should operator.truth(x) return an int or a bool?
Tim Peters believes it should return an int, but almost all
other reviewers agree that it should return a bool. My
rationale: operator.truth() exists to force a Boolean context
on its argument (it calls the C API PyObject_IsTrue()).
Whether the outcome is reported as int or bool is secondary; if
bool exists there's no reason not to use it. (Under the PEP,
operator.truth() now becomes an alias for bool(); that's fine.)
6) Should bool inherit from int?
In an ideal world, bool might be better implemented as a
separate integer type that knows how to perform mixed-mode
arithmetic. However, inheriting bool from int eases the
implementation enormously (in part since all C code that calls
PyInt_Check() will continue to work -- this returns true for
subclasses of int). Also, I believe this is right in terms of
substitutability: code that requires an int can be fed a bool
and it will behave the same as 0 or 1. Code that requires a
bool may not work when it is given an int; for example, 3 & 4
is 0, but both 3 and 4 are true when considered as truth
7) Should the name 'bool' be changed?
Some reviewers have argued for boolean instead of bool, because
this would be easier to understand (novices may have heard of
Boolean algebra but may not make the connection with bool) or
because they hate abbreviations. My take: Python uses
abbreviations judiciously (like 'def', 'int', 'dict') and I
don't think these are a burden to understanding. To a newbie,
it doesn't matter whether it's called a waffle or a bool; it's
a new word, and they learn quickly what it means.
One reviewer has argued to make the name 'truth'. I find this
an unattractive name, and would actually prefer to reserve this
term (in documentation) for the more abstract concept of truth
values that already exists in Python. For example: "when a
container is interpreted as a truth value, an empty container
is considered false and a non-empty one is considered true."
8) Should we strive to require that Boolean operations (like "if",
"and", "not") have a bool as an argument in the future, so that
for example "if :" would become illegal and would have to be
writen as "if bool():" ???
Some people believe that this is how a language with a textbook
Boolean type should behave. Because it was brought up, others
have worried that I might agree with this position. Let me
make my position on this quite clear. This is not part of the
PEP's motivation and I don't intend to make this change. (See
also the section "Clarification" below.)
Most languages eventually grow a Boolean type; even C99 (the new
and improved C standard, not yet widely adopted) has one.
Many programmers apparently feel the need for a Boolean type; most
Python documentation contains a bit of an apology for the absence
of a Boolean type. I've seen lots of modules that defined
constants "False=0" and "True=1" (or similar) at the top and used
those. The problem with this is that everybody does it
differently. For example, should you use "FALSE", "false",
"False", "F" or even "f"? And should false be the value zero or
None, or perhaps a truth value of a different type that will print
as "true" or "false"? Adding a standard bool type to the language
resolves those issues.
Some external libraries (like databases and RPC packages) need to
be able to distinguish between Boolean and integral values, and
while it's usually possible to craft a solution, it would be
easier if the language offered a standard Boolean type. This also
applies to Jython: some Java classes have separately overloaded
methods or constructors for int and boolean arguments. The bool
type can be used to select the boolean variant. (The same is
apparently the case for some COM interfaces.)
The standard bool type can also serve as a way to force a value to
be interpreted as a Boolean, which can be used to normalize
Boolean values. When a Boolean value needs to be normalized to
one of two values, bool(x) is much clearer than "not not x" and
much more concise than
Here are some arguments derived from teaching Python. When
showing people comparison operators etc. in the interactive shell,
I think this is a bit ugly:
>>> a = 13
>>> b = 12
>>> a > b
If this was:
>>> a > b
it would require a millisecond less thinking each time a 0 or 1
There's also the issue (which I've seen baffling even experienced
Pythonistas who had been away from the language for a while) that
if you see:
>>> cmp(a, b)
>>> cmp(a, a)
you might be tempted to believe that cmp() also returned a truth
value, whereas in reality it can return three different values
(-1, 0, 1). If ints were not (normally) used to represent
Booleans results, this would stand out much more clearly as
something completely different.
The following Python code specifies most of the properties of the
def __new__(cls, val=0):
# This constructor always returns an existing instance
__str__ = __repr__
def __and__(self, other):
if isinstance(other, bool):
return bool(int(self) & int(other))
return int.__and__(self, other)
__rand__ = __and__
def __or__(self, other):
if isinstance(other, bool):
return bool(int(self) | int(other))
return int.__or__(self, other)
__ror__ = __or__
def __xor__(self, other):
if isinstance(other, bool):
return bool(int(self) ^ int(other))
return int.__xor__(self, other)
__rxor__ = __xor__
# Bootstrap truth values through sheer willpower
False = int.__new__(bool, 0)
True = int.__new__(bool, 1)
The values False and True will be singletons, like None. Because
the type has two values, perhaps these should be called
"doubletons"? The real implementation will not allow other
instances of bool to be created.
True and False will properly round-trip through pickling and
marshalling; for example pickle.loads(pickle.dumps(True)) will
return True, and so will marshal.loads(marshal.dumps(True)).
All built-in operations that are defined to return a Boolean
result will be changed to return False or True instead of 0 or 1.
In particular, this affects comparisons (<, <=, ==, !=, >, >=, is,
is not, in, not in), the unary operator 'not', the built-in
functions callable(), hasattr(), isinstance() and issubclass(),
the dict method has_key(), the string and unicode methods
endswith(), isalnum(), isalpha(), isdigit(), islower(), isspace(),
istitle(), isupper(), and startswith(), the unicode methods
isdecimal() and isnumeric(), and the 'closed' attribute of file
objects. The predicates in the operator module are also changed
to return a bool, including operator.truth().
Because bool inherits from int, True+1 is valid and equals 2, and
so on. This is important for backwards compatibility: because
comparisons and so on currently return integer values, there's no
way of telling what uses existing applications make of these
It is expected that over time, the standard library will be
updated to use False and True when appropriate (but not to require
a bool argument type where previous an int was allowed). This
change should not pose additional problems and is not specified in
detail by this PEP.
The header file "boolobject.h" defines the C API for the bool
type. It is included by "Python.h" so there is no need to include
The existing names Py_False and Py_True reference the unique bool
objects False and True (previously these referenced static int
objects with values 0 and 1, which were not unique amongst int
A new API, PyObject *PyBool_FromLong(long), takes a C long int
argument and returns a new reference to either Py_False (when the
argument is zero) or Py_True (when it is nonzero).
To check whether an object is a bool, the macro PyBool_Check() can
The type of bool instances is PyBoolObject *.
The bool type object is available as PyBool_Type.
This PEP does *not* change the fact that almost all object types
can be used as truth values. For example, when used in an if
statement, an empty list is false and a non-empty one is true;
this does not change and there is no plan to ever change this.
The only thing that changes is the preferred values to represent
truth values when returned or assigned explicitly. Previously,
these preferred truth values were 0 and 1; the PEP changes the
preferred values to False and True, and changes built-in
operations to return these preferred values.
Because of backwards compatibility, the bool type lacks many
properties that some would like to see. For example, arithmetic
operations with one or two bool arguments is allowed, treating
False as 0 and True as 1. Also, a bool may be used as a sequence
I don't see this as a problem, and I don't want evolve the
language in this direction either. I don't believe that a
stricter interpretation of "Booleanness" makes the language any
Another consequence of the compatibility requirement is that the
expression "True and 6" has the value 6, and similarly the
expression "False or None" has the value None. The "and" and "or"
operators are usefully defined to return the first argument that
determines the outcome, and this won't change; in particular, they
don't force the outcome to be a bool. Of course, if both
arguments are bools, the outcome is always a bool. It can also
easily be coerced into being a bool by writing for example "bool(x
(See also the Review section above.)
- Because the repr() or str() of a bool value is different from an
int value, some code (for example doctest-based unit tests, and
possibly database code that relies on things like "%s" % truth)
may fail. It is easy to work around this (without explicitly
referencing the bool type), and it is expected that this only
affects a very small amount of code that can easily be fixed.
- Other languages (C99, C++, Java) name the constants "false" and
"true", in all lowercase. For Python, I prefer to stick with
the example set by the existing built-in constants, which all
use CapitalizedWords: None, Ellipsis, NotImplemented (as well as
all built-in exceptions). Python's built-in namespace uses all
lowercase for functions and types only.
- It has been suggested that, in order to satisfy user
expectations, for every x that is considered true in a Boolean
context, the expression x == True should be true, and likewise
if x is considered false, x == False should be true. In
particular newbies who have only just learned about Boolean
variables are likely to write
if x == True: ...
instead of the correct form,
if x: ...
There seem to be strong psychological and linguistic reasons why
many people are at first uncomfortable with the latter form, but
I believe that the solution should be in education rather than
in crippling the language. After all, == is general seen as a
transitive operator, meaning that from a==b and b==c we can
deduce a==c. But if any comparison to True were to report
equality when the other operand was a true value of any type,
atrocities like 6==True==7 would hold true, from which one could
infer the falsehood 6==7. That's unacceptable. (In addition,
it would break backwards compatibility. But even if it didn't,
I'd still be against this, for the stated reasons.)
Newbies should also be reminded that there's never a reason to
if bool(x): ...
since the bool is implicit in the "if". Explicit is *not*
better than implicit here, since the added verbiage impairs
redability and there's no other interpretation possible. There
is, however, sometimes a reason to write
b = bool(x)
This is useful when it is unattractive to keep a reference to an
arbitrary object x, or when normalization is required for some
other reason. It is also sometimes appropriate to write
i = int(bool(x))
which converts the bool to an int with the value 0 or 1. This
conveys the intention to henceforth use the value as an int.
A complete implementation in C has been uploaded to the
SourceForge patch manager:
This will soon be checked into CVS for python 2.3a0.
This document has been placed in the public domain.
ActiveState is excited to offer you the chance to share your opinion, and win a
$1000 O'Reilly Bookshelf!
As open source programmers and users ourselves, we really believe in the power
of collaboration. Your feedback is invaluable in helping us to better serve the
Python community through our open source projects and product development.
Please share your thoughts by completing our online Programming Survey.
All respondents have the option of entering a draw to win a $1000 O'Reilly
Bookshelf. If you win, you'll be able to customize your prize from all available
titles in the O'Reilly catalog, to a total value of $1000!
Survey must be completed by April 8, 2002. Draw to be held April 10, 2002.
To take the survey, please click here:
The python and zope Banner exchange has been in operation now for a while at:
Thanks to user feedback, I have now expanded the scope to include open
source. So it is now called the "Open Source Banner Exchange."
You are invited to submit your banners. I believe that by bringing
together disparate open source web sites, this service will provide a much
needed marketing boost to the python and zope community.
I invite you to join, just email me your banner.
510 795 6086
Hi everyone !
I want to introduce Romance.
Romance is an heterogeneous vision of programming / hacking. It relies on
a light dynamic object sharing protocol for sharing between different
programmic languages and programs (such as desktop applications).
In the future Romance will be more than that. It may provide a full
library, including even a graphic toolkit !
Romance is a free (GPL'ed) alternative to .NET, CORBA / Bonobo or
XML-RPC. It allows to share objects between languages, but keeps the
each language's interpreter (contrary to .NET) and look-and-feel (you
code Python, not C#).
Romance currently support Python, Guile (Scheme) and C. Future versions
will support other scripts languages (Perl, Ruby, ...), Lisp / Scheme
(ELisp, ...) and other dynamic languages (Smalltalk, OCaml)...
Romance is available at :
The use of Romance in Python is totally transparent. Here is an example
of a Romance server :
# Step 1: import and init Romance !
# Step 2: create our stuff : the Person factory
def __init__(self, name, proof):
self.name = name
self.proof = proof
return "%s is a %s." % (self.name, self.proof)
# Step 3: make it available to any Romance app as "romance.Person"
romance.Person = Person
# Step 4: wait for client !
And the corresponding client :
# Step 1: import and init Romance !
# Step 2: access to Romance lib and data (and modify them if you want !!!)
# Here, create me as a person !
jiba = romance.Person("Jiba", "hacker")
print "My name is :", jiba.name
print "More precision :", jiba.get_description()
print "Server is in %s" % jiba.__lang__()
=> My name is : Jiba
=> More precision : Jiba is a hacker.
=> Server is in python
The client is in Python too (because comp.lang.python !), but it can be Guile, or whatever "romantic"
Python is an excellent language for most purposes. However, it is
not the language of choice for complex, inhomogeneous computation
intensive tasks. Computer chess programming is probably one of the
best examples of such tasks. However, I have, together with my
friend and colleague Hannu Helminen, coded a GPLed computer
chess program in Python/Tkinter.
Well, I'd like to finally officially announce that my book, _GUI Programming
with Python using the Qt Toolkit_ is now officially available on paper. Whew!
You buy it directly from the publisher's website: http://www.opendocs.org,
or, preferably, at your favourite local or on-line bookshop. For instance,
Amazon lists it as:
(And I wonder how that's going to come across.) The ISBN is 0-97003300-4-4.
Anyway, I've written about 160.000 words of English prose and code, all about
Qt, PyQt, sip, Qt Designer and BlackAdder. I cover both Qt 2 and Qt 3 in a
lot of detail.
All source code to the examples is included on a cd-rom, and Opendocs will
shortly open a webforum where I'll post updated code and where people can
You can read the book online at: http://www.opendocspublishing.com/pyqt.
Boudewijn Rempt | http://www.valdyas.org
I am pleased to announce PMS, Python Mail System, is released
in version 0.2.18
PMS is an MUA library written in Python, supporting multiple
backends and front ends. It is availbale from
* Bug fixes, imported from the Debian fixes
* Accessing MH folders over ssh supported now.
This release is completely serious. There is nothing funny about it.
Twisted is an event-based framework for internet applications. For more
or join the list at:
Twisted joins the fight against Software Piracy
The main focus of this release is our new licensing scheme. The Business
Software Alliance may have put it best, in their page on anti-piracy
"Software pirates not only steal from the companies that make the software,
but with less money for research and development of new software, all users
are hurt. That's why all software piracy - even one copy you make for a
friend, is illegal."
Software piracy is a serious crime, and one that the Open Source community
has been remarkably lax in pursuing and protecting against. This is why
Twisted Matrix Laboratories is taking the forefront in Open Source software
In order to do your part to prevent the tragedy of unregistered, unlicensed
software, all you need to do is go to http://www.twistedmatrix.com/license
and enter your user information to obtain a license key. You can provide us
with as much or as little information as you like!
For more information on how Twisted helps you run licensed, unpirated
Open-Source software, visit:
What's New in 0.16.0
- Added Qt event loop support
- FTP client protocol support
- Reworked coil - a web-based configuration system for Twisted servers
- Win32 event loop can now run subprocesses
- Automatic log rotation for servers (and USR1 signal for manual rotation)
- Improved support for registering shutdown methods
- Better XML-RPC integration
- Bug fixes, small feature improvements, and more.
What is Twisted?
Twisted is an event-based framework for internet applications. It includes
a web server, a telnet server, a multiplayer RPG engine, a generic client
and server for remote object access, and APIs for creating new protocols and
services. Twisted supports integration of the Tk, GTK+, Qt or wxPython event
loop with its main event loop. The Win32 event loop is also supported, as is
basic support for running servers on top of Jython.
Twisted currently supports the following protocols, all implemented in pure
python, most of them as both servers and clients:
- AOL's instant messaging TOC
- OSCAR, used by AOL-IM as well as ICQ (client only)
- LDAP (client only)
- Echo, discard, chargen and friends
- Twisted Perspective Broker
For more information, visit http://www.twistedmatrix.com, or join the list
ReportLab (www.reportlab.com) are proud to announce the release of pyRXP,
the fastest XML parsing toolkit for python, and possibly for any other
pyRXP is a wrapper around the excellent RXP parser developed by Richard
Tobin at the University of Edinburgh. Our goal is very simple: get an
XML document into memory, and validated, as quickly and efficiently
as possible. You can parse and validate Hamlet in a tenth of a second on a
pyRXP constructs a tree of tuples in memory with a single API call; the tree
is easy to navigate in standard Python code and can be wrapped up with
DOM-like 'lazy accessor' nodules. It is standards-compliant
and validating, and is at least 30x faster and 6x more memory efficient than
(non-validating) minidom parser in the standard Python distribution. It
comfortably beats the Microsoft and Java (Xerces) parsers in our tests.
CEO/Chief Architect, ReportLab Inc.
April 1st 2001
Webware for Python 0.7 is now available!
Webware for Python is a suite of software components for developing
object-oriented, web-based applications. The suite uses well known design
patterns and includes popular features such as:
* A fast, easy-to-use application server
* Python Server Pages (PSP)
* Object-relational mapper
* Task scheduler
* User manager with authentication
* CGI wrapper
Key goals of the project include:
* An expansive suite of components and features to cover common needs of web
* Modular architecture where components can be used together or independently.
* Excellent documentation and numerous examples.
* Open source development and community (Python-style license).
For more information or to download Webware 0.7 see
Changes since version 0.6.1:
Python 2.0 or higher is now required.
Components of Webware no longer have independent version
numbers. There is just an overall Webware version number.
Each component still has an independent status of
alpha, beta, etc.
New option "gobblewhitespace" in Python Server Pages lets
you write if/else and try/except statements in a more
New option "formatter" in Python Server Pages lets you
specify an alternate formatter function to use instead of
New feature in MiddleKit: model inheritance. See the
user's guide for details.
Improvements to the CSV functionality in MiscUtils.
- PickleRPC as a more Pythonic alternative to XML-RPC
- SessionPrefix setting that can be used with mod_rewrite
for easy load balancing with session affinity
- improved exception reporting hooks
- EmailErrorReportAsAttachment setting can be used to
send HTML error pages as attachments
- minor bug fixes
Major speed improvements in MiddleKit.
- Geoff Talvola