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 /* Arithmetic operations redefined to return bool if both args are bool. */
59 
60 static PyObject *
bool_and(PyObject * a,PyObject * b)61 bool_and(PyObject *a, PyObject *b)
62 {
63     if (!PyBool_Check(a) || !PyBool_Check(b))
64         return PyLong_Type.tp_as_number->nb_and(a, b);
65     return PyBool_FromLong((a == Py_True) & (b == Py_True));
66 }
67 
68 static PyObject *
bool_or(PyObject * a,PyObject * b)69 bool_or(PyObject *a, PyObject *b)
70 {
71     if (!PyBool_Check(a) || !PyBool_Check(b))
72         return PyLong_Type.tp_as_number->nb_or(a, b);
73     return PyBool_FromLong((a == Py_True) | (b == Py_True));
74 }
75 
76 static PyObject *
bool_xor(PyObject * a,PyObject * b)77 bool_xor(PyObject *a, PyObject *b)
78 {
79     if (!PyBool_Check(a) || !PyBool_Check(b))
80         return PyLong_Type.tp_as_number->nb_xor(a, b);
81     return PyBool_FromLong((a == Py_True) ^ (b == Py_True));
82 }
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 };
186