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