Commit 959473a1 authored by Guido van Rossum's avatar Guido van Rossum

Add the 'bool' type and its values 'False' and 'True', as described in

PEP 285.  Everything described in the PEP is here, and there is even
some documentation.  I had to fix 12 unit tests; all but one of these
were printing Boolean outcomes that changed from 0/1 to False/True.
(The exception is test_unicode.py, which did a type(x) == type(y)
style comparison.  I could've fixed that with a single line using
issubtype(x, type(y)), but instead chose to be explicit about those
places where a bool is expected.

Still to do: perhaps more documentation; change standard library
modules to return False/True from predicates.
parent 0cda5f59
...@@ -77,6 +77,16 @@ def my_import(name): ...@@ -77,6 +77,16 @@ def my_import(name):
to \code{\var{function}(*\var{args}, **\var{keywords})}. to \code{\var{function}(*\var{args}, **\var{keywords})}.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{bool}{x}
Convert a value to a Boolean, using the standard truth testing
procedure. If \code{x} is false, this returns \code{False};
otherwise it returns \code{True}. \code{bool} is also a class,
which is a subclass of \code{int}. Class \code{bool} cannot be
subclassed further. Its only instances are \code{False} and
\code{True}.
\indexii{Boolean}{type}
\end{funcdesc}
\begin{funcdesc}{buffer}{object\optional{, offset\optional{, size}}} \begin{funcdesc}{buffer}{object\optional{, offset\optional{, size}}}
The \var{object} argument must be an object that supports the buffer The \var{object} argument must be an object that supports the buffer
call interface (such as strings, arrays, and buffers). A new buffer call interface (such as strings, arrays, and buffers). A new buffer
......
...@@ -2,10 +2,8 @@ ...@@ -2,10 +2,8 @@
The following sections describe the standard types that are built into The following sections describe the standard types that are built into
the interpreter. These are the numeric types, sequence types, and the interpreter. These are the numeric types, sequence types, and
several others, including types themselves. There is no explicit several others, including types themselves.
Boolean type; use integers instead.
\indexii{built-in}{types} \indexii{built-in}{types}
\indexii{Boolean}{type}
Some operations are supported by several object types; in particular, Some operations are supported by several object types; in particular,
all objects can be compared, tested for truth value, and converted to all objects can be compared, tested for truth value, and converted to
...@@ -30,6 +28,9 @@ The following values are considered false: ...@@ -30,6 +28,9 @@ The following values are considered false:
\item \code{None} \item \code{None}
\withsubitem{(Built-in object)}{\ttindex{None}} \withsubitem{(Built-in object)}{\ttindex{None}}
\item \code{False}
\withsubitem{(Built-in object)}{\ttindex{False}}
\item zero of any numeric type, for example, \code{0}, \code{0L}, \item zero of any numeric type, for example, \code{0}, \code{0L},
\code{0.0}, \code{0j}. \code{0.0}, \code{0j}.
...@@ -50,11 +51,12 @@ always true. ...@@ -50,11 +51,12 @@ always true.
\index{true} \index{true}
Operations and built-in functions that have a Boolean result always Operations and built-in functions that have a Boolean result always
return \code{0} for false and \code{1} for true, unless otherwise return \code{0} or \code{False} for false and \code{1} or \code{True}
stated. (Important exception: the Boolean operations for true, unless otherwise stated. (Important exception: the Boolean
\samp{or}\opindex{or} and \samp{and}\opindex{and} always return one of operations \samp{or}\opindex{or} and \samp{and}\opindex{and} always
their operands.) return one of their operands.)
\index{False}
\index{True}
\subsection{Boolean Operations \label{boolean}} \subsection{Boolean Operations \label{boolean}}
...@@ -68,7 +70,7 @@ These are the Boolean operations, ordered by ascending priority: ...@@ -68,7 +70,7 @@ These are the Boolean operations, ordered by ascending priority:
{if \var{x} is false, then \var{x}, else \var{y}}{(1)} {if \var{x} is false, then \var{x}, else \var{y}}{(1)}
\hline \hline
\lineiii{not \var{x}} \lineiii{not \var{x}}
{if \var{x} is false, then \code{1}, else \code{0}}{(2)} {if \var{x} is false, then \code{True}, else \code{False}}{(2)}
\end{tableiii} \end{tableiii}
\opindex{and} \opindex{and}
\opindex{or} \opindex{or}
...@@ -161,8 +163,10 @@ only by sequence types (below). ...@@ -161,8 +163,10 @@ only by sequence types (below).
\subsection{Numeric Types \label{typesnumeric}} \subsection{Numeric Types \label{typesnumeric}}
There are four numeric types: \dfn{plain integers}, \dfn{long integers}, There are four distinct numeric types: \dfn{plain integers},
\dfn{long integers},
\dfn{floating point numbers}, and \dfn{complex numbers}. \dfn{floating point numbers}, and \dfn{complex numbers}.
In addition, Booleans are a subtype of plain integers.
Plain integers (also just called \dfn{integers}) Plain integers (also just called \dfn{integers})
are implemented using \ctype{long} in C, which gives them at least 32 are implemented using \ctype{long} in C, which gives them at least 32
bits of precision. Long integers have unlimited precision. Floating bits of precision. Long integers have unlimited precision. Floating
...@@ -170,6 +174,7 @@ point numbers are implemented using \ctype{double} in C. All bets on ...@@ -170,6 +174,7 @@ point numbers are implemented using \ctype{double} in C. All bets on
their precision are off unless you happen to know the machine you are their precision are off unless you happen to know the machine you are
working with. working with.
\obindex{numeric} \obindex{numeric}
\obindex{Boolean}
\obindex{integer} \obindex{integer}
\obindex{long integer} \obindex{long integer}
\obindex{floating point} \obindex{floating point}
...@@ -1389,6 +1394,22 @@ special operations. There is exactly one ellipsis object, named ...@@ -1389,6 +1394,22 @@ special operations. There is exactly one ellipsis object, named
It is written as \code{Ellipsis}. It is written as \code{Ellipsis}.
\subsubsection{Boolean Values}
Boolean values are the two constant objects \code{False} and
\code{True}. They are used to represent truth values (although other
values can also be considered false or true). In numeric contexts
(for example when used as the argument to an arithmetic operator),
they behave like the integers 0 and 1, respectively. The built-in
function \function{bool()} can be used to cast any value to a Boolean,
if the value can be interpreted as a truth value (see section Truth
Value Testing above).
They are written as \code{False} and \code{True}, respectively.
\index{False}
\index{True}
\indexii{Boolean}{values}
\subsubsection{Internal Objects \label{typesinternal}} \subsubsection{Internal Objects \label{typesinternal}}
......
...@@ -162,7 +162,7 @@ complex numbers: ...@@ -162,7 +162,7 @@ complex numbers:
These represent elements from the mathematical set of whole numbers. These represent elements from the mathematical set of whole numbers.
\obindex{integer} \obindex{integer}
There are two types of integers: There are three types of integers:
\begin{description} \begin{description}
...@@ -187,6 +187,17 @@ represented in a variant of 2's complement which gives the illusion of ...@@ -187,6 +187,17 @@ represented in a variant of 2's complement which gives the illusion of
an infinite string of sign bits extending to the left. an infinite string of sign bits extending to the left.
\obindex{long integer} \obindex{long integer}
\item[Booleans]
These represent the truth values False and True. The two objects
representing the values False and True are the only Boolean objects.
The Boolean type is a subtype of plain integers, and Boolean values
behave like the values 0 and 1, respectively, in almost all contexts,
the exception being that when converted to a string, the strings
\code{"False"} or \code{"True"} are returned, respectively.
\obindex{Boolean}
\ttindex{False}
\ttindex{True}
\end{description} % Integers \end{description} % Integers
The rules for integer representation are intended to give the most The rules for integer representation are intended to give the most
...@@ -222,6 +233,7 @@ and \code{z.imag}. ...@@ -222,6 +233,7 @@ and \code{z.imag}.
\end{description} % Numbers \end{description} % Numbers
\item[Sequences] \item[Sequences]
These represent finite ordered sets indexed by non-negative numbers. These represent finite ordered sets indexed by non-negative numbers.
The built-in function \function{len()}\bifuncindex{len} returns the The built-in function \function{len()}\bifuncindex{len} returns the
...@@ -1074,8 +1086,10 @@ wrong hash bucket). ...@@ -1074,8 +1086,10 @@ wrong hash bucket).
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}[object]{__nonzero__}{self} \begin{methoddesc}[object]{__nonzero__}{self}
Called to implement truth value testing; should return \code{0} or Called to implement truth value testing, and the built-in operation
\code{1}. When this method is not defined, \method{__len__()} is \code{bool()}; should return \code{False} or \code{True}, or their
integer equivalents \code{0} or \code{1}.
When this method is not defined, \method{__len__()} is
called, if it is defined (see below). If a class defines neither called, if it is defined (see below). If a class defines neither
\method{__len__()} nor \method{__nonzero__()}, all its instances are \method{__len__()} nor \method{__nonzero__()}, all its instances are
considered true. considered true.
......
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
#include "unicodeobject.h" #include "unicodeobject.h"
#include "intobject.h" #include "intobject.h"
#include "boolobject.h"
#include "longobject.h" #include "longobject.h"
#include "floatobject.h" #include "floatobject.h"
#ifndef WITHOUT_COMPLEX #ifndef WITHOUT_COMPLEX
......
...@@ -38,21 +38,6 @@ extern DL_IMPORT(PyObject *) PyInt_FromLong(long); ...@@ -38,21 +38,6 @@ extern DL_IMPORT(PyObject *) PyInt_FromLong(long);
extern DL_IMPORT(long) PyInt_AsLong(PyObject *); extern DL_IMPORT(long) PyInt_AsLong(PyObject *);
extern DL_IMPORT(long) PyInt_GetMax(void); extern DL_IMPORT(long) PyInt_GetMax(void);
/*
False and True are special intobjects used by Boolean expressions.
All values of type Boolean must point to either of these; but in
contexts where integers are required they are integers (valued 0 and 1).
Hope these macros don't conflict with other people's.
Don't forget to apply Py_INCREF() when returning True or False!!!
*/
extern DL_IMPORT(PyIntObject) _Py_ZeroStruct, _Py_TrueStruct; /* Don't use these directly */
#define Py_False ((PyObject *) &_Py_ZeroStruct)
#define Py_True ((PyObject *) &_Py_TrueStruct)
/* Macro, trading safety for speed */ /* Macro, trading safety for speed */
#define PyInt_AS_LONG(op) (((PyIntObject *)(op))->ob_ival) #define PyInt_AS_LONG(op) (((PyIntObject *)(op))->ob_ival)
......
...@@ -531,8 +531,8 @@ extern DL_IMPORT(long) _Py_RefTotal; ...@@ -531,8 +531,8 @@ extern DL_IMPORT(long) _Py_RefTotal;
#define Py_DECREF(op) \ #define Py_DECREF(op) \
if (--_Py_RefTotal, 0 < (--((op)->ob_refcnt))) ; \ if (--_Py_RefTotal, 0 < (--((op)->ob_refcnt))) ; \
else if (0 == (op)->ob_refcnt) _Py_Dealloc( (PyObject*)(op)); \ else if (0 == (op)->ob_refcnt) _Py_Dealloc( (PyObject*)(op)); \
else (void)fprintf( stderr, "%s:%i negative ref count %i\n", \ else ((void)fprintf( stderr, "%s:%i negative ref count %i\n", \
__FILE__, __LINE__, (op)->ob_refcnt) __FILE__, __LINE__, (op)->ob_refcnt), abort())
#else /* !Py_REF_DEBUG */ #else /* !Py_REF_DEBUG */
#ifdef COUNT_ALLOCS #ifdef COUNT_ALLOCS
......
...@@ -976,11 +976,11 @@ def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): ...@@ -976,11 +976,11 @@ def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
Examples: Examples:
>>> IS_LINE_JUNK('\n') >>> IS_LINE_JUNK('\n')
1 True
>>> IS_LINE_JUNK(' # \n') >>> IS_LINE_JUNK(' # \n')
1 True
>>> IS_LINE_JUNK('hello\n') >>> IS_LINE_JUNK('hello\n')
0 False
""" """
return pat(line) is not None return pat(line) is not None
...@@ -992,13 +992,13 @@ def IS_CHARACTER_JUNK(ch, ws=" \t"): ...@@ -992,13 +992,13 @@ def IS_CHARACTER_JUNK(ch, ws=" \t"):
Examples: Examples:
>>> IS_CHARACTER_JUNK(' ') >>> IS_CHARACTER_JUNK(' ')
1 True
>>> IS_CHARACTER_JUNK('\t') >>> IS_CHARACTER_JUNK('\t')
1 True
>>> IS_CHARACTER_JUNK('\n') >>> IS_CHARACTER_JUNK('\n')
0 False
>>> IS_CHARACTER_JUNK('x') >>> IS_CHARACTER_JUNK('x')
0 False
""" """
return ch in ws return ch in ws
......
...@@ -545,19 +545,19 @@ def is_private(prefix, base): ...@@ -545,19 +545,19 @@ def is_private(prefix, base):
does not both begin and end with (at least) two underscores. does not both begin and end with (at least) two underscores.
>>> is_private("a.b", "my_func") >>> is_private("a.b", "my_func")
0 False
>>> is_private("____", "_my_func") >>> is_private("____", "_my_func")
1 True
>>> is_private("someclass", "__init__") >>> is_private("someclass", "__init__")
0 False
>>> is_private("sometypo", "__init_") >>> is_private("sometypo", "__init_")
1 True
>>> is_private("x.y.z", "_") >>> is_private("x.y.z", "_")
1 True
>>> is_private("_x.y.z", "__") >>> is_private("_x.y.z", "__")
0 False
>>> is_private("", "") # senseless but consistent >>> is_private("", "") # senseless but consistent
0 False
""" """
return base[:1] == "_" and not base[:2] == "__" == base[-2:] return base[:1] == "_" and not base[:2] == "__" == base[-2:]
......
...@@ -101,6 +101,9 @@ TUPLE = 't' ...@@ -101,6 +101,9 @@ TUPLE = 't'
EMPTY_TUPLE = ')' EMPTY_TUPLE = ')'
SETITEMS = 'u' SETITEMS = 'u'
BINFLOAT = 'G' BINFLOAT = 'G'
TRUE = 'Z'
FALSE = 'z'
__all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)])
del x del x
...@@ -256,6 +259,13 @@ class Pickler: ...@@ -256,6 +259,13 @@ class Pickler:
self.write(NONE) self.write(NONE)
dispatch[NoneType] = save_none dispatch[NoneType] = save_none
def save_bool(self, object):
if object:
self.write(TRUE)
else:
self.write(FALSE)
dispatch[bool] = save_bool
def save_int(self, object): def save_int(self, object):
if self.bin: if self.bin:
# If the int is small enough to fit in a signed 4-byte 2's-comp # If the int is small enough to fit in a signed 4-byte 2's-comp
...@@ -629,6 +639,14 @@ class Unpickler: ...@@ -629,6 +639,14 @@ class Unpickler:
self.append(None) self.append(None)
dispatch[NONE] = load_none dispatch[NONE] = load_none
def load_false(self):
self.append(False)
dispatch[FALSE] = load_false
def load_true(self):
self.append(True)
dispatch[TRUE] = load_true
def load_int(self): def load_int(self):
data = self.readline() data = self.readline()
try: try:
......
...@@ -4,14 +4,14 @@ test_augassign ...@@ -4,14 +4,14 @@ test_augassign
6 6
[1, 2, 3, 4, 1, 2, 3, 4] [1, 2, 3, 4, 1, 2, 3, 4]
[1, 2, 1, 2, 3] [1, 2, 1, 2, 3]
1 True
1 True
1 True
11 11
1 True
12 12
1 True
1 True
13 13
__add__ called __add__ called
__radd__ called __radd__ called
......
...@@ -31,7 +31,7 @@ h() argument after ** must be a dictionary ...@@ -31,7 +31,7 @@ h() argument after ** must be a dictionary
dir() argument after ** must be a dictionary dir() argument after ** must be a dictionary
NoneType object argument after ** must be a dictionary NoneType object argument after ** must be a dictionary
dir() got multiple values for keyword argument 'b' dir() got multiple values for keyword argument 'b'
3 512 1 3 512 True
3 3
3 3
za () {} -> za() takes exactly 1 argument (0 given) za () {} -> za() takes exactly 1 argument (0 given)
......
...@@ -23,7 +23,7 @@ trggrkg zrffntr pngnybt yvoenel. ...@@ -23,7 +23,7 @@ trggrkg zrffntr pngnybt yvoenel.
wink wink wink wink
bacon bacon
test api 2 test api 2
1 True
gettext gettext
albatross albatross
bacon bacon
......
...@@ -60,6 +60,6 @@ classdef ...@@ -60,6 +60,6 @@ classdef
[3, 4, 5] [3, 4, 5]
[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')] [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')] [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
[0, 0, 0] [False, False, False]
[[1, 2], [3, 4], [5, 6]] [[1, 2], [3, 4], [5, 6]]
[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')] [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]
This diff is collapsed.
...@@ -2329,7 +2329,7 @@ def descrdoc(): ...@@ -2329,7 +2329,7 @@ def descrdoc():
if verbose: print "Testing descriptor doc strings..." if verbose: print "Testing descriptor doc strings..."
def check(descr, what): def check(descr, what):
vereq(descr.__doc__, what) vereq(descr.__doc__, what)
check(file.closed, "flag set if the file is closed") # getset descriptor check(file.closed, "True if the file is closed") # getset descriptor
check(file.name, "file name") # member descriptor check(file.name, "file name") # member descriptor
def setclass(): def setclass():
......
...@@ -48,7 +48,7 @@ Here's the new type at work: ...@@ -48,7 +48,7 @@ Here's the new type at work:
>>> print a.__class__ # show its class >>> print a.__class__ # show its class
<class 'test.test_descrtut.defaultdict'> <class 'test.test_descrtut.defaultdict'>
>>> print type(a) is a.__class__ # its type is its class >>> print type(a) is a.__class__ # its type is its class
1 True
>>> a[1] = 3.25 # modify the instance >>> a[1] = 3.25 # modify the instance
>>> print a # show the new value >>> print a # show the new value
{1: 3.25} {1: 3.25}
...@@ -98,14 +98,14 @@ just like classic classes: ...@@ -98,14 +98,14 @@ just like classic classes:
>>> print a["noway"] >>> print a["noway"]
-1000 -1000
>>> 'default' in dir(a) >>> 'default' in dir(a)
1 True
>>> a.x1 = 100 >>> a.x1 = 100
>>> a.x2 = 200 >>> a.x2 = 200
>>> print a.x1 >>> print a.x1
100 100
>>> d = dir(a) >>> d = dir(a)
>>> 'default' in d and 'x1' in d and 'x2' in d >>> 'default' in d and 'x1' in d and 'x2' in d
1 True
>>> print a.__dict__ >>> print a.__dict__
{'default': -1000, 'x2': 200, 'x1': 100} {'default': -1000, 'x2': 200, 'x1': 100}
>>> >>>
...@@ -167,11 +167,11 @@ For instance of built-in types, x.__class__ is now the same as type(x): ...@@ -167,11 +167,11 @@ For instance of built-in types, x.__class__ is now the same as type(x):
>>> list >>> list
<type 'list'> <type 'list'>
>>> isinstance([], list) >>> isinstance([], list)
1 True
>>> isinstance([], dict) >>> isinstance([], dict)
0 False
>>> isinstance([], object) >>> isinstance([], object)
1 True
>>> >>>
Under the new proposal, the __methods__ attribute no longer exists: Under the new proposal, the __methods__ attribute no longer exists:
......
...@@ -386,10 +386,10 @@ From the Iterators list, about the types of these things. ...@@ -386,10 +386,10 @@ From the Iterators list, about the types of these things.
>>> print i.next.__doc__ >>> print i.next.__doc__
x.next() -> the next value, or raise StopIteration x.next() -> the next value, or raise StopIteration
>>> iter(i) is i >>> iter(i) is i
1 True
>>> import types >>> import types
>>> isinstance(i, types.GeneratorType) >>> isinstance(i, types.GeneratorType)
1 True
And more, added later. And more, added later.
...@@ -1218,16 +1218,16 @@ generated sequence, you need to copy its results. ...@@ -1218,16 +1218,16 @@ generated sequence, you need to copy its results.
>>> for n in range(10): >>> for n in range(10):
... all = list(gencopy(conjoin([lambda: iter((0, 1))] * n))) ... all = list(gencopy(conjoin([lambda: iter((0, 1))] * n)))
... print n, len(all), all[0] == [0] * n, all[-1] == [1] * n ... print n, len(all), all[0] == [0] * n, all[-1] == [1] * n
0 1 1 1 0 1 True True
1 2 1 1 1 2 True True
2 4 1 1 2 4 True True
3 8 1 1 3 8 True True
4 16 1 1 4 16 True True
5 32 1 1 5 32 True True
6 64 1 1 6 64 True True
7 128 1 1 7 128 True True
8 256 1 1 8 256 True True
9 512 1 1 9 512 True True
And run an 8-queens solver. And run an 8-queens solver.
......
...@@ -167,34 +167,34 @@ test('replace', u'one!two!three!', u'one@two@three@', u'!', u'@') ...@@ -167,34 +167,34 @@ test('replace', u'one!two!three!', u'one@two@three@', u'!', u'@')
test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@') test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@')
test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@', 2) test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@', 2)
test('startswith', u'hello', 1, u'he') test('startswith', u'hello', True, u'he')
test('startswith', u'hello', 1, u'hello') test('startswith', u'hello', True, u'hello')
test('startswith', u'hello', 0, u'hello world') test('startswith', u'hello', False, u'hello world')
test('startswith', u'hello', 1, u'') test('startswith', u'hello', True, u'')
test('startswith', u'hello', 0, u'ello') test('startswith', u'hello', False, u'ello')
test('startswith', u'hello', 1, u'ello', 1) test('startswith', u'hello', True, u'ello', 1)
test('startswith', u'hello', 1, u'o', 4) test('startswith', u'hello', True, u'o', 4)
test('startswith', u'hello', 0, u'o', 5) test('startswith', u'hello', False, u'o', 5)
test('startswith', u'hello', 1, u'', 5) test('startswith', u'hello', True, u'', 5)
test('startswith', u'hello', 0, u'lo', 6) test('startswith', u'hello', False, u'lo', 6)
test('startswith', u'helloworld', 1, u'lowo', 3) test('startswith', u'helloworld', True, u'lowo', 3)
test('startswith', u'helloworld', 1, u'lowo', 3, 7) test('startswith', u'helloworld', True, u'lowo', 3, 7)
test('startswith', u'helloworld', 0, u'lowo', 3, 6) test('startswith', u'helloworld', False, u'lowo', 3, 6)
test('endswith', u'hello', 1, u'lo') test('endswith', u'hello', True, u'lo')
test('endswith', u'hello', 0, u'he') test('endswith', u'hello', False, u'he')
test('endswith', u'hello', 1, u'') test('endswith', u'hello', True, u'')
test('endswith', u'hello', 0, u'hello world') test('endswith', u'hello', False, u'hello world')
test('endswith', u'helloworld', 0, u'worl') test('endswith', u'helloworld', False, u'worl')
test('endswith', u'helloworld', 1, u'worl', 3, 9) test('endswith', u'helloworld', True, u'worl', 3, 9)
test('endswith', u'helloworld', 1, u'world', 3, 12) test('endswith', u'helloworld', True, u'world', 3, 12)
test('endswith', u'helloworld', 1, u'lowo', 1, 7) test('endswith', u'helloworld', True, u'lowo', 1, 7)
test('endswith', u'helloworld', 1, u'lowo', 2, 7) test('endswith', u'helloworld', True, u'lowo', 2, 7)
test('endswith', u'helloworld', 1, u'lowo', 3, 7) test('endswith', u'helloworld', True, u'lowo', 3, 7)
test('endswith', u'helloworld', 0, u'lowo', 4, 7) test('endswith', u'helloworld', False, u'lowo', 4, 7)
test('endswith', u'helloworld', 0, u'lowo', 3, 8) test('endswith', u'helloworld', False, u'lowo', 3, 8)
test('endswith', u'ab', 0, u'ab', 0, 1) test('endswith', u'ab', False, u'ab', 0, 1)
test('endswith', u'ab', 0, u'ab', 0, 0) test('endswith', u'ab', False, u'ab', 0, 0)
test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab def\ng hi') test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab def\ng hi')
test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab def\ng hi', 8) test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab def\ng hi', 8)
...@@ -286,50 +286,50 @@ test('ljust', u'abc', u'abc', 2) ...@@ -286,50 +286,50 @@ test('ljust', u'abc', u'abc', 2)
test('rjust', u'abc', u'abc', 2) test('rjust', u'abc', u'abc', 2)
test('center', u'abc', u'abc', 2) test('center', u'abc', u'abc', 2)
test('islower', u'a', 1) test('islower', u'a', True)
test('islower', u'A', 0) test('islower', u'A', False)
test('islower', u'\n', 0) test('islower', u'\n', False)
test('islower', u'\u1FFc', 0) test('islower', u'\u1FFc', False)
test('islower', u'abc', 1) test('islower', u'abc', True)
test('islower', u'aBc', 0) test('islower', u'aBc', False)
test('islower', u'abc\n', 1) test('islower', u'abc\n', True)
test('isupper', u'a', 0) test('isupper', u'a', False)
test('isupper', u'A', 1) test('isupper', u'A', True)
test('isupper', u'\n', 0) test('isupper', u'\n', False)
if sys.platform[:4] != 'java': if sys.platform[:4] != 'java':
test('isupper', u'\u1FFc', 0) test('isupper', u'\u1FFc', False)
test('isupper', u'ABC', 1) test('isupper', u'ABC', True)
test('isupper', u'AbC', 0) test('isupper', u'AbC', False)
test('isupper', u'ABC\n', 1) test('isupper', u'ABC\n', True)
test('istitle', u'a', 0) test('istitle', u'a', False)
test('istitle', u'A', 1) test('istitle', u'A', True)
test('istitle', u'\n', 0) test('istitle', u'\n', False)
test('istitle', u'\u1FFc', 1) test('istitle', u'\u1FFc', True)
test('istitle', u'A Titlecased Line', 1) test('istitle', u'A Titlecased Line', True)
test('istitle', u'A\nTitlecased Line', 1) test('istitle', u'A\nTitlecased Line', True)
test('istitle', u'A Titlecased, Line', 1) test('istitle', u'A Titlecased, Line', True)
test('istitle', u'Greek \u1FFcitlecases ...', 1) test('istitle', u'Greek \u1FFcitlecases ...', True)
test('istitle', u'Not a capitalized String', 0) test('istitle', u'Not a capitalized String', False)
test('istitle', u'Not\ta Titlecase String', 0) test('istitle', u'Not\ta Titlecase String', False)
test('istitle', u'Not--a Titlecase String', 0) test('istitle', u'Not--a Titlecase String', False)
test('isalpha', u'a', 1) test('isalpha', u'a', True)
test('isalpha', u'A', 1) test('isalpha', u'A', True)
test('isalpha', u'\n', 0) test('isalpha', u'\n', False)
test('isalpha', u'\u1FFc', 1) test('isalpha', u'\u1FFc', True)
test('isalpha', u'abc', 1) test('isalpha', u'abc', True)
test('isalpha', u'aBc123', 0) test('isalpha', u'aBc123', False)
test('isalpha', u'abc\n', 0) test('isalpha', u'abc\n', False)
test('isalnum', u'a', 1) test('isalnum', u'a', True)
test('isalnum', u'A', 1) test('isalnum', u'A', True)
test('isalnum', u'\n', 0) test('isalnum', u'\n', False)
test('isalnum', u'123abc456', 1) test('isalnum', u'123abc456', True)
test('isalnum', u'a1b3c', 1) test('isalnum', u'a1b3c', True)
test('isalnum', u'aBc000 ', 0) test('isalnum', u'aBc000 ', False)
test('isalnum', u'abc\n', 0) test('isalnum', u'abc\n', False)
test('splitlines', u"abc\ndef\n\rghi", [u'abc', u'def', u'', u'ghi']) test('splitlines', u"abc\ndef\n\rghi", [u'abc', u'def', u'', u'ghi'])
test('splitlines', u"abc\ndef\n\r\nghi", [u'abc', u'def', u'', u'ghi']) test('splitlines', u"abc\ndef\n\r\nghi", [u'abc', u'def', u'', u'ghi'])
...@@ -337,7 +337,7 @@ test('splitlines', u"abc\ndef\r\nghi", [u'abc', u'def', u'ghi']) ...@@ -337,7 +337,7 @@ test('splitlines', u"abc\ndef\r\nghi", [u'abc', u'def', u'ghi'])
test('splitlines', u"abc\ndef\r\nghi\n", [u'abc', u'def', u'ghi']) test('splitlines', u"abc\ndef\r\nghi\n", [u'abc', u'def', u'ghi'])
test('splitlines', u"abc\ndef\r\nghi\n\r", [u'abc', u'def', u'ghi', u'']) test('splitlines', u"abc\ndef\r\nghi\n\r", [u'abc', u'def', u'ghi', u''])
test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'', u'abc', u'def', u'ghi', u'']) test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'', u'abc', u'def', u'ghi', u''])
test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'\n', u'abc\n', u'def\r\n', u'ghi\n', u'\r'], 1) test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'\n', u'abc\n', u'def\r\n', u'ghi\n', u'\r'], True)
test('translate', u"abababc", u'bbbc', {ord('a'):None}) test('translate', u"abababc", u'bbbc', {ord('a'):None})
test('translate', u"abababc", u'iiic', {ord('a'):None, ord('b'):ord('i')}) test('translate', u"abababc", u'iiic', {ord('a'):None, ord('b'):ord('i')})
......
...@@ -249,6 +249,7 @@ PYTHON_OBJS= \ ...@@ -249,6 +249,7 @@ PYTHON_OBJS= \
# Objects # Objects
OBJECT_OBJS= \ OBJECT_OBJS= \
Objects/abstract.o \ Objects/abstract.o \
Objects/boolobject.o \
Objects/bufferobject.o \ Objects/bufferobject.o \
Objects/cellobject.o \ Objects/cellobject.o \
Objects/classobject.o \ Objects/classobject.o \
...@@ -431,6 +432,7 @@ Objects/unicodectype.o: $(srcdir)/Objects/unicodectype.c \ ...@@ -431,6 +432,7 @@ Objects/unicodectype.o: $(srcdir)/Objects/unicodectype.c \
PYTHON_HEADERS= \ PYTHON_HEADERS= \
Include/Python.h \ Include/Python.h \
Include/abstract.h \ Include/abstract.h \
Include/boolobject.h \
Include/bufferobject.h \ Include/bufferobject.h \
Include/ceval.h \ Include/ceval.h \
Include/classobject.h \ Include/classobject.h \
......
...@@ -125,6 +125,9 @@ LONG Long (unbounded) integer; repr(i), then newline. ...@@ -125,6 +125,9 @@ LONG Long (unbounded) integer; repr(i), then newline.
#define TUPLE 't' #define TUPLE 't'
#define EMPTY_TUPLE ')' #define EMPTY_TUPLE ')'
#define SETITEMS 'u' #define SETITEMS 'u'
#define TRUE 'Z'
#define FALSE 'z'
static char MARKv = MARK; static char MARKv = MARK;
...@@ -978,6 +981,17 @@ save_none(Picklerobject *self, PyObject *args) ...@@ -978,6 +981,17 @@ save_none(Picklerobject *self, PyObject *args)
return 0; return 0;
} }
static int
save_bool(Picklerobject *self, PyObject *args)
{
static char buf[2] = {FALSE, TRUE};
long l = PyInt_AS_LONG((PyIntObject *)args);
if ((*self->write_func)(self, buf + l, 1) < 0)
return -1;
return 0;
}
static int static int
save_int(Picklerobject *self, PyObject *args) save_int(Picklerobject *self, PyObject *args)
...@@ -1921,6 +1935,12 @@ save(Picklerobject *self, PyObject *args, int pers_save) ...@@ -1921,6 +1935,12 @@ save(Picklerobject *self, PyObject *args, int pers_save)
type = args->ob_type; type = args->ob_type;
switch (type->tp_name[0]) { switch (type->tp_name[0]) {
case 'b':
if (args == Py_False || args == Py_True) {
res = save_bool(self, args);
goto finally;
}
break;
case 'i': case 'i':
if (type == &PyInt_Type) { if (type == &PyInt_Type) {
res = save_int(self, args); res = save_int(self, args);
...@@ -2635,6 +2655,20 @@ load_none(Unpicklerobject *self) ...@@ -2635,6 +2655,20 @@ load_none(Unpicklerobject *self)
return 0; return 0;
} }
static int
load_false(Unpicklerobject *self)
{
PDATA_APPEND(self->stack, Py_False, -1);
return 0;
}
static int
load_true(Unpicklerobject *self)
{
PDATA_APPEND(self->stack, Py_True, -1);
return 0;
}
static int static int
bad_readline(void) bad_readline(void)
{ {
...@@ -3777,6 +3811,16 @@ load(Unpicklerobject *self) ...@@ -3777,6 +3811,16 @@ load(Unpicklerobject *self)
break; break;
continue; continue;
case FALSE:
if (load_false(self) < 0)
break;
continue;
case TRUE:
if (load_true(self) < 0)
break;
continue;
case BININT: case BININT:
if (load_binint(self) < 0) if (load_binint(self) < 0)
break; break;
......
...@@ -102,7 +102,7 @@ used for special class methods; variants without leading and trailing\n\ ...@@ -102,7 +102,7 @@ used for special class methods; variants without leading and trailing\n\
PyObject *a1; long r; \ PyObject *a1; long r; \
if(! PyArg_ParseTuple(a,"O:" #OP,&a1)) return NULL; \ if(! PyArg_ParseTuple(a,"O:" #OP,&a1)) return NULL; \
if(-1 == (r=AOP(a1))) return NULL; \ if(-1 == (r=AOP(a1))) return NULL; \
return PyInt_FromLong(r); } return PyBool_FromLong(r); }
#define spami2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \ #define spami2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
PyObject *a1, *a2; long r; \ PyObject *a1, *a2; long r; \
...@@ -110,6 +110,12 @@ used for special class methods; variants without leading and trailing\n\ ...@@ -110,6 +110,12 @@ used for special class methods; variants without leading and trailing\n\
if(-1 == (r=AOP(a1,a2))) return NULL; \ if(-1 == (r=AOP(a1,a2))) return NULL; \
return PyInt_FromLong(r); } return PyInt_FromLong(r); }
#define spami2b(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
PyObject *a1, *a2; long r; \
if(! PyArg_ParseTuple(a,"OO:" #OP,&a1,&a2)) return NULL; \
if(-1 == (r=AOP(a1,a2))) return NULL; \
return PyBool_FromLong(r); }
#define spamrc(OP,A) static PyObject *OP(PyObject *s, PyObject *a) { \ #define spamrc(OP,A) static PyObject *OP(PyObject *s, PyObject *a) { \
PyObject *a1, *a2; \ PyObject *a1, *a2; \
if(! PyArg_ParseTuple(a,"OO:" #OP,&a1,&a2)) return NULL; \ if(! PyArg_ParseTuple(a,"OO:" #OP,&a1,&a2)) return NULL; \
...@@ -139,8 +145,8 @@ spam2(op_or_ , PyNumber_Or) ...@@ -139,8 +145,8 @@ spam2(op_or_ , PyNumber_Or)
spami(isSequenceType , PySequence_Check) spami(isSequenceType , PySequence_Check)
spam2(op_concat , PySequence_Concat) spam2(op_concat , PySequence_Concat)
spamoi(op_repeat , PySequence_Repeat) spamoi(op_repeat , PySequence_Repeat)
spami2(op_contains , PySequence_Contains) spami2b(op_contains , PySequence_Contains)
spami2(sequenceIncludes, PySequence_Contains) spami2b(sequenceIncludes, PySequence_Contains)
spami2(indexOf , PySequence_Index) spami2(indexOf , PySequence_Index)
spami2(countOf , PySequence_Count) spami2(countOf , PySequence_Count)
spami(isMappingType , PyMapping_Check) spami(isMappingType , PyMapping_Check)
...@@ -208,11 +214,11 @@ static struct PyMethodDef operator_methods[] = { ...@@ -208,11 +214,11 @@ static struct PyMethodDef operator_methods[] = {
spam1(isCallable, spam1(isCallable,
"isCallable(a) -- Same as callable(a).") "isCallable(a) -- Same as callable(a).")
spam1(isNumberType, spam1(isNumberType,
"isNumberType(a) -- Return 1 if a has a numeric type, and zero otherwise.") "isNumberType(a) -- Return True if a has a numeric type, False otherwise.")
spam1(isSequenceType, spam1(isSequenceType,
"isSequenceType(a) -- Return 1 if a has a sequence type, and zero otherwise.") "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.")
spam1(truth, spam1(truth,
"truth(a) -- Return 1 if a is true, and 0 otherwise.") "truth(a) -- Return True if a is true, False otherwise.")
spam2(contains,__contains__, spam2(contains,__contains__,
"contains(a, b) -- Same as b in a (note reversed operands).") "contains(a, b) -- Same as b in a (note reversed operands).")
spam1(sequenceIncludes, spam1(sequenceIncludes,
...@@ -222,7 +228,7 @@ spam1(indexOf, ...@@ -222,7 +228,7 @@ spam1(indexOf,
spam1(countOf, spam1(countOf,
"countOf(a, b) -- Return the number of times b occurs in a.") "countOf(a, b) -- Return the number of times b occurs in a.")
spam1(isMappingType, spam1(isMappingType,
"isMappingType(a) -- Return 1 if a has a mapping type, and zero otherwise.") "isMappingType(a) -- Return True if a has a mapping type, False otherwise.")
spam2(add,__add__, "add(a, b) -- Same as a + b.") spam2(add,__add__, "add(a, b) -- Same as a + b.")
spam2(sub,__sub__, "sub(a, b) -- Same as a - b.") spam2(sub,__sub__, "sub(a, b) -- Same as a - b.")
......
...@@ -1429,7 +1429,7 @@ dict_has_key(register dictobject *mp, PyObject *key) ...@@ -1429,7 +1429,7 @@ dict_has_key(register dictobject *mp, PyObject *key)
return NULL; return NULL;
} }
ok = (mp->ma_lookup)(mp, key, hash)->me_value != NULL; ok = (mp->ma_lookup)(mp, key, hash)->me_value != NULL;
return PyInt_FromLong(ok); return PyBool_FromLong(ok);
} }
static PyObject * static PyObject *
......
...@@ -1444,7 +1444,7 @@ static char flush_doc[] = ...@@ -1444,7 +1444,7 @@ static char flush_doc[] =
static char close_doc[] = static char close_doc[] =
"close() -> None or (perhaps) an integer. Close the file.\n" "close() -> None or (perhaps) an integer. Close the file.\n"
"\n" "\n"
"Sets data attribute .closed to true. A closed file cannot be used for\n" "Sets data attribute .closed to True. A closed file cannot be used for\n"
"further I/O operations. close() may be called more than once without\n" "further I/O operations. close() may be called more than once without\n"
"error. Some kinds of file objects (for example, opened by popen())\n" "error. Some kinds of file objects (for example, opened by popen())\n"
"may return an exit status upon closing."; "may return an exit status upon closing.";
...@@ -1488,11 +1488,11 @@ static PyMemberDef file_memberlist[] = { ...@@ -1488,11 +1488,11 @@ static PyMemberDef file_memberlist[] = {
static PyObject * static PyObject *
get_closed(PyFileObject *f, void *closure) get_closed(PyFileObject *f, void *closure)
{ {
return PyInt_FromLong((long)(f->f_fp == 0)); return PyBool_FromLong((long)(f->f_fp == 0));
} }
static PyGetSetDef file_getsetlist[] = { static PyGetSetDef file_getsetlist[] = {
{"closed", (getter)get_closed, NULL, "flag set if the file is closed"}, {"closed", (getter)get_closed, NULL, "True if the file is closed"},
{0}, {0},
}; };
......
...@@ -10,18 +10,6 @@ PyInt_GetMax(void) ...@@ -10,18 +10,6 @@ PyInt_GetMax(void)
return LONG_MAX; /* To initialize sys.maxint */ return LONG_MAX; /* To initialize sys.maxint */
} }
/* Standard Booleans */
PyIntObject _Py_ZeroStruct = {
PyObject_HEAD_INIT(&PyInt_Type)
0
};
PyIntObject _Py_TrueStruct = {
PyObject_HEAD_INIT(&PyInt_Type)
1
};
/* Return 1 if exception raised, 0 if caller should retry using longs */ /* Return 1 if exception raised, 0 if caller should retry using longs */
static int static int
err_ovf(char *msg) err_ovf(char *msg)
......
...@@ -1763,6 +1763,9 @@ _Py_ReadyTypes(void) ...@@ -1763,6 +1763,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyType_Type) < 0) if (PyType_Ready(&PyType_Type) < 0)
Py_FatalError("Can't initialize 'type'"); Py_FatalError("Can't initialize 'type'");
if (PyType_Ready(&PyBool_Type) < 0)
Py_FatalError("Can't initialize 'bool'");
if (PyType_Ready(&PyList_Type) < 0) if (PyType_Ready(&PyList_Type) < 0)
Py_FatalError("Can't initialize 'list'"); Py_FatalError("Can't initialize 'list'");
......
...@@ -2000,9 +2000,9 @@ string_replace(PyStringObject *self, PyObject *args) ...@@ -2000,9 +2000,9 @@ string_replace(PyStringObject *self, PyObject *args)
static char startswith__doc__[] = static char startswith__doc__[] =
"S.startswith(prefix[, start[, end]]) -> int\n\ "S.startswith(prefix[, start[, end]]) -> bool\n\
\n\ \n\
Return 1 if S starts with the specified prefix, otherwise return 0. With\n\ Return True if S starts with the specified prefix, False otherwise. With\n\
optional start, test S beginning at that position. With optional end, stop\n\ optional start, test S beginning at that position. With optional end, stop\n\
comparing S at that position."; comparing S at that position.";
...@@ -2032,7 +2032,7 @@ string_startswith(PyStringObject *self, PyObject *args) ...@@ -2032,7 +2032,7 @@ string_startswith(PyStringObject *self, PyObject *args)
if (rc == -1) if (rc == -1)
return NULL; return NULL;
else else
return PyInt_FromLong((long) rc); return PyBool_FromLong((long) rc);
} }
#endif #endif
else if (PyObject_AsCharBuffer(subobj, &prefix, &plen)) else if (PyObject_AsCharBuffer(subobj, &prefix, &plen))
...@@ -2043,25 +2043,25 @@ string_startswith(PyStringObject *self, PyObject *args) ...@@ -2043,25 +2043,25 @@ string_startswith(PyStringObject *self, PyObject *args)
* the empty string. * the empty string.
*/ */
if (start < 0 || start+plen > len) if (start < 0 || start+plen > len)
return PyInt_FromLong(0); return PyBool_FromLong(0);
if (!memcmp(str+start, prefix, plen)) { if (!memcmp(str+start, prefix, plen)) {
/* did the match end after the specified end? */ /* did the match end after the specified end? */
if (end < 0) if (end < 0)
return PyInt_FromLong(1); return PyBool_FromLong(1);
else if (end - start < plen) else if (end - start < plen)
return PyInt_FromLong(0); return PyBool_FromLong(0);
else else
return PyInt_FromLong(1); return PyBool_FromLong(1);
} }
else return PyInt_FromLong(0); else return PyBool_FromLong(0);
} }
static char endswith__doc__[] = static char endswith__doc__[] =
"S.endswith(suffix[, start[, end]]) -> int\n\ "S.endswith(suffix[, start[, end]]) -> bool\n\
\n\ \n\
Return 1 if S ends with the specified suffix, otherwise return 0. With\n\ Return True if S ends with the specified suffix, False otherwise. With\n\
optional start, test S beginning at that position. With optional end, stop\n\ optional start, test S beginning at that position. With optional end, stop\n\
comparing S at that position."; comparing S at that position.";
...@@ -2092,21 +2092,21 @@ string_endswith(PyStringObject *self, PyObject *args) ...@@ -2092,21 +2092,21 @@ string_endswith(PyStringObject *self, PyObject *args)
if (rc == -1) if (rc == -1)
return NULL; return NULL;
else else
return PyInt_FromLong((long) rc); return PyBool_FromLong((long) rc);
} }
#endif #endif
else if (PyObject_AsCharBuffer(subobj, &suffix, &slen)) else if (PyObject_AsCharBuffer(subobj, &suffix, &slen))
return NULL; return NULL;
if (start < 0 || start > len || slen > len) if (start < 0 || start > len || slen > len)
return PyInt_FromLong(0); return PyBool_FromLong(0);
upper = (end >= 0 && end <= len) ? end : len; upper = (end >= 0 && end <= len) ? end : len;
lower = (upper - slen) > start ? (upper - slen) : start; lower = (upper - slen) > start ? (upper - slen) : start;
if (upper-lower >= slen && !memcmp(str+lower, suffix, slen)) if (upper-lower >= slen && !memcmp(str+lower, suffix, slen))
return PyInt_FromLong(1); return PyBool_FromLong(1);
else return PyInt_FromLong(0); else return PyBool_FromLong(0);
} }
...@@ -2311,10 +2311,10 @@ string_center(PyStringObject *self, PyObject *args) ...@@ -2311,10 +2311,10 @@ string_center(PyStringObject *self, PyObject *args)
} }
static char isspace__doc__[] = static char isspace__doc__[] =
"S.isspace() -> int\n" "S.isspace() -> bool\n"
"\n" "\n"
"Return 1 if there are only whitespace characters in S,\n" "Return True if there are only whitespace characters in S,\n"
"0 otherwise."; "False otherwise.";
static PyObject* static PyObject*
string_isspace(PyStringObject *self) string_isspace(PyStringObject *self)
...@@ -2326,26 +2326,26 @@ string_isspace(PyStringObject *self) ...@@ -2326,26 +2326,26 @@ string_isspace(PyStringObject *self)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1 && if (PyString_GET_SIZE(self) == 1 &&
isspace(*p)) isspace(*p))
return PyInt_FromLong(1); return PyBool_FromLong(1);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
for (; p < e; p++) { for (; p < e; p++) {
if (!isspace(*p)) if (!isspace(*p))
return PyInt_FromLong(0); return PyBool_FromLong(0);
} }
return PyInt_FromLong(1); return PyBool_FromLong(1);
} }
static char isalpha__doc__[] = static char isalpha__doc__[] =
"S.isalpha() -> int\n\ "S.isalpha() -> bool\n\
\n\ \n\
Return 1 if all characters in S are alphabetic\n\ Return True if all characters in S are alphabetic\n\
and there is at least one character in S, 0 otherwise."; and there is at least one character in S, False otherwise.";
static PyObject* static PyObject*
string_isalpha(PyStringObject *self) string_isalpha(PyStringObject *self)
...@@ -2357,26 +2357,26 @@ string_isalpha(PyStringObject *self) ...@@ -2357,26 +2357,26 @@ string_isalpha(PyStringObject *self)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1 && if (PyString_GET_SIZE(self) == 1 &&
isalpha(*p)) isalpha(*p))
return PyInt_FromLong(1); return PyBool_FromLong(1);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
for (; p < e; p++) { for (; p < e; p++) {
if (!isalpha(*p)) if (!isalpha(*p))
return PyInt_FromLong(0); return PyBool_FromLong(0);
} }
return PyInt_FromLong(1); return PyBool_FromLong(1);
} }
static char isalnum__doc__[] = static char isalnum__doc__[] =
"S.isalnum() -> int\n\ "S.isalnum() -> bool\n\
\n\ \n\
Return 1 if all characters in S are alphanumeric\n\ Return True if all characters in S are alphanumeric\n\
and there is at least one character in S, 0 otherwise."; and there is at least one character in S, False otherwise.";
static PyObject* static PyObject*
string_isalnum(PyStringObject *self) string_isalnum(PyStringObject *self)
...@@ -2388,26 +2388,26 @@ string_isalnum(PyStringObject *self) ...@@ -2388,26 +2388,26 @@ string_isalnum(PyStringObject *self)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1 && if (PyString_GET_SIZE(self) == 1 &&
isalnum(*p)) isalnum(*p))
return PyInt_FromLong(1); return PyBool_FromLong(1);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
for (; p < e; p++) { for (; p < e; p++) {
if (!isalnum(*p)) if (!isalnum(*p))
return PyInt_FromLong(0); return PyBool_FromLong(0);
} }
return PyInt_FromLong(1); return PyBool_FromLong(1);
} }
static char isdigit__doc__[] = static char isdigit__doc__[] =
"S.isdigit() -> int\n\ "S.isdigit() -> bool\n\
\n\ \n\
Return 1 if there are only digit characters in S,\n\ Return True if there are only digit characters in S,\n\
0 otherwise."; False otherwise.";
static PyObject* static PyObject*
string_isdigit(PyStringObject *self) string_isdigit(PyStringObject *self)
...@@ -2419,26 +2419,26 @@ string_isdigit(PyStringObject *self) ...@@ -2419,26 +2419,26 @@ string_isdigit(PyStringObject *self)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1 && if (PyString_GET_SIZE(self) == 1 &&
isdigit(*p)) isdigit(*p))
return PyInt_FromLong(1); return PyBool_FromLong(1);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
for (; p < e; p++) { for (; p < e; p++) {
if (!isdigit(*p)) if (!isdigit(*p))
return PyInt_FromLong(0); return PyBool_FromLong(0);
} }
return PyInt_FromLong(1); return PyBool_FromLong(1);
} }
static char islower__doc__[] = static char islower__doc__[] =
"S.islower() -> int\n\ "S.islower() -> bool\n\
\n\ \n\
Return 1 if all cased characters in S are lowercase and there is\n\ Return True if all cased characters in S are lowercase and there is\n\
at least one cased character in S, 0 otherwise."; at least one cased character in S, False otherwise.";
static PyObject* static PyObject*
string_islower(PyStringObject *self) string_islower(PyStringObject *self)
...@@ -2450,29 +2450,29 @@ string_islower(PyStringObject *self) ...@@ -2450,29 +2450,29 @@ string_islower(PyStringObject *self)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1) if (PyString_GET_SIZE(self) == 1)
return PyInt_FromLong(islower(*p) != 0); return PyBool_FromLong(islower(*p) != 0);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
cased = 0; cased = 0;
for (; p < e; p++) { for (; p < e; p++) {
if (isupper(*p)) if (isupper(*p))
return PyInt_FromLong(0); return PyBool_FromLong(0);
else if (!cased && islower(*p)) else if (!cased && islower(*p))
cased = 1; cased = 1;
} }
return PyInt_FromLong(cased); return PyBool_FromLong(cased);
} }
static char isupper__doc__[] = static char isupper__doc__[] =
"S.isupper() -> int\n\ "S.isupper() -> bool\n\
\n\ \n\
Return 1 if all cased characters in S are uppercase and there is\n\ Return True if all cased characters in S are uppercase and there is\n\
at least one cased character in S, 0 otherwise."; at least one cased character in S, False otherwise.";
static PyObject* static PyObject*
string_isupper(PyStringObject *self) string_isupper(PyStringObject *self)
...@@ -2484,30 +2484,30 @@ string_isupper(PyStringObject *self) ...@@ -2484,30 +2484,30 @@ string_isupper(PyStringObject *self)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1) if (PyString_GET_SIZE(self) == 1)
return PyInt_FromLong(isupper(*p) != 0); return PyBool_FromLong(isupper(*p) != 0);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
cased = 0; cased = 0;
for (; p < e; p++) { for (; p < e; p++) {
if (islower(*p)) if (islower(*p))
return PyInt_FromLong(0); return PyBool_FromLong(0);
else if (!cased && isupper(*p)) else if (!cased && isupper(*p))
cased = 1; cased = 1;
} }
return PyInt_FromLong(cased); return PyBool_FromLong(cased);
} }
static char istitle__doc__[] = static char istitle__doc__[] =
"S.istitle() -> int\n\ "S.istitle() -> bool\n\
\n\ \n\
Return 1 if S is a titlecased string, i.e. uppercase characters\n\ Return True if S is a titlecased string, i.e. uppercase characters\n\
may only follow uncased characters and lowercase characters only cased\n\ may only follow uncased characters and lowercase characters only cased\n\
ones. Return 0 otherwise."; ones. Return False otherwise.";
static PyObject* static PyObject*
string_istitle(PyStringObject *self, PyObject *uncased) string_istitle(PyStringObject *self, PyObject *uncased)
...@@ -2519,11 +2519,11 @@ string_istitle(PyStringObject *self, PyObject *uncased) ...@@ -2519,11 +2519,11 @@ string_istitle(PyStringObject *self, PyObject *uncased)
/* Shortcut for single character strings */ /* Shortcut for single character strings */
if (PyString_GET_SIZE(self) == 1) if (PyString_GET_SIZE(self) == 1)
return PyInt_FromLong(isupper(*p) != 0); return PyBool_FromLong(isupper(*p) != 0);
/* Special case for empty strings */ /* Special case for empty strings */
if (PyString_GET_SIZE(self) == 0) if (PyString_GET_SIZE(self) == 0)
return PyInt_FromLong(0); return PyBool_FromLong(0);
e = p + PyString_GET_SIZE(self); e = p + PyString_GET_SIZE(self);
cased = 0; cased = 0;
...@@ -2533,20 +2533,20 @@ string_istitle(PyStringObject *self, PyObject *uncased) ...@@ -2533,20 +2533,20 @@ string_istitle(PyStringObject *self, PyObject *uncased)
if (isupper(ch)) { if (isupper(ch)) {
if (previous_is_cased) if (previous_is_cased)
return PyInt_FromLong(0); return PyBool_FromLong(0);
previous_is_cased = 1; previous_is_cased = 1;
cased = 1; cased = 1;
} }
else if (islower(ch)) { else if (islower(ch)) {
if (!previous_is_cased) if (!previous_is_cased)
return PyInt_FromLong(0); return PyBool_FromLong(0);
previous_is_cased = 1; previous_is_cased = 1;
cased = 1; cased = 1;
} }
else else
previous_is_cased = 0; previous_is_cased = 0;
} }
return PyInt_FromLong(cased); return PyBool_FromLong(cased);
} }
......
This diff is collapsed.
...@@ -130,11 +130,11 @@ extend to the end of the target object (or with the specified size)."; ...@@ -130,11 +130,11 @@ extend to the end of the target object (or with the specified size).";
static PyObject * static PyObject *
builtin_callable(PyObject *self, PyObject *v) builtin_callable(PyObject *self, PyObject *v)
{ {
return PyInt_FromLong((long)PyCallable_Check(v)); return PyBool_FromLong((long)PyCallable_Check(v));
} }
static char callable_doc[] = static char callable_doc[] =
"callable(object) -> Boolean\n\ "callable(object) -> bool\n\
\n\ \n\
Return whether the object is callable (i.e., some kind of function).\n\ Return whether the object is callable (i.e., some kind of function).\n\
Note that classes are callable, as are instances with a __call__() method."; Note that classes are callable, as are instances with a __call__() method.";
...@@ -713,7 +713,7 @@ builtin_hasattr(PyObject *self, PyObject *args) ...@@ -713,7 +713,7 @@ builtin_hasattr(PyObject *self, PyObject *args)
} }
static char hasattr_doc[] = static char hasattr_doc[] =
"hasattr(object, name) -> Boolean\n\ "hasattr(object, name) -> bool\n\
\n\ \n\
Return whether the object has an attribute with the given name.\n\ Return whether the object has an attribute with the given name.\n\
(This is done by calling getattr(object, name) and catching exceptions.)"; (This is done by calling getattr(object, name) and catching exceptions.)";
...@@ -1666,11 +1666,11 @@ builtin_isinstance(PyObject *self, PyObject *args) ...@@ -1666,11 +1666,11 @@ builtin_isinstance(PyObject *self, PyObject *args)
retval = PyObject_IsInstance(inst, cls); retval = PyObject_IsInstance(inst, cls);
if (retval < 0) if (retval < 0)
return NULL; return NULL;
return PyInt_FromLong(retval); return PyBool_FromLong(retval);
} }
static char isinstance_doc[] = static char isinstance_doc[] =
"isinstance(object, class-or-type-or-tuple) -> Boolean\n\ "isinstance(object, class-or-type-or-tuple) -> bool\n\
\n\ \n\
Return whether an object is an instance of a class or of a subclass thereof.\n\ Return whether an object is an instance of a class or of a subclass thereof.\n\
With a type as second argument, return whether that is the object's type.\n\ With a type as second argument, return whether that is the object's type.\n\
...@@ -1691,11 +1691,11 @@ builtin_issubclass(PyObject *self, PyObject *args) ...@@ -1691,11 +1691,11 @@ builtin_issubclass(PyObject *self, PyObject *args)
retval = PyObject_IsSubclass(derived, cls); retval = PyObject_IsSubclass(derived, cls);
if (retval < 0) if (retval < 0)
return NULL; return NULL;
return PyInt_FromLong(retval); return PyBool_FromLong(retval);
} }
static char issubclass_doc[] = static char issubclass_doc[] =
"issubclass(C, B) -> Boolean\n\ "issubclass(C, B) -> bool\n\
\n\ \n\
Return whether class C is a subclass (i.e., a derived class) of class B."; Return whether class C is a subclass (i.e., a derived class) of class B.";
...@@ -1856,6 +1856,9 @@ _PyBuiltin_Init(void) ...@@ -1856,6 +1856,9 @@ _PyBuiltin_Init(void)
SETBUILTIN("None", Py_None); SETBUILTIN("None", Py_None);
SETBUILTIN("Ellipsis", Py_Ellipsis); SETBUILTIN("Ellipsis", Py_Ellipsis);
SETBUILTIN("NotImplemented", Py_NotImplemented); SETBUILTIN("NotImplemented", Py_NotImplemented);
SETBUILTIN("False", Py_False);
SETBUILTIN("True", Py_True);
SETBUILTIN("bool", &PyBool_Type);
SETBUILTIN("classmethod", &PyClassMethod_Type); SETBUILTIN("classmethod", &PyClassMethod_Type);
#ifndef WITHOUT_COMPLEX #ifndef WITHOUT_COMPLEX
SETBUILTIN("complex", &PyComplex_Type); SETBUILTIN("complex", &PyComplex_Type);
...@@ -1879,7 +1882,7 @@ _PyBuiltin_Init(void) ...@@ -1879,7 +1882,7 @@ _PyBuiltin_Init(void)
#ifdef Py_USING_UNICODE #ifdef Py_USING_UNICODE
SETBUILTIN("unicode", &PyUnicode_Type); SETBUILTIN("unicode", &PyUnicode_Type);
#endif #endif
debug = PyInt_FromLong(Py_OptimizeFlag == 0); debug = PyBool_FromLong(Py_OptimizeFlag == 0);
if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
Py_XDECREF(debug); Py_XDECREF(debug);
return NULL; return NULL;
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define TYPE_NULL '0' #define TYPE_NULL '0'
#define TYPE_NONE 'N' #define TYPE_NONE 'N'
#define TYPE_FALSE 'F'
#define TYPE_TRUE 'T'
#define TYPE_STOPITER 'S' #define TYPE_STOPITER 'S'
#define TYPE_ELLIPSIS '.' #define TYPE_ELLIPSIS '.'
#define TYPE_INT 'i' #define TYPE_INT 'i'
...@@ -126,6 +128,12 @@ w_object(PyObject *v, WFILE *p) ...@@ -126,6 +128,12 @@ w_object(PyObject *v, WFILE *p)
else if (v == Py_Ellipsis) { else if (v == Py_Ellipsis) {
w_byte(TYPE_ELLIPSIS, p); w_byte(TYPE_ELLIPSIS, p);
} }
else if (v == Py_False) {
w_byte(TYPE_FALSE, p);
}
else if (v == Py_True) {
w_byte(TYPE_TRUE, p);
}
else if (PyInt_Check(v)) { else if (PyInt_Check(v)) {
long x = PyInt_AS_LONG((PyIntObject *)v); long x = PyInt_AS_LONG((PyIntObject *)v);
#if SIZEOF_LONG > 4 #if SIZEOF_LONG > 4
...@@ -398,6 +406,14 @@ r_object(RFILE *p) ...@@ -398,6 +406,14 @@ r_object(RFILE *p)
Py_INCREF(Py_Ellipsis); Py_INCREF(Py_Ellipsis);
return Py_Ellipsis; return Py_Ellipsis;
case TYPE_FALSE:
Py_INCREF(Py_False);
return Py_False;
case TYPE_TRUE:
Py_INCREF(Py_True);
return Py_True;
case TYPE_INT: case TYPE_INT:
return PyInt_FromLong(r_long(p)); return PyInt_FromLong(r_long(p));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment