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 : : /* We define bool_repr to return "False" or "True" */
8 : :
9 : : static PyObject *
10 : 38861 : bool_repr(PyObject *self)
11 : : {
12 [ + + ]: 38861 : PyObject *res = self == Py_True ? &_Py_ID(True) : &_Py_ID(False);
13 : 38861 : return Py_NewRef(res);
14 : : }
15 : :
16 : : /* Function to return a bool from a C long */
17 : :
18 : 116585684 : PyObject *PyBool_FromLong(long ok)
19 : : {
20 : : PyObject *result;
21 : :
22 [ + + ]: 116585684 : if (ok)
23 : 47231968 : result = Py_True;
24 : : else
25 : 69353716 : result = Py_False;
26 : 116585684 : Py_INCREF(result);
27 : 116585684 : return result;
28 : : }
29 : :
30 : : /* We define bool_new to always return either Py_True or Py_False */
31 : :
32 : : static PyObject *
33 : 5 : bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
34 : : {
35 : 5 : PyObject *x = Py_False;
36 : : long ok;
37 : :
38 [ - + - - ]: 5 : if (!_PyArg_NoKeywords("bool", kwds))
39 : 0 : return NULL;
40 [ - + ]: 5 : if (!PyArg_UnpackTuple(args, "bool", 0, 1, &x))
41 : 0 : return NULL;
42 : 5 : ok = PyObject_IsTrue(x);
43 [ - + ]: 5 : if (ok < 0)
44 : 0 : return NULL;
45 : 5 : return PyBool_FromLong(ok);
46 : : }
47 : :
48 : : static PyObject *
49 : 515499 : bool_vectorcall(PyObject *type, PyObject * const*args,
50 : : size_t nargsf, PyObject *kwnames)
51 : : {
52 : 515499 : long ok = 0;
53 [ + + + - ]: 515499 : if (!_PyArg_NoKwnames("bool", kwnames)) {
54 : 3 : return NULL;
55 : : }
56 : :
57 : 515496 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
58 [ + - + + : 515496 : if (!_PyArg_CheckPositional("bool", nargs, 0, 1)) {
+ - ]
59 : 1 : return NULL;
60 : : }
61 : :
62 : : assert(PyType_Check(type));
63 [ + + ]: 515495 : if (nargs) {
64 : 515494 : ok = PyObject_IsTrue(args[0]);
65 [ + + ]: 515494 : if (ok < 0) {
66 : 67 : return NULL;
67 : : }
68 : : }
69 : 515428 : return PyBool_FromLong(ok);
70 : : }
71 : :
72 : : /* Arithmetic operations redefined to return bool if both args are bool. */
73 : :
74 : : static PyObject *
75 : 24 : bool_and(PyObject *a, PyObject *b)
76 : : {
77 [ + + + + ]: 24 : if (!PyBool_Check(a) || !PyBool_Check(b))
78 : 18 : return PyLong_Type.tp_as_number->nb_and(a, b);
79 : 6 : return PyBool_FromLong((a == Py_True) & (b == Py_True));
80 : : }
81 : :
82 : : static PyObject *
83 : 164440 : bool_or(PyObject *a, PyObject *b)
84 : : {
85 [ + + + + ]: 164440 : if (!PyBool_Check(a) || !PyBool_Check(b))
86 : 163379 : return PyLong_Type.tp_as_number->nb_or(a, b);
87 : 1061 : return PyBool_FromLong((a == Py_True) | (b == Py_True));
88 : : }
89 : :
90 : : static PyObject *
91 : 689 : bool_xor(PyObject *a, PyObject *b)
92 : : {
93 [ + + + + ]: 689 : if (!PyBool_Check(a) || !PyBool_Check(b))
94 : 18 : return PyLong_Type.tp_as_number->nb_xor(a, b);
95 : 671 : 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
147 : 0 : bool_dealloc(PyObject* Py_UNUSED(ignore))
148 : : {
149 : 0 : _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 : : };
|