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