reSTify PEP 285 (#366)
This commit is contained in:
parent
27d218f1bb
commit
b596c6abe3
130
pep-0285.txt
130
pep-0285.txt
|
@ -5,25 +5,28 @@ Last-Modified: $Date$
|
||||||
Author: guido@python.org (Guido van Rossum)
|
Author: guido@python.org (Guido van Rossum)
|
||||||
Status: Final
|
Status: Final
|
||||||
Type: Standards Track
|
Type: Standards Track
|
||||||
|
Content-Type: text/x-rst
|
||||||
Created: 8-Mar-2002
|
Created: 8-Mar-2002
|
||||||
Python-Version: 2.3
|
Python-Version: 2.3
|
||||||
Post-History: 8-Mar-2002, 30-Mar-2002, 3-Apr-2002
|
Post-History: 8-Mar-2002, 30-Mar-2002, 3-Apr-2002
|
||||||
|
|
||||||
|
|
||||||
Abstract
|
Abstract
|
||||||
|
========
|
||||||
|
|
||||||
This PEP proposes the introduction of a new built-in type, bool,
|
This PEP proposes the introduction of a new built-in type, bool,
|
||||||
with two constants, False and True. The bool type would be a
|
with two constants, ``False`` and ``True``. The bool type would be a
|
||||||
straightforward subtype (in C) of the int type, and the values
|
straightforward subtype (in C) of the int type, and the values
|
||||||
False and True would behave like 0 and 1 in most respects (for
|
``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
|
example, ``False==0`` and ``True==1`` would be true) except ``repr()`` and
|
||||||
str(). All built-in operations that conceptually return a Boolean
|
``str()``. All built-in operations that conceptually return a Boolean
|
||||||
result will be changed to return False or True instead of 0 or 1;
|
result will be changed to return ``False`` or ``True`` instead of 0 or 1;
|
||||||
for example, comparisons, the "not" operator, and predicates like
|
for example, comparisons, the "not" operator, and predicates like
|
||||||
isinstance().
|
``isinstance()``.
|
||||||
|
|
||||||
|
|
||||||
Review
|
Review
|
||||||
|
======
|
||||||
|
|
||||||
I've collected enough feedback to last me a lifetime, so I declare
|
I've collected enough feedback to last me a lifetime, so I declare
|
||||||
the review period officially OVER. I had Chinese food today; my
|
the review period officially OVER. I had Chinese food today; my
|
||||||
|
@ -46,9 +49,9 @@ Review
|
||||||
More about that below too. I think this is not a sufficient
|
More about that below too. I think this is not a sufficient
|
||||||
reason to reject the PEP.
|
reason to reject the PEP.
|
||||||
|
|
||||||
2) Should str(True) return "True" or "1"? "1" might reduce
|
2) Should ``str(True)`` return "True" or "1"? "1" might reduce
|
||||||
backwards compatibility problems, but looks strange.
|
backwards compatibility problems, but looks strange.
|
||||||
(repr(True) would always return "True".)
|
(``repr(True)`` would always return "True".)
|
||||||
|
|
||||||
=> "True".
|
=> "True".
|
||||||
|
|
||||||
|
@ -73,17 +76,17 @@ Review
|
||||||
all, but most reviewers agree with me that bools should always
|
all, but most reviewers agree with me that bools should always
|
||||||
allow arithmetic operations.
|
allow arithmetic operations.
|
||||||
|
|
||||||
5) Should operator.truth(x) return an int or a bool?
|
5) Should ``operator.truth(x)`` return an int or a bool?
|
||||||
|
|
||||||
=> bool.
|
=> bool.
|
||||||
|
|
||||||
Tim Peters believes it should return an int, but almost all
|
Tim Peters believes it should return an int, but almost all
|
||||||
other reviewers agree that it should return a bool. My
|
other reviewers agree that it should return a bool. My
|
||||||
rationale: operator.truth() exists to force a Boolean context
|
rationale: ``operator.truth()`` exists to force a Boolean context
|
||||||
on its argument (it calls the C API PyObject_IsTrue()).
|
on its argument (it calls the C API ``PyObject_IsTrue())``.
|
||||||
Whether the outcome is reported as int or bool is secondary; if
|
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,
|
bool exists there's no reason not to use it. (Under the PEP,
|
||||||
operator.truth() now becomes an alias for bool(); that's fine.)
|
``operator.truth()`` now becomes an alias for ``bool()``; that's fine.)
|
||||||
|
|
||||||
6) Should bool inherit from int?
|
6) Should bool inherit from int?
|
||||||
|
|
||||||
|
@ -93,7 +96,7 @@ Review
|
||||||
separate integer type that knows how to perform mixed-mode
|
separate integer type that knows how to perform mixed-mode
|
||||||
arithmetic. However, inheriting bool from int eases the
|
arithmetic. However, inheriting bool from int eases the
|
||||||
implementation enormously (in part since all C code that calls
|
implementation enormously (in part since all C code that calls
|
||||||
PyInt_Check() will continue to work -- this returns true for
|
``PyInt_Check()`` will continue to work -- this returns true for
|
||||||
subclasses of int). Also, I believe this is right in terms of
|
subclasses of int). Also, I believe this is right in terms of
|
||||||
substitutability: code that requires an int can be fed a bool
|
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
|
and it will behave the same as 0 or 1. Code that requires a
|
||||||
|
@ -137,6 +140,7 @@ Review
|
||||||
|
|
||||||
|
|
||||||
Rationale
|
Rationale
|
||||||
|
=========
|
||||||
|
|
||||||
Most languages eventually grow a Boolean type; even C99 (the new
|
Most languages eventually grow a Boolean type; even C99 (the new
|
||||||
and improved C standard, not yet widely adopted) has one.
|
and improved C standard, not yet widely adopted) has one.
|
||||||
|
@ -164,9 +168,11 @@ Rationale
|
||||||
The standard bool type can also serve as a way to force a value to
|
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
|
be interpreted as a Boolean, which can be used to normalize
|
||||||
Boolean values. When a Boolean value needs to be normalized to
|
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
|
one of two values, ``bool(x)`` is much clearer than "not not x" and
|
||||||
much more concise than
|
much more concise than
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
if x:
|
if x:
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
|
@ -174,7 +180,7 @@ Rationale
|
||||||
|
|
||||||
Here are some arguments derived from teaching Python. When
|
Here are some arguments derived from teaching Python. When
|
||||||
showing people comparison operators etc. in the interactive shell,
|
showing people comparison operators etc. in the interactive shell,
|
||||||
I think this is a bit ugly:
|
I think this is a bit ugly::
|
||||||
|
|
||||||
>>> a = 13
|
>>> a = 13
|
||||||
>>> b = 12
|
>>> b = 12
|
||||||
|
@ -182,7 +188,7 @@ Rationale
|
||||||
1
|
1
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
If this was:
|
If this was::
|
||||||
|
|
||||||
>>> a > b
|
>>> a > b
|
||||||
True
|
True
|
||||||
|
@ -193,7 +199,7 @@ Rationale
|
||||||
|
|
||||||
There's also the issue (which I've seen baffling even experienced
|
There's also the issue (which I've seen baffling even experienced
|
||||||
Pythonistas who had been away from the language for a while) that
|
Pythonistas who had been away from the language for a while) that
|
||||||
if you see:
|
if you see::
|
||||||
|
|
||||||
>>> cmp(a, b)
|
>>> cmp(a, b)
|
||||||
1
|
1
|
||||||
|
@ -201,17 +207,18 @@ Rationale
|
||||||
0
|
0
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
you might be tempted to believe that cmp() also returned a truth
|
you might be tempted to believe that ``cmp()`` also returned a truth
|
||||||
value, whereas in reality it can return three different values
|
value, whereas in reality it can return three different values
|
||||||
(-1, 0, 1). If ints were not (normally) used to represent
|
``(-1, 0, 1)``. If ints were not (normally) used to represent
|
||||||
Booleans results, this would stand out much more clearly as
|
Booleans results, this would stand out much more clearly as
|
||||||
something completely different.
|
something completely different.
|
||||||
|
|
||||||
|
|
||||||
Specification
|
Specification
|
||||||
|
=============
|
||||||
|
|
||||||
The following Python code specifies most of the properties of the
|
The following Python code specifies most of the properties of the
|
||||||
new type:
|
new type::
|
||||||
|
|
||||||
class bool(int):
|
class bool(int):
|
||||||
|
|
||||||
|
@ -258,26 +265,26 @@ Specification
|
||||||
False = int.__new__(bool, 0)
|
False = int.__new__(bool, 0)
|
||||||
True = int.__new__(bool, 1)
|
True = int.__new__(bool, 1)
|
||||||
|
|
||||||
The values False and True will be singletons, like None. Because
|
The values ``False`` and ``True`` will be singletons, like None. Because
|
||||||
the type has two values, perhaps these should be called
|
the type has two values, perhaps these should be called
|
||||||
"doubletons"? The real implementation will not allow other
|
"doubletons"? The real implementation will not allow other
|
||||||
instances of bool to be created.
|
instances of bool to be created.
|
||||||
|
|
||||||
True and False will properly round-trip through pickling and
|
``True`` and ``False`` will properly round-trip through pickling and
|
||||||
marshalling; for example pickle.loads(pickle.dumps(True)) will
|
marshalling; for example ``pickle.loads(pickle.dumps(True))`` will
|
||||||
return True, and so will marshal.loads(marshal.dumps(True)).
|
return ``True``, and so will ``marshal.loads(marshal.dumps(True))``.
|
||||||
|
|
||||||
All built-in operations that are defined to return a Boolean
|
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.
|
result will be changed to return ``False`` or ``True`` instead of 0 or 1.
|
||||||
In particular, this affects comparisons (<, <=, ==, !=, >, >=, is,
|
In particular, this affects comparisons (``<``, ``<=``, ``==``, ``!=``,
|
||||||
is not, in, not in), the unary operator 'not', the built-in
|
``>``, ``>=``, is, is not, in, not in), the unary operator 'not', the built-in
|
||||||
functions callable(), hasattr(), isinstance() and issubclass(),
|
functions ``callable()``, ``hasattr()``, ``isinstance()`` and ``issubclass()``,
|
||||||
the dict method has_key(), the string and unicode methods
|
the dict method ``has_key()``, the string and unicode methods
|
||||||
endswith(), isalnum(), isalpha(), isdigit(), islower(), isspace(),
|
``endswith()``, ``isalnum()``, ``isalpha()``, ``isdigit()``, ``islower()``, ``isspace()``,
|
||||||
istitle(), isupper(), and startswith(), the unicode methods
|
``istitle()``, ``isupper()``, and ``startswith()``, the unicode methods
|
||||||
isdecimal() and isnumeric(), and the 'closed' attribute of file
|
``isdecimal()`` and ``isnumeric()``, and the 'closed' attribute of file
|
||||||
objects. The predicates in the operator module are also changed
|
objects. The predicates in the operator module are also changed
|
||||||
to return a bool, including operator.truth().
|
to return a bool, including ``operator.truth()``.
|
||||||
|
|
||||||
Because bool inherits from int, True+1 is valid and equals 2, and
|
Because bool inherits from int, True+1 is valid and equals 2, and
|
||||||
so on. This is important for backwards compatibility: because
|
so on. This is important for backwards compatibility: because
|
||||||
|
@ -286,38 +293,40 @@ Specification
|
||||||
values.
|
values.
|
||||||
|
|
||||||
It is expected that over time, the standard library will be
|
It is expected that over time, the standard library will be
|
||||||
updated to use False and True when appropriate (but not to require
|
updated to use ``False`` and ``True`` when appropriate (but not to require
|
||||||
a bool argument type where previous an int was allowed). This
|
a bool argument type where previous an int was allowed). This
|
||||||
change should not pose additional problems and is not specified in
|
change should not pose additional problems and is not specified in
|
||||||
detail by this PEP.
|
detail by this PEP.
|
||||||
|
|
||||||
|
|
||||||
C API
|
C API
|
||||||
|
=====
|
||||||
|
|
||||||
The header file "boolobject.h" defines the C API for the bool
|
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
|
type. It is included by "Python.h" so there is no need to include
|
||||||
it directly.
|
it directly.
|
||||||
|
|
||||||
The existing names Py_False and Py_True reference the unique bool
|
The existing names ``Py_False`` and ``Py_True`` reference the unique bool
|
||||||
objects False and True (previously these referenced static int
|
objects ``False`` and ``True`` (previously these referenced static int
|
||||||
objects with values 0 and 1, which were not unique amongst int
|
objects with values 0 and 1, which were not unique amongst int
|
||||||
values).
|
values).
|
||||||
|
|
||||||
A new API, PyObject *PyBool_FromLong(long), takes a C long 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 and returns a new reference to either ``Py_False`` (when the
|
||||||
argument is zero) or Py_True (when it is nonzero).
|
argument is zero) or ``Py_True`` (when it is nonzero).
|
||||||
|
|
||||||
To check whether an object is a bool, the macro PyBool_Check() can
|
To check whether an object is a bool, the macro ``PyBool_Check()`` can
|
||||||
be used.
|
be used.
|
||||||
|
|
||||||
The type of bool instances is PyBoolObject *.
|
The type of bool instances is ``PyBoolObject *``.
|
||||||
|
|
||||||
The bool type object is available as PyBool_Type.
|
The bool type object is available as PyBool_Type.
|
||||||
|
|
||||||
|
|
||||||
Clarification
|
Clarification
|
||||||
|
=============
|
||||||
|
|
||||||
This PEP does *not* change the fact that almost all object types
|
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
|
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;
|
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.
|
this does not change and there is no plan to ever change this.
|
||||||
|
@ -325,16 +334,17 @@ Clarification
|
||||||
The only thing that changes is the preferred values to represent
|
The only thing that changes is the preferred values to represent
|
||||||
truth values when returned or assigned explicitly. Previously,
|
truth values when returned or assigned explicitly. Previously,
|
||||||
these preferred truth values were 0 and 1; the PEP changes the
|
these preferred truth values were 0 and 1; the PEP changes the
|
||||||
preferred values to False and True, and changes built-in
|
preferred values to ``False`` and ``True``, and changes built-in
|
||||||
operations to return these preferred values.
|
operations to return these preferred values.
|
||||||
|
|
||||||
|
|
||||||
Compatibility
|
Compatibility
|
||||||
|
=============
|
||||||
|
|
||||||
Because of backwards compatibility, the bool type lacks many
|
Because of backwards compatibility, the bool type lacks many
|
||||||
properties that some would like to see. For example, arithmetic
|
properties that some would like to see. For example, arithmetic
|
||||||
operations with one or two bool arguments is allowed, treating
|
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
|
``False`` as 0 and ``True`` as 1. Also, a bool may be used as a sequence
|
||||||
index.
|
index.
|
||||||
|
|
||||||
I don't see this as a problem, and I don't want evolve the
|
I don't see this as a problem, and I don't want evolve the
|
||||||
|
@ -354,10 +364,11 @@ Compatibility
|
||||||
|
|
||||||
|
|
||||||
Resolved Issues
|
Resolved Issues
|
||||||
|
===============
|
||||||
|
|
||||||
(See also the Review section above.)
|
(See also the Review section above.)
|
||||||
|
|
||||||
- Because the repr() or str() of a bool value is different from an
|
- Because the ``repr()`` or ``str()`` of a bool value is different from an
|
||||||
int value, some code (for example doctest-based unit tests, and
|
int value, some code (for example doctest-based unit tests, and
|
||||||
possibly database code that relies on things like "%s" % truth)
|
possibly database code that relies on things like "%s" % truth)
|
||||||
may fail. It is easy to work around this (without explicitly
|
may fail. It is easy to work around this (without explicitly
|
||||||
|
@ -367,20 +378,22 @@ Resolved Issues
|
||||||
- Other languages (C99, C++, Java) name the constants "false" and
|
- Other languages (C99, C++, Java) name the constants "false" and
|
||||||
"true", in all lowercase. For Python, I prefer to stick with
|
"true", in all lowercase. For Python, I prefer to stick with
|
||||||
the example set by the existing built-in constants, which all
|
the example set by the existing built-in constants, which all
|
||||||
use CapitalizedWords: None, Ellipsis, NotImplemented (as well as
|
use CapitalizedWords: ``None``, ``Ellipsis``, ``NotImplemented`` (as well as
|
||||||
all built-in exceptions). Python's built-in namespace uses all
|
all built-in exceptions). Python's built-in namespace uses all
|
||||||
lowercase for functions and types only.
|
lowercase for functions and types only.
|
||||||
|
|
||||||
- It has been suggested that, in order to satisfy user
|
- It has been suggested that, in order to satisfy user
|
||||||
expectations, for every x that is considered true in a Boolean
|
expectations, for every x that is considered true in a Boolean
|
||||||
context, the expression x == True should be true, and likewise
|
context, the expression ``x == True`` should be true, and likewise
|
||||||
if x is considered false, x == False should be true. In
|
if x is considered false, ``x == False`` should be true. In
|
||||||
particular newbies who have only just learned about Boolean
|
particular newbies who have only just learned about Boolean
|
||||||
variables are likely to write
|
variables are likely to write
|
||||||
|
::
|
||||||
|
|
||||||
if x == True: ...
|
if x == True: ...
|
||||||
|
|
||||||
instead of the correct form,
|
instead of the correct form,
|
||||||
|
::
|
||||||
|
|
||||||
if x: ...
|
if x: ...
|
||||||
|
|
||||||
|
@ -388,29 +401,32 @@ Resolved Issues
|
||||||
many people are at first uncomfortable with the latter form, but
|
many people are at first uncomfortable with the latter form, but
|
||||||
I believe that the solution should be in education rather than
|
I believe that the solution should be in education rather than
|
||||||
in crippling the language. After all, == is general seen as a
|
in crippling the language. After all, == is general seen as a
|
||||||
transitive operator, meaning that from a==b and b==c we can
|
transitive operator, meaning that from ``a==b`` and ``b==c`` we can
|
||||||
deduce a==c. But if any comparison to True were to report
|
deduce ``a==c``. But if any comparison to ``True`` were to report
|
||||||
equality when the other operand was a true value of any type,
|
equality when the other operand was a true value of any type,
|
||||||
atrocities like 6==True==7 would hold true, from which one could
|
atrocities like ``6==True==7`` would hold true, from which one could
|
||||||
infer the falsehood 6==7. That's unacceptable. (In addition,
|
infer the falsehood ``6==7``. That's unacceptable. (In addition,
|
||||||
it would break backwards compatibility. But even if it didn't,
|
it would break backwards compatibility. But even if it didn't,
|
||||||
I'd still be against this, for the stated reasons.)
|
I'd still be against this, for the stated reasons.)
|
||||||
|
|
||||||
Newbies should also be reminded that there's never a reason to
|
Newbies should also be reminded that there's never a reason to
|
||||||
write
|
write
|
||||||
|
::
|
||||||
|
|
||||||
if bool(x): ...
|
if bool(x): ...
|
||||||
|
|
||||||
since the bool is implicit in the "if". Explicit is *not*
|
since the bool is implicit in the "if". Explicit is **not**
|
||||||
better than implicit here, since the added verbiage impairs
|
better than implicit here, since the added verbiage impairs
|
||||||
redability and there's no other interpretation possible. There
|
redability and there's no other interpretation possible. There
|
||||||
is, however, sometimes a reason to write
|
is, however, sometimes a reason to write
|
||||||
|
::
|
||||||
|
|
||||||
b = bool(x)
|
b = bool(x)
|
||||||
|
|
||||||
This is useful when it is unattractive to keep a reference to an
|
This is useful when it is unattractive to keep a reference to an
|
||||||
arbitrary object x, or when normalization is required for some
|
arbitrary object x, or when normalization is required for some
|
||||||
other reason. It is also sometimes appropriate to write
|
other reason. It is also sometimes appropriate to write
|
||||||
|
::
|
||||||
|
|
||||||
i = int(bool(x))
|
i = int(bool(x))
|
||||||
|
|
||||||
|
@ -419,21 +435,21 @@ Resolved Issues
|
||||||
|
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
==============
|
||||||
|
|
||||||
A complete implementation in C has been uploaded to the
|
A complete implementation in C has been uploaded to the
|
||||||
SourceForge patch manager:
|
SourceForge patch manager: http://python.org/sf/528022
|
||||||
|
|
||||||
http://python.org/sf/528022
|
|
||||||
|
|
||||||
This will soon be checked into CVS for python 2.3a0.
|
This will soon be checked into CVS for python 2.3a0.
|
||||||
|
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
|
=========
|
||||||
|
|
||||||
This document has been placed in the public domain.
|
This document has been placed in the public domain.
|
||||||
|
|
||||||
|
|
||||||
|
..
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode: indented-text
|
mode: indented-text
|
||||||
indent-tabs-mode: nil
|
indent-tabs-mode: nil
|
||||||
|
|
Loading…
Reference in New Issue