1 /* Boolean type, a subtype of int */
2
3 #include "Python.h"
4 #include "longintrepr.h"
5
6 /* We define bool_repr to return "False" or "True" */
7
8 static PyObject *false_str = NULL;
9 static PyObject *true_str = NULL;
10
11 static PyObject *
bool_repr(PyObject * self)12 bool_repr(PyObject *self)
13 {
14 PyObject *s;
15
16 if (self == Py_True)
17 s = true_str ? true_str :
18 (true_str = PyUnicode_InternFromString("True"));
19 else
20 s = false_str ? false_str :
21 (false_str = PyUnicode_InternFromString("False"));
22 Py_XINCREF(s);
23 return s;
24 }
25
26 /* Function to return a bool from a C long */
27
PyBool_FromLong(long ok)28 PyObject *PyBool_FromLong(long ok)
29 {
30 PyObject *result;
31
32 if (ok)
33 result = Py_True;
34 else
35 result = Py_False;
36 Py_INCREF(result);
37 return result;
38 }
39
40 /* We define bool_new to always return either Py_True or Py_False */
41
42 static PyObject *
bool_new(PyTypeObject * type,PyObject * args,PyObject * kwds)43 bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
44 {
45 PyObject *x = Py_False;
46 long ok;
47
48 if (!_PyArg_NoKeywords("bool", kwds))
49 return NULL;
50 if (!PyArg_UnpackTuple(args, "bool", 0, 1, &x))
51 return NULL;
52 ok = PyObject_IsTrue(x);
53 if (ok < 0)
54 return NULL;
55 return PyBool_FromLong(ok);
56 }
57
58 static PyObject *
bool_vectorcall(PyObject * type,PyObject * const * args,size_t nargsf,PyObject * kwnames)59 bool_vectorcall(PyObject *type, PyObject * const*args,
60 size_t nargsf, PyObject *kwnames)
61 {
62 long ok = 0;
63 if (!_PyArg_NoKwnames("bool", kwnames)) {
64 return NULL;
65 }
66
67 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
68 if (!_PyArg_CheckPositional("bool", nargs, 0, 1)) {
69 return NULL;
70 }
71
72 assert(PyType_Check(type));
73 if (nargs) {
74 ok = PyObject_IsTrue(args[0]);
75 if (ok < 0) {
76 return NULL;
77 }
78 }
79 return PyBool_FromLong(ok);
80 }
81
82 /* Arithmetic operations redefined to return bool if both args are bool. */
83
84 static PyObject *
bool_and(PyObject * a,PyObject * b)85 bool_and(PyObject *a, PyObject *b)
86 {
87 if (!PyBool_Check(a) || !PyBool_Check(b))
88 return PyLong_Type.tp_as_number->nb_and(a, b);
89 return PyBool_FromLong((a == Py_True) & (b == Py_True));
90 }
91
92 static PyObject *
bool_or(PyObject * a,PyObject * b)93 bool_or(PyObject *a, PyObject *b)
94 {
95 if (!PyBool_Check(a) || !PyBool_Check(b))
96 return PyLong_Type.tp_as_number->nb_or(a, b);
97 return PyBool_FromLong((a == Py_True) | (b == Py_True));
98 }
99
100 static PyObject *
bool_xor(PyObject * a,PyObject * b)101 bool_xor(PyObject *a, PyObject *b)
102 {
103 if (!PyBool_Check(a) || !PyBool_Check(b))
104 return PyLong_Type.tp_as_number->nb_xor(a, b);
105 return PyBool_FromLong((a == Py_True) ^ (b == Py_True));
106 }
107
108 /* Doc string */
109
110 PyDoc_STRVAR(bool_doc,
111 "bool(x) -> bool\n\
112 \n\
113 Returns True when the argument x is true, False otherwise.\n\
114 The builtins True and False are the only two instances of the class bool.\n\
115 The class bool is a subclass of the class int, and cannot be subclassed.");
116
117 /* Arithmetic methods -- only so we can override &, |, ^. */
118
119 static PyNumberMethods bool_as_number = {
120 0, /* nb_add */
121 0, /* nb_subtract */
122 0, /* nb_multiply */
123 0, /* nb_remainder */
124 0, /* nb_divmod */
125 0, /* nb_power */
126 0, /* nb_negative */
127 0, /* nb_positive */
128 0, /* nb_absolute */
129 0, /* nb_bool */
130 0, /* nb_invert */
131 0, /* nb_lshift */
132 0, /* nb_rshift */
133 bool_and, /* nb_and */
134 bool_xor, /* nb_xor */
135 bool_or, /* nb_or */
136 0, /* nb_int */
137 0, /* nb_reserved */
138 0, /* nb_float */
139 0, /* nb_inplace_add */
140 0, /* nb_inplace_subtract */
141 0, /* nb_inplace_multiply */
142 0, /* nb_inplace_remainder */
143 0, /* nb_inplace_power */
144 0, /* nb_inplace_lshift */
145 0, /* nb_inplace_rshift */
146 0, /* nb_inplace_and */
147 0, /* nb_inplace_xor */
148 0, /* nb_inplace_or */
149 0, /* nb_floor_divide */
150 0, /* nb_true_divide */
151 0, /* nb_inplace_floor_divide */
152 0, /* nb_inplace_true_divide */
153 0, /* nb_index */
154 };
155
156 /* The type object for bool. Note that this cannot be subclassed! */
157
158 PyTypeObject PyBool_Type = {
159 PyVarObject_HEAD_INIT(&PyType_Type, 0)
160 "bool",
161 sizeof(struct _longobject),
162 0,
163 0, /* tp_dealloc */
164 0, /* tp_vectorcall_offset */
165 0, /* tp_getattr */
166 0, /* tp_setattr */
167 0, /* tp_as_async */
168 bool_repr, /* tp_repr */
169 &bool_as_number, /* tp_as_number */
170 0, /* tp_as_sequence */
171 0, /* tp_as_mapping */
172 0, /* tp_hash */
173 0, /* tp_call */
174 0, /* tp_str */
175 0, /* tp_getattro */
176 0, /* tp_setattro */
177 0, /* tp_as_buffer */
178 Py_TPFLAGS_DEFAULT, /* tp_flags */
179 bool_doc, /* tp_doc */
180 0, /* tp_traverse */
181 0, /* tp_clear */
182 0, /* tp_richcompare */
183 0, /* tp_weaklistoffset */
184 0, /* tp_iter */
185 0, /* tp_iternext */
186 0, /* tp_methods */
187 0, /* tp_members */
188 0, /* tp_getset */
189 &PyLong_Type, /* tp_base */
190 0, /* tp_dict */
191 0, /* tp_descr_get */
192 0, /* tp_descr_set */
193 0, /* tp_dictoffset */
194 0, /* tp_init */
195 0, /* tp_alloc */
196 bool_new, /* tp_new */
197 .tp_vectorcall = bool_vectorcall,
198 };
199
200 /* The objects representing bool values False and True */
201
202 struct _longobject _Py_FalseStruct = {
203 PyVarObject_HEAD_INIT(&PyBool_Type, 0)
204 { 0 }
205 };
206
207 struct _longobject _Py_TrueStruct = {
208 PyVarObject_HEAD_INIT(&PyBool_Type, 1)
209 { 1 }
210 };
211