• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Boolean type, a subtype of int */
2 
3 #include "Python.h"
4 
5 /* We need to define bool_print to override int_print */
6 
7 static int
bool_print(PyBoolObject * self,FILE * fp,int flags)8 bool_print(PyBoolObject *self, FILE *fp, int flags)
9 {
10     Py_BEGIN_ALLOW_THREADS
11     fputs(self->ob_ival == 0 ? "False" : "True", fp);
12     Py_END_ALLOW_THREADS
13     return 0;
14 }
15 
16 /* We define bool_repr to return "False" or "True" */
17 
18 static PyObject *false_str = NULL;
19 static PyObject *true_str = NULL;
20 
21 static PyObject *
bool_repr(PyBoolObject * self)22 bool_repr(PyBoolObject *self)
23 {
24     PyObject *s;
25 
26     if (self->ob_ival)
27         s = true_str ? true_str :
28             (true_str = PyString_InternFromString("True"));
29     else
30         s = false_str ? false_str :
31             (false_str = PyString_InternFromString("False"));
32     Py_XINCREF(s);
33     return s;
34 }
35 
36 /* Function to return a bool from a C long */
37 
PyBool_FromLong(long ok)38 PyObject *PyBool_FromLong(long ok)
39 {
40     PyObject *result;
41 
42     if (ok)
43         result = Py_True;
44     else
45         result = Py_False;
46     Py_INCREF(result);
47     return result;
48 }
49 
50 /* We define bool_new to always return either Py_True or Py_False */
51 
52 static PyObject *
bool_new(PyTypeObject * type,PyObject * args,PyObject * kwds)53 bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
54 {
55     static char *kwlist[] = {"x", 0};
56     PyObject *x = Py_False;
57     long ok;
58 
59     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
60         return NULL;
61     ok = PyObject_IsTrue(x);
62     if (ok < 0)
63         return NULL;
64     return PyBool_FromLong(ok);
65 }
66 
67 /* Arithmetic operations redefined to return bool if both args are bool. */
68 
69 static PyObject *
bool_and(PyObject * a,PyObject * b)70 bool_and(PyObject *a, PyObject *b)
71 {
72     if (!PyBool_Check(a) || !PyBool_Check(b))
73         return PyInt_Type.tp_as_number->nb_and(a, b);
74     return PyBool_FromLong(
75         ((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival);
76 }
77 
78 static PyObject *
bool_or(PyObject * a,PyObject * b)79 bool_or(PyObject *a, PyObject *b)
80 {
81     if (!PyBool_Check(a) || !PyBool_Check(b))
82         return PyInt_Type.tp_as_number->nb_or(a, b);
83     return PyBool_FromLong(
84         ((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival);
85 }
86 
87 static PyObject *
bool_xor(PyObject * a,PyObject * b)88 bool_xor(PyObject *a, PyObject *b)
89 {
90     if (!PyBool_Check(a) || !PyBool_Check(b))
91         return PyInt_Type.tp_as_number->nb_xor(a, b);
92     return PyBool_FromLong(
93         ((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival);
94 }
95 
96 /* Doc string */
97 
98 PyDoc_STRVAR(bool_doc,
99 "bool(x) -> bool\n\
100 \n\
101 Returns True when the argument x is true, False otherwise.\n\
102 The builtins True and False are the only two instances of the class bool.\n\
103 The class bool is a subclass of the class int, and cannot be subclassed.");
104 
105 /* Arithmetic methods -- only so we can override &, |, ^. */
106 
107 static PyNumberMethods bool_as_number = {
108     0,                          /* nb_add */
109     0,                          /* nb_subtract */
110     0,                          /* nb_multiply */
111     0,                          /* nb_divide */
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_nonzero */
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_coerce */
126     0,                          /* nb_int */
127     0,                          /* nb_long */
128     0,                          /* nb_float */
129     0,                          /* nb_oct */
130     0,                          /* nb_hex */
131     0,                          /* nb_inplace_add */
132     0,                          /* nb_inplace_subtract */
133     0,                          /* nb_inplace_multiply */
134     0,                          /* nb_inplace_divide */
135     0,                          /* nb_inplace_remainder */
136     0,                          /* nb_inplace_power */
137     0,                          /* nb_inplace_lshift */
138     0,                          /* nb_inplace_rshift */
139     0,                          /* nb_inplace_and */
140     0,                          /* nb_inplace_xor */
141     0,                          /* nb_inplace_or */
142     0,                          /* nb_floor_divide */
143     0,                          /* nb_true_divide */
144     0,                          /* nb_inplace_floor_divide */
145     0,                          /* nb_inplace_true_divide */
146 };
147 
148 /* The type object for bool.  Note that this cannot be subclassed! */
149 
150 PyTypeObject PyBool_Type = {
151     PyVarObject_HEAD_INIT(&PyType_Type, 0)
152     "bool",
153     sizeof(PyIntObject),
154     0,
155     0,                                          /* tp_dealloc */
156     (printfunc)bool_print,                      /* tp_print */
157     0,                                          /* tp_getattr */
158     0,                                          /* tp_setattr */
159     0,                                          /* tp_compare */
160     (reprfunc)bool_repr,                        /* tp_repr */
161     &bool_as_number,                            /* tp_as_number */
162     0,                                          /* tp_as_sequence */
163     0,                                          /* tp_as_mapping */
164     0,                                          /* tp_hash */
165     0,                                          /* tp_call */
166     (reprfunc)bool_repr,                        /* tp_str */
167     0,                                          /* tp_getattro */
168     0,                                          /* tp_setattro */
169     0,                                          /* tp_as_buffer */
170     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
171     bool_doc,                                   /* tp_doc */
172     0,                                          /* tp_traverse */
173     0,                                          /* tp_clear */
174     0,                                          /* tp_richcompare */
175     0,                                          /* tp_weaklistoffset */
176     0,                                          /* tp_iter */
177     0,                                          /* tp_iternext */
178     0,                                          /* tp_methods */
179     0,                                          /* tp_members */
180     0,                                          /* tp_getset */
181     &PyInt_Type,                                /* tp_base */
182     0,                                          /* tp_dict */
183     0,                                          /* tp_descr_get */
184     0,                                          /* tp_descr_set */
185     0,                                          /* tp_dictoffset */
186     0,                                          /* tp_init */
187     0,                                          /* tp_alloc */
188     bool_new,                                   /* tp_new */
189 };
190 
191 /* The objects representing bool values False and True */
192 
193 /* Named Zero for link-level compatibility */
194 PyIntObject _Py_ZeroStruct = {
195     PyObject_HEAD_INIT(&PyBool_Type)
196     0
197 };
198 
199 PyIntObject _Py_TrueStruct = {
200     PyObject_HEAD_INIT(&PyBool_Type)
201     1
202 };
203