peps/pep-0285/index.html

510 lines
38 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 285 Adding a bool type | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0285/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 285 Adding a bool type | peps.python.org'>
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0285/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="Python Enhancement Proposals (PEPs)">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 285</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 285 Adding a bool type</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Guido van Rossum &lt;guido&#32;&#97;t&#32;python.org&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">08-Mar-2002</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.3</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even">08-Mar-2002, 30-Mar-2002, 03-Apr-2002</dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#review">Review</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#specification">Specification</a></li>
<li><a class="reference internal" href="#c-api">C API</a></li>
<li><a class="reference internal" href="#clarification">Clarification</a></li>
<li><a class="reference internal" href="#compatibility">Compatibility</a></li>
<li><a class="reference internal" href="#resolved-issues">Resolved Issues</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes the introduction of a new built-in type, bool,
with two constants, <code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">True</span></code>. The bool type would be a
straightforward subtype (in C) of the int type, and the values
<code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">True</span></code> would behave like 0 and 1 in most respects (for
example, <code class="docutils literal notranslate"><span class="pre">False==0</span></code> and <code class="docutils literal notranslate"><span class="pre">True==1</span></code> would be true) except <code class="docutils literal notranslate"><span class="pre">repr()</span></code> and
<code class="docutils literal notranslate"><span class="pre">str()</span></code>. All built-in operations that conceptually return a Boolean
result will be changed to return <code class="docutils literal notranslate"><span class="pre">False</span></code> or <code class="docutils literal notranslate"><span class="pre">True</span></code> instead of 0 or 1;
for example, comparisons, the “not” operator, and predicates like
<code class="docutils literal notranslate"><span class="pre">isinstance()</span></code>.</p>
</section>
<section id="review">
<h2><a class="toc-backref" href="#review" role="doc-backlink">Review</a></h2>
<p>Ive 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… :-)</p>
<p>Anyway, here are my BDFL pronouncements. (Executive summary: Im
not changing a thing; all variants are rejected.)</p>
<ol class="arabic">
<li>Should this PEP be accepted?<p>=&gt; Yes.</p>
<p>There have been many arguments against the PEP. Many of them
were based on misunderstandings. Ive 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.</p>
</li>
<li>Should <code class="docutils literal notranslate"><span class="pre">str(True)</span></code> return “True” or “1”? “1” might reduce
backwards compatibility problems, but looks strange.
(<code class="docutils literal notranslate"><span class="pre">repr(True)</span></code> would always return “True”.)<p>=&gt; “True”.</p>
<p>Almost all reviewers agree with this.</p>
</li>
<li>Should the constants be called True and False (similar to
None) or true and false (as in C++, Java and C99)?<p>=&gt; True and False.</p>
<p>Most reviewers agree that consistency within Python is more
important than consistency with other languages.</p>
</li>
<li>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?<p>=&gt; No.</p>
<p>Theres a small but vocal minority that would prefer to see
“textbook” bools that dont support arithmetic operations at
all, but most reviewers agree with me that bools should always
allow arithmetic operations.</p>
</li>
<li>Should <code class="docutils literal notranslate"><span class="pre">operator.truth(x)</span></code> return an int or a bool?<p>=&gt; bool.</p>
<p>Tim Peters believes it should return an int, but almost all
other reviewers agree that it should return a bool. My
rationale: <code class="docutils literal notranslate"><span class="pre">operator.truth()</span></code> exists to force a Boolean context
on its argument (it calls the C API <code class="docutils literal notranslate"><span class="pre">PyObject_IsTrue())</span></code>.
Whether the outcome is reported as int or bool is secondary; if
bool exists theres no reason not to use it. (Under the PEP,
<code class="docutils literal notranslate"><span class="pre">operator.truth()</span></code> now becomes an alias for <code class="docutils literal notranslate"><span class="pre">bool()</span></code>; thats fine.)</p>
</li>
<li>Should bool inherit from int?<p>=&gt; Yes.</p>
<p>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
<code class="docutils literal notranslate"><span class="pre">PyInt_Check()</span></code> 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 &amp; 4
is 0, but both 3 and 4 are true when considered as truth
values.</p>
</li>
<li>Should the name bool be changed?<p>=&gt; No.</p>
<p>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
dont think these are a burden to understanding. To a newbie,
it doesnt matter whether its called a waffle or a bool; its
a new word, and they learn quickly what it means.</p>
<p>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.”</p>
</li>
<li>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
written as “if bool([]):” ???<p>=&gt; No!!!</p>
<p>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
PEPs motivation and I dont intend to make this change. (See
also the section “Clarification” below.)</p>
</li>
</ol>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Most languages eventually grow a Boolean type; even C99 (the new
and improved C standard, not yet widely adopted) has one.</p>
<p>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. Ive 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.</p>
<p>Some external libraries (like databases and RPC packages) need to
be able to distinguish between Boolean and integral values, and
while its 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.)</p>
<p>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, <code class="docutils literal notranslate"><span class="pre">bool(x)</span></code> is much clearer than “not not x” and
much more concise than</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">x</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
</pre></div>
</div>
<p>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:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">=</span> <span class="mi">13</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">b</span> <span class="o">=</span> <span class="mi">12</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span>
<span class="go">1</span>
<span class="gp">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p>If this was:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p>it would require a millisecond less thinking each time a 0 or 1
was printed.</p>
<p>Theres also the issue (which Ive seen baffling even experienced
Pythonistas who had been away from the language for a while) that
if you see:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">cmp</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
<span class="go">1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cmp</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">a</span><span class="p">)</span>
<span class="go">0</span>
<span class="gp">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p>you might be tempted to believe that <code class="docutils literal notranslate"><span class="pre">cmp()</span></code> also returned a truth
value, whereas in reality it can return three different values
<code class="docutils literal notranslate"><span class="pre">(-1,</span> <span class="pre">0,</span> <span class="pre">1)</span></code>. If ints were not (normally) used to represent
Booleans results, this would stand out much more clearly as
something completely different.</p>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<p>The following Python code specifies most of the properties of the
new type:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">bool</span><span class="p">(</span><span class="nb">int</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">val</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="c1"># This constructor always returns an existing instance</span>
<span class="k">if</span> <span class="n">val</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;True&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;False&quot;</span>
<span class="fm">__str__</span> <span class="o">=</span> <span class="fm">__repr__</span>
<span class="k">def</span> <span class="fm">__and__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">bool</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">&amp;</span> <span class="nb">int</span><span class="p">(</span><span class="n">other</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">int</span><span class="o">.</span><span class="fm">__and__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
<span class="fm">__rand__</span> <span class="o">=</span> <span class="fm">__and__</span>
<span class="k">def</span> <span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">bool</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">|</span> <span class="nb">int</span><span class="p">(</span><span class="n">other</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">int</span><span class="o">.</span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
<span class="fm">__ror__</span> <span class="o">=</span> <span class="fm">__or__</span>
<span class="k">def</span> <span class="fm">__xor__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">bool</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">^</span> <span class="nb">int</span><span class="p">(</span><span class="n">other</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">int</span><span class="o">.</span><span class="fm">__xor__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
<span class="fm">__rxor__</span> <span class="o">=</span> <span class="fm">__xor__</span>
<span class="c1"># Bootstrap truth values through sheer willpower</span>
<span class="kc">False</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="nb">bool</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="kc">True</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="nb">bool</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>The values <code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">True</span></code> 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.</p>
<p><code class="docutils literal notranslate"><span class="pre">True</span></code> and <code class="docutils literal notranslate"><span class="pre">False</span></code> will properly round-trip through pickling and
marshalling; for example <code class="docutils literal notranslate"><span class="pre">pickle.loads(pickle.dumps(True))</span></code> will
return <code class="docutils literal notranslate"><span class="pre">True</span></code>, and so will <code class="docutils literal notranslate"><span class="pre">marshal.loads(marshal.dumps(True))</span></code>.</p>
<p>All built-in operations that are defined to return a Boolean
result will be changed to return <code class="docutils literal notranslate"><span class="pre">False</span></code> or <code class="docutils literal notranslate"><span class="pre">True</span></code> instead of 0 or 1.
In particular, this affects comparisons (<code class="docutils literal notranslate"><span class="pre">&lt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&lt;=</span></code>, <code class="docutils literal notranslate"><span class="pre">==</span></code>, <code class="docutils literal notranslate"><span class="pre">!=</span></code>,
<code class="docutils literal notranslate"><span class="pre">&gt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;=</span></code>, is, is not, in, not in), the unary operator not, the built-in
functions <code class="docutils literal notranslate"><span class="pre">callable()</span></code>, <code class="docutils literal notranslate"><span class="pre">hasattr()</span></code>, <code class="docutils literal notranslate"><span class="pre">isinstance()</span></code> and <code class="docutils literal notranslate"><span class="pre">issubclass()</span></code>,
the dict method <code class="docutils literal notranslate"><span class="pre">has_key()</span></code>, the string and unicode methods
<code class="docutils literal notranslate"><span class="pre">endswith()</span></code>, <code class="docutils literal notranslate"><span class="pre">isalnum()</span></code>, <code class="docutils literal notranslate"><span class="pre">isalpha()</span></code>, <code class="docutils literal notranslate"><span class="pre">isdigit()</span></code>, <code class="docutils literal notranslate"><span class="pre">islower()</span></code>, <code class="docutils literal notranslate"><span class="pre">isspace()</span></code>,
<code class="docutils literal notranslate"><span class="pre">istitle()</span></code>, <code class="docutils literal notranslate"><span class="pre">isupper()</span></code>, and <code class="docutils literal notranslate"><span class="pre">startswith()</span></code>, the unicode methods
<code class="docutils literal notranslate"><span class="pre">isdecimal()</span></code> and <code class="docutils literal notranslate"><span class="pre">isnumeric()</span></code>, and the closed attribute of file
objects. The predicates in the operator module are also changed
to return a bool, including <code class="docutils literal notranslate"><span class="pre">operator.truth()</span></code>.</p>
<p>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, theres no
way of telling what uses existing applications make of these
values.</p>
<p>It is expected that over time, the standard library will be
updated to use <code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">True</span></code> 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.</p>
</section>
<section id="c-api">
<h2><a class="toc-backref" href="#c-api" role="doc-backlink">C API</a></h2>
<p>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.</p>
<p>The existing names <code class="docutils literal notranslate"><span class="pre">Py_False</span></code> and <code class="docutils literal notranslate"><span class="pre">Py_True</span></code> reference the unique bool
objects <code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">True</span></code> (previously these referenced static int
objects with values 0 and 1, which were not unique amongst int
values).</p>
<p>A new API, <code class="docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*PyBool_FromLong(long)</span></code>, takes a C long int
argument and returns a new reference to either <code class="docutils literal notranslate"><span class="pre">Py_False</span></code> (when the
argument is zero) or <code class="docutils literal notranslate"><span class="pre">Py_True</span></code> (when it is nonzero).</p>
<p>To check whether an object is a bool, the macro <code class="docutils literal notranslate"><span class="pre">PyBool_Check()</span></code> can
be used.</p>
<p>The type of bool instances is <code class="docutils literal notranslate"><span class="pre">PyBoolObject</span> <span class="pre">*</span></code>.</p>
<p>The bool type object is available as PyBool_Type.</p>
</section>
<section id="clarification">
<h2><a class="toc-backref" href="#clarification" role="doc-backlink">Clarification</a></h2>
<p>This PEP does <strong>not</strong> 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.</p>
<p>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 <code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">True</span></code>, and changes built-in
operations to return these preferred values.</p>
</section>
<section id="compatibility">
<h2><a class="toc-backref" href="#compatibility" role="doc-backlink">Compatibility</a></h2>
<p>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
<code class="docutils literal notranslate"><span class="pre">False</span></code> as 0 and <code class="docutils literal notranslate"><span class="pre">True</span></code> as 1. Also, a bool may be used as a sequence
index.</p>
<p>I dont see this as a problem, and I dont want evolve the
language in this direction either. I dont believe that a
stricter interpretation of “Booleanness” makes the language any
clearer.</p>
<p>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 wont change; in particular, they
dont 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)”.</p>
</section>
<section id="resolved-issues">
<h2><a class="toc-backref" href="#resolved-issues" role="doc-backlink">Resolved Issues</a></h2>
<p>(See also the Review section above.)</p>
<ul>
<li>Because the <code class="docutils literal notranslate"><span class="pre">repr()</span></code> or <code class="docutils literal notranslate"><span class="pre">str()</span></code> 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.</li>
<li>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: <code class="docutils literal notranslate"><span class="pre">None</span></code>, <code class="docutils literal notranslate"><span class="pre">Ellipsis</span></code>, <code class="docutils literal notranslate"><span class="pre">NotImplemented</span></code> (as well as
all built-in exceptions). Pythons built-in namespace uses all
lowercase for functions and types only.</li>
<li>It has been suggested that, in order to satisfy user
expectations, for every x that is considered true in a Boolean
context, the expression <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">True</span></code> should be true, and likewise
if x is considered false, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">False</span></code> should be true. In
particular newbies who have only just learned about Boolean
variables are likely to write<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="o">...</span>
</pre></div>
</div>
<p>instead of the correct form,</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">x</span><span class="p">:</span> <span class="o">...</span>
</pre></div>
</div>
<p>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 <code class="docutils literal notranslate"><span class="pre">a==b</span></code> and <code class="docutils literal notranslate"><span class="pre">b==c</span></code> we can
deduce <code class="docutils literal notranslate"><span class="pre">a==c</span></code>. But if any comparison to <code class="docutils literal notranslate"><span class="pre">True</span></code> were to report
equality when the other operand was a true value of any type,
atrocities like <code class="docutils literal notranslate"><span class="pre">6==True==7</span></code> would hold true, from which one could
infer the falsehood <code class="docutils literal notranslate"><span class="pre">6==7</span></code>. Thats unacceptable. (In addition,
it would break backwards compatibility. But even if it didnt,
Id still be against this, for the stated reasons.)</p>
<p>Newbies should also be reminded that theres never a reason to
write</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="nb">bool</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="o">...</span>
</pre></div>
</div>
<p>since the bool is implicit in the “if”. Explicit is <strong>not</strong>
better than implicit here, since the added verbiage impairs
readability and theres no other interpretation possible. There
is, however, sometimes a reason to write</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</pre></div>
</div>
<p>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</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">i</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">bool</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</pre></div>
</div>
<p>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.</p>
</li>
</ul>
</section>
<section id="implementation">
<h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2>
<p>A complete implementation in C has been uploaded to the
SourceForge patch manager: <a class="reference external" href="https://bugs.python.org/issue528022">https://bugs.python.org/issue528022</a></p>
<p>This will soon be checked into CVS for python 2.3a0.</p>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0285.rst">https://github.com/python/peps/blob/main/peps/pep-0285.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0285.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#review">Review</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#specification">Specification</a></li>
<li><a class="reference internal" href="#c-api">C API</a></li>
<li><a class="reference internal" href="#clarification">Clarification</a></li>
<li><a class="reference internal" href="#compatibility">Compatibility</a></li>
<li><a class="reference internal" href="#resolved-issues">Resolved Issues</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0285.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>