
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/) PEP: 285 Title: Adding a bool type Version: $Revision: 1.20 $ Last-Modified: $Date: 2002/04/03 22:11:05 $ Author: guido@python.org (Guido van Rossum) Status: Accepted Type: Standards Track Created: 8-Mar-2002 Python-Version: 2.3 Post-History: 8-Mar-2002, 30-Mar-2002, 3-Apr-2002 Abstract 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 isinstance(). Review 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 PEP... :-) Anyway, here are my BDFL pronouncements. (Executive summary: I'm not changing a thing; all variants are rejected.) 1) Should this PEP be accepted? => Yes. 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".) => "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? => No. 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? => 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? => Yes. 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 values. 7) Should the name 'bool' be changed? => No. 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([]):" ??? => No!!! 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.) Rationale 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 if x: return 1 else: return 0 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 1 >>> If this was: >>> a > b True >>> it would require a millisecond less thinking each time a 0 or 1 was printed. 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) 1 >>> cmp(a, a) 0 >>> 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. Specification The following Python code specifies most of the properties of the new type: class bool(int): def __new__(cls, val=0): # This constructor always returns an existing instance if val: return True else: return False def __repr__(self): if self: return "True" else: return "False" __str__ = __repr__ def __and__(self, other): if isinstance(other, bool): return bool(int(self) & int(other)) else: return int.__and__(self, other) __rand__ = __and__ def __or__(self, other): if isinstance(other, bool): return bool(int(self) | int(other)) else: return int.__or__(self, other) __ror__ = __or__ def __xor__(self, other): if isinstance(other, bool): return bool(int(self) ^ int(other)) else: 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 values. 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. C API 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 it directly. 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 values). 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 be used. The type of bool instances is PyBoolObject *. The bool type object is available as PyBool_Type. Clarification 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. Compatibility 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 index. 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 clearer. 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 and y)". Resolved Issues (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 write 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. Implementation A complete implementation in C has been uploaded to the SourceForge patch manager: http://python.org/sf/528022 This will soon be checked into CVS for python 2.3a0. Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil fill-column: 70 End:

Guido van Rossum wrote:
Would it not be "relatively" easy to add a compiler-time warning for most uses of this dangerous idiom? At the very least, the boolean type could do the equivalent of: def __eq__(self, other): if __debug__ and other not in (0,1,True,False): warnings.warn("Testing of equality is best done by asking objects whether they're true, not comparing with a boolean", RunTimeWarning) return int.__eq__(self, other) or something similar? --david

I think this would be a job for PyChecker. Neal? --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Neal just posted that PyChecker deals with it, which is great, but I don't think that PyChecker is enough - until PyChecker is part of the standard distribution and integrated with e.g. the interactive shell, I think that PyChecker is not likely to be used by novices. And we're talking about novices here, right? Come to think of it, getting PyChecker integrated w/ the interactive shell would be great! Hard, I suspect, but great! --david

David Ascher wrote:
Not too hard: >>> from pychecker import checker >>> import test_bool test_bool.py:6: Comparisions with True are not necessary test_bool.py:7: Comparisions with False are not necessary If you always wanted this, you could add a PYTHONSTARTUP script to do the import or you could add/modify sitecustomize.py. It probably isn't perfect since I don't use this, but it could work. Neal

Neal Norwitz wrote:
David Ascher wrote:
That's nice, but it doesn't deal with the real novice's usage, which is to learn at the >>> prompt, not in modules. E:\tmp>cat > foo.py cat: Reading input from keyboard: def foo(): a = 3 return 3 ^Z E:\tmp>python ActivePython 2.2.0 Build 221 (ActiveState Corp.) based on Python 2.2 (#28, Mar 28 2002, 12:10:20) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
that's nice, but:
The fact that it doesn't pick up on the unused variable is too bad. The integration I'm thinking of would be deeper. --da

Yeah, but I think we should only complain about comparisons to bool that use the literals (as opposed to "if x == y" where either x or y happens to be a bool). A run-time warning can't really do that.
Come to think of it, getting PyChecker integrated w/ the interactive shell would be great! Hard, I suspect, but great!
Certainly better than running tabnanny. :-) I'm not even sure how hard it would be to add this to IDLE -- pychecker is already a module. Maybe Neal will enjoy this challenge? --Guido van Rossum (home page: http://www.python.org/~guido/)

Hey! Who told you you could have the keys to the time machine! --Guido van Rossum (home page: http://www.python.org/~guido/)

David Ascher <DavidA@ActiveState.com> wrote:
I warning about `x == True` wouldn't hurt. But your proposed `__eq__` certainly would -- don't do that please. Equality testing is useful if one wants to check whether two predicates have the same boolean value. -- Christian Tanzer tanzer@swing.co.at Glasauergasse 32 Tel: +43 1 876 62 36 A-1130 Vienna, Austria Fax: +43 1 877 66 92

Guido van Rossum wrote:
And the warnings have already been added to pychecker. I know I'm going to wish I never said this, but ... If you find REAL problems with code that breaks, let me know. I will try to address problems that may arise. This code: True = 1 False = 0 def test(a): if a is True: print 'True' if a == False: print 'False' generates these warnings: test.py:2: Should not assign to True, it is (or will be) a builtin test.py:3: Should not assign to False, it is (or will be) a builtin test.py:6: Comparisions with True are not necessary test.py:7: Comparisions with False are not necessary Neal

And the warnings have already been added to pychecker.
I knew I could count on you. :-)
I wonder if you should add warnings for *any* spelling, or at least also for true and TRUE, if assigned the constant 1 (and similar for false/FALSE), on the basis that these are probably other ways to spell the same thing. E.g. I've seen FALSE, TRUE = range(2)
def test(a): if a is True: print 'True'
But 'is True' can be a useful test. The newbies we're trying to catch in verboten activities are using ==.
Cool. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
I wonder if you should add warnings for *any* spelling, or at least
Done.
But 'is True' can be a useful test. The newbies we're trying to catch in verboten activities are using ==.
Done, 'is' and 'is not' do not generate a warning. Also fixed the spelling mistake and made the warning harsher: Comparisons with True are not necessary and may not work as expected Neal

"Neal" == Neal Norwitz <neal@metaslash.com> writes:
Neal> This code [...] generates these warnings: Neal> test.py:6: Comparisions with True are not necessary That doesn't look like "shinai"[1] to me. Is it strong enough? Footnotes: [1] The split-bamboo sword preferred by Zen masters because it hurts more, with less permanent damage---to the bamboo, anyway. -- Institute of Policy and Planning Sciences http://turnbull.sk.tsukuba.ac.jp University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN Don't ask how you can "do" free software business; ask what your business can "do for" free software.

Hi Neal!
if a is True: print 'True'
[...]
test.py:6: Comparisions with True are not necessary
Testing if "a is True" is ok. True and False are singletons this is the best way to know if 'a' is really 'True' (and not 1, [0], "foo", etc). This test will be necessary sometimes.
if a == False: print 'False'
[...]
test.py:7: Comparisions with False are not necessary
This should probably say something more agressive, like "Comparisions with boolean values may be dangerous", since this may give undesirable results (if the user was trying to check for False, and not for 0, [], "", etc). -- Gustavo Niemeyer [ 2AAC 7928 0FBF 0299 5EB5 60E2 2253 B29A 6664 3A0C ]

"MvL" == Martin v Loewis <martin@v.loewis.de> writes:
MvL> While Gustavo suggests to let pass 'a is True', I recommend MvL> to give a warning for this - people who want to see whether MvL> something is True should write 'True is a'. "True is a"... what? hippopotamus? <wink>. -Barry

martin@v.loewis.de (Martin v. Loewis)
people who want to see whether something is True should write 'True is a'.
But only if "from __future__ import yoda" is in effect. :-) Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+

I love the idea of a bool type, but please don't inherit bool from int. I didn't want to chime in before because I thought Ka-Ping Yee covered what a "real boolean" is better than I could, but his email didn't elicit much comment. The main disadvantage to a bool inheriting from an int is that there is no way that the Python interpreter can check to make sure that it really gets a bool if it inherits from int. The only way to check if you got a real bool is if the end programmer writes something using isinstance(). For compatibility, having True and False equate to 1 and 0, respectively, is a good idea. But please do it by promotion or conversion or something, not inheritance. Once the assumption of bool-is-an-int gets locked into the language, it will be impossible to switch to bool-only-looks-like-an-int or bool-is-a-real-type later. If bool is a separate type, Python can have a --anal-bool (name specifically chosen to be memorable ;) option which means "By gosh, if it isn't a bool and it should be, throw something." If bool inherits from int, I see no way to ever implement that check in the language. Please correct me if this is an erroneous assumption. As a concrete example, I have a VLSI layout tool written completely in Python. Because I and my colleagues are disciples of the Cult of Paranoid Programming(tm), the codebase of 7674 lines includes 31 lines (counting the else and complaint as one line) with checks of the following form:
That means that about .5-1% (depending on how you really count the checking lines) of the code exists solely to check to make sure that a bool really is a bool. And it's drudgery, boilerplate code that adds no functionality to the program. This practice got adopted because we were running down too many bugs which started from [] or None sliding through as false and then causing subtle problems later in the program when it could have been caught and fixed immediately. However, to catch these bugs requires a programmer to write the extra check. With --anal-bool: the above sequence becomes:
With --anal-bool:
Without --anal-bool:
By leaving the default as loose, the backward compatibility is preserved while still allowing stricter semantics. By having --anal-bool as a flag, I can remove .5-1% of my total codebase. And we all know that the only bug-free code is code that doesn't exist. ;) The --anal-bool flag will also help point out all those places in the Python code itself which will have to be changed to True and False. And do so loudly. ;) -a

Guido van Rossum wrote:
Would it not be "relatively" easy to add a compiler-time warning for most uses of this dangerous idiom? At the very least, the boolean type could do the equivalent of: def __eq__(self, other): if __debug__ and other not in (0,1,True,False): warnings.warn("Testing of equality is best done by asking objects whether they're true, not comparing with a boolean", RunTimeWarning) return int.__eq__(self, other) or something similar? --david

I think this would be a job for PyChecker. Neal? --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Neal just posted that PyChecker deals with it, which is great, but I don't think that PyChecker is enough - until PyChecker is part of the standard distribution and integrated with e.g. the interactive shell, I think that PyChecker is not likely to be used by novices. And we're talking about novices here, right? Come to think of it, getting PyChecker integrated w/ the interactive shell would be great! Hard, I suspect, but great! --david

David Ascher wrote:
Not too hard: >>> from pychecker import checker >>> import test_bool test_bool.py:6: Comparisions with True are not necessary test_bool.py:7: Comparisions with False are not necessary If you always wanted this, you could add a PYTHONSTARTUP script to do the import or you could add/modify sitecustomize.py. It probably isn't perfect since I don't use this, but it could work. Neal

Neal Norwitz wrote:
David Ascher wrote:
That's nice, but it doesn't deal with the real novice's usage, which is to learn at the >>> prompt, not in modules. E:\tmp>cat > foo.py cat: Reading input from keyboard: def foo(): a = 3 return 3 ^Z E:\tmp>python ActivePython 2.2.0 Build 221 (ActiveState Corp.) based on Python 2.2 (#28, Mar 28 2002, 12:10:20) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
that's nice, but:
The fact that it doesn't pick up on the unused variable is too bad. The integration I'm thinking of would be deeper. --da

Yeah, but I think we should only complain about comparisons to bool that use the literals (as opposed to "if x == y" where either x or y happens to be a bool). A run-time warning can't really do that.
Come to think of it, getting PyChecker integrated w/ the interactive shell would be great! Hard, I suspect, but great!
Certainly better than running tabnanny. :-) I'm not even sure how hard it would be to add this to IDLE -- pychecker is already a module. Maybe Neal will enjoy this challenge? --Guido van Rossum (home page: http://www.python.org/~guido/)

Hey! Who told you you could have the keys to the time machine! --Guido van Rossum (home page: http://www.python.org/~guido/)

David Ascher <DavidA@ActiveState.com> wrote:
I warning about `x == True` wouldn't hurt. But your proposed `__eq__` certainly would -- don't do that please. Equality testing is useful if one wants to check whether two predicates have the same boolean value. -- Christian Tanzer tanzer@swing.co.at Glasauergasse 32 Tel: +43 1 876 62 36 A-1130 Vienna, Austria Fax: +43 1 877 66 92

Guido van Rossum wrote:
And the warnings have already been added to pychecker. I know I'm going to wish I never said this, but ... If you find REAL problems with code that breaks, let me know. I will try to address problems that may arise. This code: True = 1 False = 0 def test(a): if a is True: print 'True' if a == False: print 'False' generates these warnings: test.py:2: Should not assign to True, it is (or will be) a builtin test.py:3: Should not assign to False, it is (or will be) a builtin test.py:6: Comparisions with True are not necessary test.py:7: Comparisions with False are not necessary Neal

And the warnings have already been added to pychecker.
I knew I could count on you. :-)
I wonder if you should add warnings for *any* spelling, or at least also for true and TRUE, if assigned the constant 1 (and similar for false/FALSE), on the basis that these are probably other ways to spell the same thing. E.g. I've seen FALSE, TRUE = range(2)
def test(a): if a is True: print 'True'
But 'is True' can be a useful test. The newbies we're trying to catch in verboten activities are using ==.
Cool. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
I wonder if you should add warnings for *any* spelling, or at least
Done.
But 'is True' can be a useful test. The newbies we're trying to catch in verboten activities are using ==.
Done, 'is' and 'is not' do not generate a warning. Also fixed the spelling mistake and made the warning harsher: Comparisons with True are not necessary and may not work as expected Neal

"Neal" == Neal Norwitz <neal@metaslash.com> writes:
Neal> This code [...] generates these warnings: Neal> test.py:6: Comparisions with True are not necessary That doesn't look like "shinai"[1] to me. Is it strong enough? Footnotes: [1] The split-bamboo sword preferred by Zen masters because it hurts more, with less permanent damage---to the bamboo, anyway. -- Institute of Policy and Planning Sciences http://turnbull.sk.tsukuba.ac.jp University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN Don't ask how you can "do" free software business; ask what your business can "do for" free software.

Hi Neal!
if a is True: print 'True'
[...]
test.py:6: Comparisions with True are not necessary
Testing if "a is True" is ok. True and False are singletons this is the best way to know if 'a' is really 'True' (and not 1, [0], "foo", etc). This test will be necessary sometimes.
if a == False: print 'False'
[...]
test.py:7: Comparisions with False are not necessary
This should probably say something more agressive, like "Comparisions with boolean values may be dangerous", since this may give undesirable results (if the user was trying to check for False, and not for 0, [], "", etc). -- Gustavo Niemeyer [ 2AAC 7928 0FBF 0299 5EB5 60E2 2253 B29A 6664 3A0C ]

"MvL" == Martin v Loewis <martin@v.loewis.de> writes:
MvL> While Gustavo suggests to let pass 'a is True', I recommend MvL> to give a warning for this - people who want to see whether MvL> something is True should write 'True is a'. "True is a"... what? hippopotamus? <wink>. -Barry

martin@v.loewis.de (Martin v. Loewis)
people who want to see whether something is True should write 'True is a'.
But only if "from __future__ import yoda" is in effect. :-) Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+

I love the idea of a bool type, but please don't inherit bool from int. I didn't want to chime in before because I thought Ka-Ping Yee covered what a "real boolean" is better than I could, but his email didn't elicit much comment. The main disadvantage to a bool inheriting from an int is that there is no way that the Python interpreter can check to make sure that it really gets a bool if it inherits from int. The only way to check if you got a real bool is if the end programmer writes something using isinstance(). For compatibility, having True and False equate to 1 and 0, respectively, is a good idea. But please do it by promotion or conversion or something, not inheritance. Once the assumption of bool-is-an-int gets locked into the language, it will be impossible to switch to bool-only-looks-like-an-int or bool-is-a-real-type later. If bool is a separate type, Python can have a --anal-bool (name specifically chosen to be memorable ;) option which means "By gosh, if it isn't a bool and it should be, throw something." If bool inherits from int, I see no way to ever implement that check in the language. Please correct me if this is an erroneous assumption. As a concrete example, I have a VLSI layout tool written completely in Python. Because I and my colleagues are disciples of the Cult of Paranoid Programming(tm), the codebase of 7674 lines includes 31 lines (counting the else and complaint as one line) with checks of the following form:
That means that about .5-1% (depending on how you really count the checking lines) of the code exists solely to check to make sure that a bool really is a bool. And it's drudgery, boilerplate code that adds no functionality to the program. This practice got adopted because we were running down too many bugs which started from [] or None sliding through as false and then causing subtle problems later in the program when it could have been caught and fixed immediately. However, to catch these bugs requires a programmer to write the extra check. With --anal-bool: the above sequence becomes:
With --anal-bool:
Without --anal-bool:
By leaving the default as loose, the backward compatibility is preserved while still allowing stricter semantics. By having --anal-bool as a flag, I can remove .5-1% of my total codebase. And we all know that the only bug-free code is code that doesn't exist. ;) The --anal-bool flag will also help point out all those places in the Python code itself which will have to be changed to True and False. And do so loudly. ;) -a
participants (10)
-
Andrew P. Lentvorski
-
barry@zope.com
-
David Ascher
-
Greg Ewing
-
Guido van Rossum
-
Gustavo Niemeyer
-
martin@v.loewis.de
-
Neal Norwitz
-
Stephen J. Turnbull
-
tanzer@swing.co.at