• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
bool_repr(PyObject * self)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 
PyBool_FromLong(long ok)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 *
bool_new(PyTypeObject * type,PyObject * args,PyObject * kwds)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 *
bool_vectorcall(PyObject * type,PyObject * const * args,size_t nargsf,PyObject * kwnames)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 *
bool_and(PyObject * a,PyObject * b)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 *
bool_or(PyObject * a,PyObject * b)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 *
bool_xor(PyObject * a,PyObject * b)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