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