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