LCOV - code coverage report
Current view: top level - Objects - boolobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 40 45 88.9 %
Date: 2022-07-20 13:12:14 Functions: 7 8 87.5 %
Branches: 30 38 78.9 %

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

Generated by: LCOV version 1.14