Oops. Here are the new files. My apologies.

This commit is contained in:
Guido van Rossum 2002-04-03 23:01:45 +00:00
parent 3a52ff6df4
commit 5f8203679d
3 changed files with 460 additions and 0 deletions

20
Include/boolobject.h Normal file
View File

@ -0,0 +1,20 @@
/* Boolean object interface */
typedef PyIntObject PyBoolObject;
extern DL_IMPORT(PyTypeObject) PyBool_Type;
#define PyBool_Check(x) ((x)->ob_type == &PyBool_Type)
/* Py_False and Py_True are the only two bools in existence.
Don't forget to apply Py_INCREF() when returning either!!! */
/* Don't use these directly */
extern DL_IMPORT(PyIntObject) _Py_ZeroStruct, _Py_TrueStruct;
/* Use these macros */
#define Py_False ((PyObject *) &_Py_ZeroStruct)
#define Py_True ((PyObject *) &_Py_TrueStruct)
/* Function to return a bool from a C long */
PyObject *PyBool_FromLong(long);

228
Lib/test/test_bool.py Normal file
View File

@ -0,0 +1,228 @@
# Test properties of bool promised by PEP 285
from test_support import verbose, TestFailed, TESTFN, vereq
def veris(a, b):
if a is not b:
raise TestFailed, "%r is %r" % (a, b)
def verisnot(a, b):
if a is b:
raise TestFailed, "%r is %r" % (a, b)
try:
class C(bool):
pass
except TypeError:
pass
else:
raise TestFailed, "bool should not be subclassable"
try:
int.__new__(bool, 0)
except TypeError:
pass
else:
raise TestFailed, "should not be able to create new bool instances"
vereq(int(False), 0)
verisnot(int(False), False)
vereq(int(True), 1)
verisnot(int(True), True)
vereq(+False, 0)
verisnot(+False, False)
vereq(-False, 0)
verisnot(-False, False)
vereq(abs(False), 0)
verisnot(abs(False), False)
vereq(+True, 1)
verisnot(+True, True)
vereq(-True, -1)
vereq(abs(True), 1)
verisnot(abs(True), True)
vereq(~False, -1)
vereq(~True, -2)
vereq(False+2, 2)
vereq(True+2, 3)
vereq(2+False, 2)
vereq(2+True, 3)
vereq(False+False, 0)
verisnot(False+False, False)
vereq(False+True, 1)
verisnot(False+True, True)
vereq(True+False, 1)
verisnot(True+False, True)
vereq(True+True, 2)
vereq(True-True, 0)
verisnot(True-True, False)
vereq(False-False, 0)
verisnot(False-False, False)
vereq(True-False, 1)
verisnot(True-False, True)
vereq(False-True, -1)
vereq(True*1, 1)
vereq(False*1, 0)
verisnot(False*1, False)
vereq(True/1, 1)
verisnot(True/1, True)
vereq(False/1, 0)
verisnot(False/1, False)
for b in False, True:
for i in 0, 1, 2:
vereq(b**i, int(b)**i)
verisnot(b**i, bool(int(b)**i))
for a in False, True:
for b in False, True:
veris(a&b, bool(int(a)&int(b)))
veris(a|b, bool(int(a)|int(b)))
veris(a^b, bool(int(a)^int(b)))
vereq(a&int(b), int(a)&int(b))
verisnot(a&int(b), bool(int(a)&int(b)))
vereq(a|int(b), int(a)|int(b))
verisnot(a|int(b), bool(int(a)|int(b)))
vereq(a^int(b), int(a)^int(b))
verisnot(a^int(b), bool(int(a)^int(b)))
vereq(int(a)&b, int(a)&int(b))
verisnot(int(a)&b, bool(int(a)&int(b)))
vereq(int(a)|b, int(a)|int(b))
verisnot(int(a)|b, bool(int(a)|int(b)))
vereq(int(a)^b, int(a)^int(b))
verisnot(int(a)^b, bool(int(a)^int(b)))
veris(1==1, True)
veris(1==0, False)
# XXX <, <=, >, >=, !=
x = [1]
veris(x is x, True)
veris(x is not x, False)
veris(1 in x, True)
veris(0 in x, False)
veris(1 not in x, False)
veris(0 not in x, True)
veris(not True, False)
veris(not False, True)
veris(bool(10), True)
veris(bool(1), True)
veris(bool(-1), True)
veris(bool(0), False)
veris(bool("hello"), True)
veris(bool(""), False)
veris(hasattr([], "append"), True)
veris(hasattr([], "wobble"), False)
veris(callable(len), True)
veris(callable(1), False)
veris(isinstance(True, bool), True)
veris(isinstance(False, bool), True)
veris(isinstance(True, int), True)
veris(isinstance(False, int), True)
veris(isinstance(1, bool), False)
veris(isinstance(0, bool), False)
veris(issubclass(bool, int), True)
veris(issubclass(int, bool), False)
veris({}.has_key(1), False)
veris({1:1}.has_key(1), True)
veris("xyz".endswith("z"), True)
veris("xyz".endswith("x"), False)
veris("xyz0123".isalnum(), True)
veris("@#$%".isalnum(), False)
veris("xyz".isalpha(), True)
veris("@#$%".isalpha(), False)
veris("0123".isdigit(), True)
veris("xyz".isdigit(), False)
veris("xyz".islower(), True)
veris("XYZ".islower(), False)
veris(" ".isspace(), True)
veris("XYZ".isspace(), False)
veris("X".istitle(), True)
veris("x".istitle(), False)
veris("XYZ".isupper(), True)
veris("xyz".isupper(), False)
veris("xyz".startswith("x"), True)
veris("xyz".startswith("z"), False)
veris(u"xyz".endswith(u"z"), True)
veris(u"xyz".endswith(u"x"), False)
veris(u"xyz0123".isalnum(), True)
veris(u"@#$%".isalnum(), False)
veris(u"xyz".isalpha(), True)
veris(u"@#$%".isalpha(), False)
veris(u"0123".isdecimal(), True)
veris(u"xyz".isdecimal(), False)
veris(u"0123".isdigit(), True)
veris(u"xyz".isdigit(), False)
veris(u"xyz".islower(), True)
veris(u"XYZ".islower(), False)
veris(u"0123".isnumeric(), True)
veris(u"xyz".isnumeric(), False)
veris(u" ".isspace(), True)
veris(u"XYZ".isspace(), False)
veris(u"X".istitle(), True)
veris(u"x".istitle(), False)
veris(u"XYZ".isupper(), True)
veris(u"xyz".isupper(), False)
veris(u"xyz".startswith(u"x"), True)
veris(u"xyz".startswith(u"z"), False)
f = file(TESTFN, "w")
veris(f.closed, False)
f.close()
veris(f.closed, True)
import os
os.remove(TESTFN)
import operator
veris(operator.truth(0), False)
veris(operator.truth(1), True)
veris(operator.isCallable(0), False)
veris(operator.isCallable(len), True)
veris(operator.isNumberType(None), False)
veris(operator.isNumberType(0), True)
veris(operator.not_(1), False)
veris(operator.not_(0), True)
veris(operator.isSequenceType(0), False)
veris(operator.isSequenceType([]), True)
veris(operator.contains([], 1), False)
veris(operator.contains([1], 1), True)
veris(operator.isMappingType([]), False)
veris(operator.isMappingType({}), True)
veris(operator.lt(0, 0), False)
veris(operator.lt(0, 1), True)
import marshal
veris(marshal.loads(marshal.dumps(True)), True)
veris(marshal.loads(marshal.dumps(False)), False)
import pickle
veris(pickle.loads(pickle.dumps(True)), True)
veris(pickle.loads(pickle.dumps(False)), False)
import cPickle
veris(cPickle.loads(cPickle.dumps(True)), True)
veris(cPickle.loads(cPickle.dumps(False)), False)
veris(pickle.loads(cPickle.dumps(True)), True)
veris(pickle.loads(cPickle.dumps(False)), False)
veris(cPickle.loads(pickle.dumps(True)), True)
veris(cPickle.loads(pickle.dumps(False)), False)
if verbose:
print "All OK"

212
Objects/boolobject.c Normal file
View File

@ -0,0 +1,212 @@
/* Boolean type, a subtype of int */
#include "Python.h"
/* We need to define bool_print to override int_print */
static int
bool_print(PyBoolObject *self, FILE *fp, int flags)
{
if (flags & Py_PRINT_RAW) {
if (self->ob_ival == 0)
fputs("False", fp);
else
fputs("True", fp);
}
else {
if (self->ob_ival == 0)
fputs("False", fp);
else
fputs("True", fp);
}
return 0;
}
/* We define bool_repr to return "False" or "True" */
static PyObject *false_str = NULL;
static PyObject *true_str = NULL;
PyObject *
bool_repr(PyBoolObject *self)
{
PyObject *s;
if (self->ob_ival)
s = true_str ? true_str :
(true_str = PyString_InternFromString("True"));
else
s = false_str ? false_str :
(false_str = PyString_InternFromString("False"));
Py_XINCREF(s);
return s;
}
/* Function to return a bool from a C long */
PyObject *PyBool_FromLong(long ok)
{
PyObject *result;
if (ok)
result = Py_True;
else
result = Py_False;
Py_INCREF(result);
return result;
}
/* We define bool_new to always return either Py_True or Py_False */
PyObject *
bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"x", 0};
PyObject *x;
long ok;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:bool", kwlist, &x))
return NULL;
ok = PyObject_IsTrue(x);
if (ok < 0)
return NULL;
return PyBool_FromLong(ok);
}
/* Arithmetic operations redefined to return bool if both args are bool. */
static PyObject *
bool_and(PyObject *a, PyObject *b)
{
if (!PyBool_Check(a) || !PyBool_Check(b))
return PyInt_Type.tp_as_number->nb_and(a, b);
return PyBool_FromLong(
((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival);
}
static PyObject *
bool_or(PyObject *a, PyObject *b)
{
if (!PyBool_Check(a) || !PyBool_Check(b))
return PyInt_Type.tp_as_number->nb_or(a, b);
return PyBool_FromLong(
((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival);
}
static PyObject *
bool_xor(PyObject *a, PyObject *b)
{
if (!PyBool_Check(a) || !PyBool_Check(b))
return PyInt_Type.tp_as_number->nb_xor(a, b);
return PyBool_FromLong(
((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival);
}
/* Doc string */
static char bool_doc[] =
"bool(x) -> bool\n\
\n\
Returns True when the argument x is true, False otherwise.\n\
The builtins True and False are the only two instances of the class bool.\n\
The class bool is a subclass of the class int, and cannot be subclassed.";
/* Arithmetic methods -- only so we can override &, |, ^. */
static PyNumberMethods bool_as_number = {
0, /*nb_add*/
0, /*nb_subtract*/
0, /*nb_multiply*/
0, /*nb_divide*/
0, /*nb_remainder*/
0, /*nb_divmod*/
0, /*nb_power*/
0, /*nb_negative*/
0, /*nb_positive*/
0, /*nb_absolute*/
0, /*nb_nonzero*/
0, /*nb_invert*/
0, /*nb_lshift*/
0, /*nb_rshift*/
(binaryfunc)bool_and, /*nb_and*/
(binaryfunc)bool_xor, /*nb_xor*/
(binaryfunc)bool_or, /*nb_or*/
0, /*nb_coerce*/
0, /*nb_int*/
0, /*nb_long*/
0, /*nb_float*/
0, /*nb_oct*/
0, /*nb_hex*/
0, /*nb_inplace_add*/
0, /*nb_inplace_subtract*/
0, /*nb_inplace_multiply*/
0, /*nb_inplace_divide*/
0, /*nb_inplace_remainder*/
0, /*nb_inplace_power*/
0, /*nb_inplace_lshift*/
0, /*nb_inplace_rshift*/
0, /*nb_inplace_and*/
0, /*nb_inplace_xor*/
0, /*nb_inplace_or*/
0, /* nb_floor_divide */
0, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
};
/* The type object for bool. Note that this cannot be subclassed! */
PyTypeObject PyBool_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"bool",
sizeof(PyIntObject),
0,
0, /* tp_dealloc */
(printfunc)bool_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)bool_repr, /* tp_repr */
&bool_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
(reprfunc)bool_repr, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
bool_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PyInt_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
bool_new, /* tp_new */
};
/* The objects representing bool values False and True */
/* Named Zero for link-level compatibility */
PyIntObject _Py_ZeroStruct = {
PyObject_HEAD_INIT(&PyBool_Type)
0
};
PyIntObject _Py_TrueStruct = {
PyObject_HEAD_INIT(&PyBool_Type)
1
};