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