Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 285 – Adding a bool type

Author:
Guido van Rossum <guido at python.org>
Status:
Final
Type:
Standards Track
Created:
08-Mar-2002
Python-Version:
2.3
Post-History:
08-Mar-2002, 30-Mar-2002, 03-Apr-2002

Table of Contents

Abstract

This PEP proposes the introduction of a new built-in type, bool,with two constants,False andTrue. The bool type would be astraightforward subtype (in C) of the int type, and the valuesFalse andTrue would behave like 0 and 1 in most respects (forexample,False==0 andTrue==1 would be true) exceptrepr() andstr(). All built-in operations that conceptually return a Booleanresult will be changed to returnFalse orTrue instead of 0 or 1;for example, comparisons, the “not” operator, and predicates likeisinstance().

Review

I’ve collected enough feedback to last me a lifetime, so I declarethe review period officially OVER. I had Chinese food today; myfortune cookie said “Strong and bitter words indicate a weakcause.” It reminded me of some of the posts against thisPEP… :-)

Anyway, here are my BDFL pronouncements. (Executive summary: I’mnot changing a thing; all variants are rejected.)

  1. Should this PEP be accepted?

    => Yes.

    There have been many arguments against the PEP. Many of themwere based on misunderstandings. I’ve tried to clarify some ofthe most common misunderstandings below in the main text of thePEP. The only issue that weighs at all for me is the tendencyof newbies to write “if x == True” where “if x” would suffice.More about that below too. I think this is not a sufficientreason to reject the PEP.

  2. Shouldstr(True) return “True” or “1”? “1” might reducebackwards 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 toNone) or ‘true’ and ‘false’ (as in C++, Java and C99)?

    => True and False.

    Most reviewers agree that consistency within Python is moreimportant than consistency with other languages.

  4. Should we strive to eliminate non-Boolean operations on boolsin the future, through suitable warnings, so that for exampleTrue+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 atall, but most reviewers agree with me that bools should alwaysallow arithmetic operations.

  5. Shouldoperator.truth(x) return an int or a bool?

    => bool.

    Tim Peters believes it should return an int, but almost allother reviewers agree that it should return a bool. Myrationale:operator.truth() exists to force a Boolean contexton its argument (it calls the C APIPyObject_IsTrue()).Whether the outcome is reported as int or bool is secondary; ifbool exists there’s no reason not to use it. (Under the PEP,operator.truth() now becomes an alias forbool(); that’s fine.)

  6. Should bool inherit from int?

    => Yes.

    In an ideal world, bool might be better implemented as aseparate integer type that knows how to perform mixed-modearithmetic. However, inheriting bool from int eases theimplementation enormously (in part since all C code that callsPyInt_Check() will continue to work – this returns true forsubclasses of int). Also, I believe this is right in terms ofsubstitutability: code that requires an int can be fed a booland it will behave the same as 0 or 1. Code that requires abool may not work when it is given an int; for example, 3 & 4is 0, but both 3 and 4 are true when considered as truthvalues.

  7. Should the name ‘bool’ be changed?

    => No.

    Some reviewers have argued for boolean instead of bool, becausethis would be easier to understand (novices may have heard ofBoolean algebra but may not make the connection with bool) orbecause they hate abbreviations. My take: Python usesabbreviations judiciously (like ‘def’, ‘int’, ‘dict’) and Idon’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’sa new word, and they learn quickly what it means.

    One reviewer has argued to make the name ‘truth’. I find thisan unattractive name, and would actually prefer to reserve thisterm (in documentation) for the more abstract concept of truthvalues that already exists in Python. For example: “when acontainer is interpreted as a truth value, an empty containeris 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 thatfor example “if []:” would become illegal and would have to bewritten as “if bool([]):” ???

    => No!!!

    Some people believe that this is how a language with a textbookBoolean type should behave. Because it was brought up, othershave worried that I might agree with this position. Let memake my position on this quite clear. This is not part of thePEP’s motivation and I don’t intend to make this change. (Seealso the section “Clarification” below.)

Rationale

Most languages eventually grow a Boolean type; even C99 (the newand improved C standard, not yet widely adopted) has one.

Many programmers apparently feel the need for a Boolean type; mostPython documentation contains a bit of an apology for the absenceof a Boolean type. I’ve seen lots of modules that definedconstants “False=0” and “True=1” (or similar) at the top and usedthose. The problem with this is that everybody does itdifferently. For example, should you use “FALSE”, “false”,“False”, “F” or even “f”? And should false be the value zero orNone, or perhaps a truth value of a different type that will printas “true” or “false”? Adding a standard bool type to the languageresolves those issues.

Some external libraries (like databases and RPC packages) need tobe able to distinguish between Boolean and integral values, andwhile it’s usually possible to craft a solution, it would beeasier if the language offered a standard Boolean type. This alsoapplies to Jython: some Java classes have separately overloadedmethods or constructors for int and boolean arguments. The booltype can be used to select the boolean variant. (The same isapparently the case for some COM interfaces.)

The standard bool type can also serve as a way to force a value tobe interpreted as a Boolean, which can be used to normalizeBoolean values. When a Boolean value needs to be normalized toone of two values,bool(x) is much clearer than “not not x” andmuch more concise than

ifx:return1else:return0

Here are some arguments derived from teaching Python. Whenshowing people comparison operators etc. in the interactive shell,I think this is a bit ugly:

>>>a=13>>>b=12>>>a>b1>>>

If this was:

>>>a>bTrue>>>

it would require a millisecond less thinking each time a 0 or 1was printed.

There’s also the issue (which I’ve seen baffling even experiencedPythonistas who had been away from the language for a while) thatif you see:

>>>cmp(a,b)1>>>cmp(a,a)0>>>

you might be tempted to believe thatcmp() also returned a truthvalue, whereas in reality it can return three different values(-1,0,1). If ints were not (normally) used to representBooleans results, this would stand out much more clearly assomething completely different.

Specification

The following Python code specifies most of the properties of thenew type:

classbool(int):def__new__(cls,val=0):# This constructor always returns an existing instanceifval:returnTrueelse:returnFalsedef__repr__(self):ifself:return"True"else:return"False"__str__=__repr__def__and__(self,other):ifisinstance(other,bool):returnbool(int(self)&int(other))else:returnint.__and__(self,other)__rand__=__and__def__or__(self,other):ifisinstance(other,bool):returnbool(int(self)|int(other))else:returnint.__or__(self,other)__ror__=__or__def__xor__(self,other):ifisinstance(other,bool):returnbool(int(self)^int(other))else:returnint.__xor__(self,other)__rxor__=__xor__# Bootstrap truth values through sheer willpowerFalse=int.__new__(bool,0)True=int.__new__(bool,1)

The valuesFalse andTrue will be singletons, like None. Becausethe type has two values, perhaps these should be called“doubletons”? The real implementation will not allow otherinstances of bool to be created.

True andFalse will properly round-trip through pickling andmarshalling; for examplepickle.loads(pickle.dumps(True)) willreturnTrue, and so willmarshal.loads(marshal.dumps(True)).

All built-in operations that are defined to return a Booleanresult will be changed to returnFalse orTrue instead of 0 or 1.In particular, this affects comparisons (<,<=,==,!=,>,>=, is, is not, in, not in), the unary operator ‘not’, the built-infunctionscallable(),hasattr(),isinstance() andissubclass(),the dict methodhas_key(), the string and unicode methodsendswith(),isalnum(),isalpha(),isdigit(),islower(),isspace(),istitle(),isupper(), andstartswith(), the unicode methodsisdecimal() andisnumeric(), and the ‘closed’ attribute of fileobjects. The predicates in the operator module are also changedto return a bool, includingoperator.truth().

Because bool inherits from int, True+1 is valid and equals 2, andso on. This is important for backwards compatibility: becausecomparisons and so on currently return integer values, there’s noway of telling what uses existing applications make of thesevalues.

It is expected that over time, the standard library will beupdated to useFalse andTrue when appropriate (but not to requirea bool argument type where previous an int was allowed). Thischange should not pose additional problems and is not specified indetail by this PEP.

C API

The header file “boolobject.h” defines the C API for the booltype. It is included by “Python.h” so there is no need to includeit directly.

The existing namesPy_False andPy_True reference the unique boolobjectsFalse andTrue (previously these referenced static intobjects with values 0 and 1, which were not unique amongst intvalues).

A new API,PyObject*PyBool_FromLong(long), takes a C long intargument and returns a new reference to eitherPy_False (when theargument is zero) orPy_True (when it is nonzero).

To check whether an object is a bool, the macroPyBool_Check() canbe used.

The type of bool instances isPyBoolObject*.

The bool type object is available as PyBool_Type.

Clarification

This PEP doesnot change the fact that almost all object typescan be used as truth values. For example, when used in an ifstatement, 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 representtruth values when returned or assigned explicitly. Previously,these preferred truth values were 0 and 1; the PEP changes thepreferred values toFalse andTrue, and changes built-inoperations to return these preferred values.

Compatibility

Because of backwards compatibility, the bool type lacks manyproperties that some would like to see. For example, arithmeticoperations with one or two bool arguments is allowed, treatingFalse as 0 andTrue as 1. Also, a bool may be used as a sequenceindex.

I don’t see this as a problem, and I don’t want evolve thelanguage in this direction either. I don’t believe that astricter interpretation of “Booleanness” makes the language anyclearer.

Another consequence of the compatibility requirement is that theexpression “True and 6” has the value 6, and similarly theexpression “False or None” has the value None. The “and” and “or”operators are usefully defined to return the first argument thatdetermines the outcome, and this won’t change; in particular, theydon’t force the outcome to be a bool. Of course, if botharguments are bools, the outcome is always a bool. It can alsoeasily be coerced into being a bool by writing for example “bool(xand y)”.

Resolved Issues

(See also the Review section above.)

  • Because therepr() orstr() of a bool value is different from anint value, some code (for example doctest-based unit tests, andpossibly database code that relies on things like “%s” % truth)may fail. It is easy to work around this (without explicitlyreferencing the bool type), and it is expected that this onlyaffects 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 withthe example set by the existing built-in constants, which alluse CapitalizedWords:None,Ellipsis,NotImplemented (as well asall built-in exceptions). Python’s built-in namespace uses alllowercase for functions and types only.
  • It has been suggested that, in order to satisfy userexpectations, for every x that is considered true in a Booleancontext, the expressionx==True should be true, and likewiseif x is considered false,x==False should be true. Inparticular newbies who have only just learned about Booleanvariables are likely to write
    ifx==True:...

    instead of the correct form,

    ifx:...

    There seem to be strong psychological and linguistic reasons whymany people are at first uncomfortable with the latter form, butI believe that the solution should be in education rather thanin crippling the language. After all, == is general seen as atransitive operator, meaning that froma==b andb==c we candeducea==c. But if any comparison toTrue were to reportequality when the other operand was a true value of any type,atrocities like6==True==7 would hold true, from which one couldinfer the falsehood6==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 towrite

    ifbool(x):...

    since the bool is implicit in the “if”. Explicit isnotbetter than implicit here, since the added verbiage impairsreadability and there’s no other interpretation possible. Thereis, however, sometimes a reason to write

    b=bool(x)

    This is useful when it is unattractive to keep a reference to anarbitrary object x, or when normalization is required for someother 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. Thisconveys the intention to henceforth use the value as an int.

Implementation

A complete implementation in C has been uploaded to theSourceForge patch manager:https://bugs.python.org/issue528022

This will soon be checked into CVS for python 2.3a0.

Copyright

This document has been placed in the public domain.


Source:https://github.com/python/peps/blob/main/peps/pep-0285.rst

Last modified:2025-02-01 08:55:40 GMT


[8]ページ先頭

©2009-2025 Movatter.jp