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