LCOV - code coverage report
Current view: top level - Objects - boolobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 17 44 38.6 %
Date: 2023-03-20 08:15:36 Functions: 3 8 37.5 %
Branches: 9 38 23.7 %

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

Generated by: LCOV version 1.14