LCOV - code coverage report
Current view: top level - Objects - abstract.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 589 1454 40.5 %
Date: 2023-03-20 08:15:36 Functions: 84 131 64.1 %
Branches: 338 984 34.3 %

           Branch data     Line data    Source code
       1                 :            : /* Abstract Object Interface (many thanks to Jim Fulton) */
       2                 :            : 
       3                 :            : #include "Python.h"
       4                 :            : #include "pycore_abstract.h"      // _PyIndex_Check()
       5                 :            : #include "pycore_call.h"          // _PyObject_CallNoArgs()
       6                 :            : #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate()
       7                 :            : #include "pycore_object.h"        // _Py_CheckSlotResult()
       8                 :            : #include "pycore_pyerrors.h"      // _PyErr_Occurred()
       9                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
      10                 :            : #include "pycore_unionobject.h"   // _PyUnion_Check()
      11                 :            : #include <ctype.h>
      12                 :            : #include <stddef.h>               // offsetof()
      13                 :            : 
      14                 :            : 
      15                 :            : 
      16                 :            : /* Shorthands to return certain errors */
      17                 :            : 
      18                 :            : static PyObject *
      19                 :         88 : type_error(const char *msg, PyObject *obj)
      20                 :            : {
      21                 :         88 :     PyErr_Format(PyExc_TypeError, msg, Py_TYPE(obj)->tp_name);
      22                 :         88 :     return NULL;
      23                 :            : }
      24                 :            : 
      25                 :            : static PyObject *
      26                 :          0 : null_error(void)
      27                 :            : {
      28                 :          0 :     PyThreadState *tstate = _PyThreadState_GET();
      29         [ #  # ]:          0 :     if (!_PyErr_Occurred(tstate)) {
      30                 :          0 :         _PyErr_SetString(tstate, PyExc_SystemError,
      31                 :            :                          "null argument to internal routine");
      32                 :            :     }
      33                 :          0 :     return NULL;
      34                 :            : }
      35                 :            : 
      36                 :            : /* Operations on any object */
      37                 :            : 
      38                 :            : PyObject *
      39                 :         81 : PyObject_Type(PyObject *o)
      40                 :            : {
      41                 :            :     PyObject *v;
      42                 :            : 
      43         [ -  + ]:         81 :     if (o == NULL) {
      44                 :          0 :         return null_error();
      45                 :            :     }
      46                 :            : 
      47                 :         81 :     v = (PyObject *)Py_TYPE(o);
      48                 :         81 :     return Py_NewRef(v);
      49                 :            : }
      50                 :            : 
      51                 :            : Py_ssize_t
      52                 :      47322 : PyObject_Size(PyObject *o)
      53                 :            : {
      54         [ -  + ]:      47322 :     if (o == NULL) {
      55                 :          0 :         null_error();
      56                 :          0 :         return -1;
      57                 :            :     }
      58                 :            : 
      59                 :      47322 :     PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
      60   [ +  -  +  + ]:      47322 :     if (m && m->sq_length) {
      61                 :      46948 :         Py_ssize_t len = m->sq_length(o);
      62                 :            :         assert(_Py_CheckSlotResult(o, "__len__", len >= 0));
      63                 :      46948 :         return len;
      64                 :            :     }
      65                 :            : 
      66                 :        374 :     return PyMapping_Size(o);
      67                 :            : }
      68                 :            : 
      69                 :            : #undef PyObject_Length
      70                 :            : Py_ssize_t
      71                 :          0 : PyObject_Length(PyObject *o)
      72                 :            : {
      73                 :          0 :     return PyObject_Size(o);
      74                 :            : }
      75                 :            : #define PyObject_Length PyObject_Size
      76                 :            : 
      77                 :            : int
      78                 :      24012 : _PyObject_HasLen(PyObject *o) {
      79   [ +  +  +  + ]:      46238 :     return (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) ||
      80   [ +  +  +  + ]:      22226 :         (Py_TYPE(o)->tp_as_mapping && Py_TYPE(o)->tp_as_mapping->mp_length);
      81                 :            : }
      82                 :            : 
      83                 :            : /* The length hint function returns a non-negative value from o.__len__()
      84                 :            :    or o.__length_hint__(). If those methods aren't found the defaultvalue is
      85                 :            :    returned.  If one of the calls fails with an exception other than TypeError
      86                 :            :    this function returns -1.
      87                 :            : */
      88                 :            : 
      89                 :            : Py_ssize_t
      90                 :      23997 : PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
      91                 :            : {
      92                 :            :     PyObject *hint, *result;
      93                 :            :     Py_ssize_t res;
      94         [ +  + ]:      23997 :     if (_PyObject_HasLen(o)) {
      95                 :       1928 :         res = PyObject_Length(o);
      96         [ -  + ]:       1928 :         if (res < 0) {
      97                 :          0 :             PyThreadState *tstate = _PyThreadState_GET();
      98                 :            :             assert(_PyErr_Occurred(tstate));
      99         [ #  # ]:          0 :             if (!_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
     100                 :          0 :                 return -1;
     101                 :            :             }
     102                 :          0 :             _PyErr_Clear(tstate);
     103                 :            :         }
     104                 :            :         else {
     105                 :       1928 :             return res;
     106                 :            :         }
     107                 :            :     }
     108                 :      22069 :     hint = _PyObject_LookupSpecial(o, &_Py_ID(__length_hint__));
     109         [ +  + ]:      22069 :     if (hint == NULL) {
     110         [ -  + ]:      19031 :         if (PyErr_Occurred()) {
     111                 :          0 :             return -1;
     112                 :            :         }
     113                 :      19031 :         return defaultvalue;
     114                 :            :     }
     115                 :       3038 :     result = _PyObject_CallNoArgs(hint);
     116                 :       3038 :     Py_DECREF(hint);
     117         [ -  + ]:       3038 :     if (result == NULL) {
     118                 :          0 :         PyThreadState *tstate = _PyThreadState_GET();
     119         [ #  # ]:          0 :         if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
     120                 :          0 :             _PyErr_Clear(tstate);
     121                 :          0 :             return defaultvalue;
     122                 :            :         }
     123                 :          0 :         return -1;
     124                 :            :     }
     125         [ -  + ]:       3038 :     else if (result == Py_NotImplemented) {
     126                 :          0 :         Py_DECREF(result);
     127                 :          0 :         return defaultvalue;
     128                 :            :     }
     129         [ -  + ]:       3038 :     if (!PyLong_Check(result)) {
     130                 :          0 :         PyErr_Format(PyExc_TypeError, "__length_hint__ must be an integer, not %.100s",
     131                 :          0 :             Py_TYPE(result)->tp_name);
     132                 :          0 :         Py_DECREF(result);
     133                 :          0 :         return -1;
     134                 :            :     }
     135                 :       3038 :     res = PyLong_AsSsize_t(result);
     136                 :       3038 :     Py_DECREF(result);
     137   [ -  +  -  - ]:       3038 :     if (res < 0 && PyErr_Occurred()) {
     138                 :          0 :         return -1;
     139                 :            :     }
     140         [ -  + ]:       3038 :     if (res < 0) {
     141                 :          0 :         PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0");
     142                 :          0 :         return -1;
     143                 :            :     }
     144                 :       3038 :     return res;
     145                 :            : }
     146                 :            : 
     147                 :            : PyObject *
     148                 :     200351 : PyObject_GetItem(PyObject *o, PyObject *key)
     149                 :            : {
     150   [ +  -  -  + ]:     200351 :     if (o == NULL || key == NULL) {
     151                 :          0 :         return null_error();
     152                 :            :     }
     153                 :            : 
     154                 :     200351 :     PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping;
     155   [ +  +  +  + ]:     200351 :     if (m && m->mp_subscript) {
     156                 :     200266 :         PyObject *item = m->mp_subscript(o, key);
     157                 :            :         assert(_Py_CheckSlotResult(o, "__getitem__", item != NULL));
     158                 :     200266 :         return item;
     159                 :            :     }
     160                 :            : 
     161                 :         85 :     PySequenceMethods *ms = Py_TYPE(o)->tp_as_sequence;
     162   [ +  +  -  + ]:         85 :     if (ms && ms->sq_item) {
     163         [ #  # ]:          0 :         if (_PyIndex_Check(key)) {
     164                 :            :             Py_ssize_t key_value;
     165                 :          0 :             key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
     166   [ #  #  #  # ]:          0 :             if (key_value == -1 && PyErr_Occurred())
     167                 :          0 :                 return NULL;
     168                 :          0 :             return PySequence_GetItem(o, key_value);
     169                 :            :         }
     170                 :            :         else {
     171                 :          0 :             return type_error("sequence index must "
     172                 :            :                               "be integer, not '%.200s'", key);
     173                 :            :         }
     174                 :            :     }
     175                 :            : 
     176         [ +  - ]:         85 :     if (PyType_Check(o)) {
     177                 :            :         PyObject *meth, *result;
     178                 :            : 
     179                 :            :         // Special case type[int], but disallow other types so str[int] fails
     180         [ +  + ]:         85 :         if ((PyTypeObject*)o == &PyType_Type) {
     181                 :          3 :             return Py_GenericAlias(o, key);
     182                 :            :         }
     183                 :            : 
     184         [ -  + ]:         82 :         if (_PyObject_LookupAttr(o, &_Py_ID(__class_getitem__), &meth) < 0) {
     185                 :          0 :             return NULL;
     186                 :            :         }
     187   [ +  -  +  - ]:         82 :         if (meth && meth != Py_None) {
     188                 :         82 :             result = PyObject_CallOneArg(meth, key);
     189                 :         82 :             Py_DECREF(meth);
     190                 :         82 :             return result;
     191                 :            :         }
     192                 :          0 :         Py_XDECREF(meth);
     193                 :          0 :         PyErr_Format(PyExc_TypeError, "type '%.200s' is not subscriptable",
     194                 :            :                      ((PyTypeObject *)o)->tp_name);
     195                 :          0 :         return NULL;
     196                 :            :     }
     197                 :            : 
     198                 :          0 :     return type_error("'%.200s' object is not subscriptable", o);
     199                 :            : }
     200                 :            : 
     201                 :            : int
     202                 :      10336 : PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
     203                 :            : {
     204   [ +  -  +  -  :      10336 :     if (o == NULL || key == NULL || value == NULL) {
                   -  + ]
     205                 :          0 :         null_error();
     206                 :          0 :         return -1;
     207                 :            :     }
     208                 :            : 
     209                 :      10336 :     PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping;
     210   [ +  -  +  - ]:      10336 :     if (m && m->mp_ass_subscript) {
     211                 :      10336 :         int res = m->mp_ass_subscript(o, key, value);
     212                 :            :         assert(_Py_CheckSlotResult(o, "__setitem__", res >= 0));
     213                 :      10336 :         return res;
     214                 :            :     }
     215                 :            : 
     216         [ #  # ]:          0 :     if (Py_TYPE(o)->tp_as_sequence) {
     217         [ #  # ]:          0 :         if (_PyIndex_Check(key)) {
     218                 :            :             Py_ssize_t key_value;
     219                 :          0 :             key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
     220   [ #  #  #  # ]:          0 :             if (key_value == -1 && PyErr_Occurred())
     221                 :          0 :                 return -1;
     222                 :          0 :             return PySequence_SetItem(o, key_value, value);
     223                 :            :         }
     224         [ #  # ]:          0 :         else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) {
     225                 :          0 :             type_error("sequence index must be "
     226                 :            :                        "integer, not '%.200s'", key);
     227                 :          0 :             return -1;
     228                 :            :         }
     229                 :            :     }
     230                 :            : 
     231                 :          0 :     type_error("'%.200s' object does not support item assignment", o);
     232                 :          0 :     return -1;
     233                 :            : }
     234                 :            : 
     235                 :            : int
     236                 :       1753 : PyObject_DelItem(PyObject *o, PyObject *key)
     237                 :            : {
     238   [ +  -  -  + ]:       1753 :     if (o == NULL || key == NULL) {
     239                 :          0 :         null_error();
     240                 :          0 :         return -1;
     241                 :            :     }
     242                 :            : 
     243                 :       1753 :     PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping;
     244   [ +  -  +  - ]:       1753 :     if (m && m->mp_ass_subscript) {
     245                 :       1753 :         int res = m->mp_ass_subscript(o, key, (PyObject*)NULL);
     246                 :            :         assert(_Py_CheckSlotResult(o, "__delitem__", res >= 0));
     247                 :       1753 :         return res;
     248                 :            :     }
     249                 :            : 
     250         [ #  # ]:          0 :     if (Py_TYPE(o)->tp_as_sequence) {
     251         [ #  # ]:          0 :         if (_PyIndex_Check(key)) {
     252                 :            :             Py_ssize_t key_value;
     253                 :          0 :             key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
     254   [ #  #  #  # ]:          0 :             if (key_value == -1 && PyErr_Occurred())
     255                 :          0 :                 return -1;
     256                 :          0 :             return PySequence_DelItem(o, key_value);
     257                 :            :         }
     258         [ #  # ]:          0 :         else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) {
     259                 :          0 :             type_error("sequence index must be "
     260                 :            :                        "integer, not '%.200s'", key);
     261                 :          0 :             return -1;
     262                 :            :         }
     263                 :            :     }
     264                 :            : 
     265                 :          0 :     type_error("'%.200s' object does not support item deletion", o);
     266                 :          0 :     return -1;
     267                 :            : }
     268                 :            : 
     269                 :            : int
     270                 :          0 : PyObject_DelItemString(PyObject *o, const char *key)
     271                 :            : {
     272                 :            :     PyObject *okey;
     273                 :            :     int ret;
     274                 :            : 
     275   [ #  #  #  # ]:          0 :     if (o == NULL || key == NULL) {
     276                 :          0 :         null_error();
     277                 :          0 :         return -1;
     278                 :            :     }
     279                 :          0 :     okey = PyUnicode_FromString(key);
     280         [ #  # ]:          0 :     if (okey == NULL)
     281                 :          0 :         return -1;
     282                 :          0 :     ret = PyObject_DelItem(o, okey);
     283                 :          0 :     Py_DECREF(okey);
     284                 :          0 :     return ret;
     285                 :            : }
     286                 :            : 
     287                 :            : 
     288                 :            : /* Return 1 if the getbuffer function is available, otherwise return 0. */
     289                 :            : int
     290                 :       2795 : PyObject_CheckBuffer(PyObject *obj)
     291                 :            : {
     292                 :       2795 :     PyBufferProcs *tp_as_buffer = Py_TYPE(obj)->tp_as_buffer;
     293   [ +  +  +  - ]:       2795 :     return (tp_as_buffer != NULL && tp_as_buffer->bf_getbuffer != NULL);
     294                 :            : }
     295                 :            : 
     296                 :            : 
     297                 :            : /* We release the buffer right after use of this function which could
     298                 :            :    cause issues later on.  Don't use these functions in new code.
     299                 :            :  */
     300                 :            : int
     301                 :          0 : PyObject_CheckReadBuffer(PyObject *obj)
     302                 :            : {
     303                 :          0 :     PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer;
     304                 :            :     Py_buffer view;
     305                 :            : 
     306         [ #  # ]:          0 :     if (pb == NULL ||
     307         [ #  # ]:          0 :         pb->bf_getbuffer == NULL)
     308                 :          0 :         return 0;
     309         [ #  # ]:          0 :     if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) {
     310                 :          0 :         PyErr_Clear();
     311                 :          0 :         return 0;
     312                 :            :     }
     313                 :          0 :     PyBuffer_Release(&view);
     314                 :          0 :     return 1;
     315                 :            : }
     316                 :            : 
     317                 :            : static int
     318                 :          0 : as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
     319                 :            : {
     320                 :            :     Py_buffer view;
     321                 :            : 
     322   [ #  #  #  #  :          0 :     if (obj == NULL || buffer == NULL || buffer_len == NULL) {
                   #  # ]
     323                 :          0 :         null_error();
     324                 :          0 :         return -1;
     325                 :            :     }
     326         [ #  # ]:          0 :     if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)
     327                 :          0 :         return -1;
     328                 :            : 
     329                 :          0 :     *buffer = view.buf;
     330                 :          0 :     *buffer_len = view.len;
     331                 :          0 :     PyBuffer_Release(&view);
     332                 :          0 :     return 0;
     333                 :            : }
     334                 :            : 
     335                 :            : int
     336                 :          0 : PyObject_AsCharBuffer(PyObject *obj,
     337                 :            :                       const char **buffer,
     338                 :            :                       Py_ssize_t *buffer_len)
     339                 :            : {
     340                 :          0 :     return as_read_buffer(obj, (const void **)buffer, buffer_len);
     341                 :            : }
     342                 :            : 
     343                 :          0 : int PyObject_AsReadBuffer(PyObject *obj,
     344                 :            :                           const void **buffer,
     345                 :            :                           Py_ssize_t *buffer_len)
     346                 :            : {
     347                 :          0 :     return as_read_buffer(obj, buffer, buffer_len);
     348                 :            : }
     349                 :            : 
     350                 :          0 : int PyObject_AsWriteBuffer(PyObject *obj,
     351                 :            :                            void **buffer,
     352                 :            :                            Py_ssize_t *buffer_len)
     353                 :            : {
     354                 :            :     PyBufferProcs *pb;
     355                 :            :     Py_buffer view;
     356                 :            : 
     357   [ #  #  #  #  :          0 :     if (obj == NULL || buffer == NULL || buffer_len == NULL) {
                   #  # ]
     358                 :          0 :         null_error();
     359                 :          0 :         return -1;
     360                 :            :     }
     361                 :          0 :     pb = Py_TYPE(obj)->tp_as_buffer;
     362         [ #  # ]:          0 :     if (pb == NULL ||
     363   [ #  #  #  # ]:          0 :         pb->bf_getbuffer == NULL ||
     364                 :          0 :         ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) {
     365                 :          0 :         PyErr_SetString(PyExc_TypeError,
     366                 :            :                         "expected a writable bytes-like object");
     367                 :          0 :         return -1;
     368                 :            :     }
     369                 :            : 
     370                 :          0 :     *buffer = view.buf;
     371                 :          0 :     *buffer_len = view.len;
     372                 :          0 :     PyBuffer_Release(&view);
     373                 :          0 :     return 0;
     374                 :            : }
     375                 :            : 
     376                 :            : /* Buffer C-API for Python 3.0 */
     377                 :            : 
     378                 :            : int
     379                 :      24304 : PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
     380                 :            : {
     381                 :      24304 :     PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer;
     382                 :            : 
     383   [ +  -  -  + ]:      24304 :     if (pb == NULL || pb->bf_getbuffer == NULL) {
     384                 :          0 :         PyErr_Format(PyExc_TypeError,
     385                 :            :                      "a bytes-like object is required, not '%.100s'",
     386                 :          0 :                      Py_TYPE(obj)->tp_name);
     387                 :          0 :         return -1;
     388                 :            :     }
     389                 :      24304 :     int res = (*pb->bf_getbuffer)(obj, view, flags);
     390                 :            :     assert(_Py_CheckSlotResult(obj, "getbuffer", res >= 0));
     391                 :      24304 :     return res;
     392                 :            : }
     393                 :            : 
     394                 :            : static int
     395                 :          0 : _IsFortranContiguous(const Py_buffer *view)
     396                 :            : {
     397                 :            :     Py_ssize_t sd, dim;
     398                 :            :     int i;
     399                 :            : 
     400                 :            :     /* 1) len = product(shape) * itemsize
     401                 :            :        2) itemsize > 0
     402                 :            :        3) len = 0 <==> exists i: shape[i] = 0 */
     403         [ #  # ]:          0 :     if (view->len == 0) return 1;
     404         [ #  # ]:          0 :     if (view->strides == NULL) {  /* C-contiguous by definition */
     405                 :            :         /* Trivially F-contiguous */
     406         [ #  # ]:          0 :         if (view->ndim <= 1) return 1;
     407                 :            : 
     408                 :            :         /* ndim > 1 implies shape != NULL */
     409                 :            :         assert(view->shape != NULL);
     410                 :            : 
     411                 :            :         /* Effectively 1-d */
     412                 :          0 :         sd = 0;
     413         [ #  # ]:          0 :         for (i=0; i<view->ndim; i++) {
     414         [ #  # ]:          0 :             if (view->shape[i] > 1) sd += 1;
     415                 :            :         }
     416                 :          0 :         return sd <= 1;
     417                 :            :     }
     418                 :            : 
     419                 :            :     /* strides != NULL implies both of these */
     420                 :            :     assert(view->ndim > 0);
     421                 :            :     assert(view->shape != NULL);
     422                 :            : 
     423                 :          0 :     sd = view->itemsize;
     424         [ #  # ]:          0 :     for (i=0; i<view->ndim; i++) {
     425                 :          0 :         dim = view->shape[i];
     426   [ #  #  #  # ]:          0 :         if (dim > 1 && view->strides[i] != sd) {
     427                 :          0 :             return 0;
     428                 :            :         }
     429                 :          0 :         sd *= dim;
     430                 :            :     }
     431                 :          0 :     return 1;
     432                 :            : }
     433                 :            : 
     434                 :            : static int
     435                 :      10846 : _IsCContiguous(const Py_buffer *view)
     436                 :            : {
     437                 :            :     Py_ssize_t sd, dim;
     438                 :            :     int i;
     439                 :            : 
     440                 :            :     /* 1) len = product(shape) * itemsize
     441                 :            :        2) itemsize > 0
     442                 :            :        3) len = 0 <==> exists i: shape[i] = 0 */
     443         [ +  + ]:      10846 :     if (view->len == 0) return 1;
     444         [ +  + ]:      10214 :     if (view->strides == NULL) return 1; /* C-contiguous by definition */
     445                 :            : 
     446                 :            :     /* strides != NULL implies both of these */
     447                 :            :     assert(view->ndim > 0);
     448                 :            :     assert(view->shape != NULL);
     449                 :            : 
     450                 :        164 :     sd = view->itemsize;
     451         [ +  + ]:        328 :     for (i=view->ndim-1; i>=0; i--) {
     452                 :        164 :         dim = view->shape[i];
     453   [ +  +  -  + ]:        164 :         if (dim > 1 && view->strides[i] != sd) {
     454                 :          0 :             return 0;
     455                 :            :         }
     456                 :        164 :         sd *= dim;
     457                 :            :     }
     458                 :        164 :     return 1;
     459                 :            : }
     460                 :            : 
     461                 :            : int
     462                 :      10846 : PyBuffer_IsContiguous(const Py_buffer *view, char order)
     463                 :            : {
     464                 :            : 
     465         [ -  + ]:      10846 :     if (view->suboffsets != NULL) return 0;
     466                 :            : 
     467         [ +  - ]:      10846 :     if (order == 'C')
     468                 :      10846 :         return _IsCContiguous(view);
     469         [ #  # ]:          0 :     else if (order == 'F')
     470                 :          0 :         return _IsFortranContiguous(view);
     471         [ #  # ]:          0 :     else if (order == 'A')
     472   [ #  #  #  # ]:          0 :         return (_IsCContiguous(view) || _IsFortranContiguous(view));
     473                 :          0 :     return 0;
     474                 :            : }
     475                 :            : 
     476                 :            : 
     477                 :            : void*
     478                 :          0 : PyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices)
     479                 :            : {
     480                 :            :     char* pointer;
     481                 :            :     int i;
     482                 :          0 :     pointer = (char *)view->buf;
     483         [ #  # ]:          0 :     for (i = 0; i < view->ndim; i++) {
     484                 :          0 :         pointer += view->strides[i]*indices[i];
     485   [ #  #  #  # ]:          0 :         if ((view->suboffsets != NULL) && (view->suboffsets[i] >= 0)) {
     486                 :          0 :             pointer = *((char**)pointer) + view->suboffsets[i];
     487                 :            :         }
     488                 :            :     }
     489                 :          0 :     return (void*)pointer;
     490                 :            : }
     491                 :            : 
     492                 :            : 
     493                 :            : void
     494                 :          0 : _Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
     495                 :            : {
     496                 :            :     int k;
     497                 :            : 
     498         [ #  # ]:          0 :     for (k=0; k<nd; k++) {
     499         [ #  # ]:          0 :         if (index[k] < shape[k]-1) {
     500                 :          0 :             index[k]++;
     501                 :          0 :             break;
     502                 :            :         }
     503                 :            :         else {
     504                 :          0 :             index[k] = 0;
     505                 :            :         }
     506                 :            :     }
     507                 :          0 : }
     508                 :            : 
     509                 :            : void
     510                 :          0 : _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
     511                 :            : {
     512                 :            :     int k;
     513                 :            : 
     514         [ #  # ]:          0 :     for (k=nd-1; k>=0; k--) {
     515         [ #  # ]:          0 :         if (index[k] < shape[k]-1) {
     516                 :          0 :             index[k]++;
     517                 :          0 :             break;
     518                 :            :         }
     519                 :            :         else {
     520                 :          0 :             index[k] = 0;
     521                 :            :         }
     522                 :            :     }
     523                 :          0 : }
     524                 :            : 
     525                 :            : Py_ssize_t
     526                 :          0 : PyBuffer_SizeFromFormat(const char *format)
     527                 :            : {
     528                 :          0 :     PyObject *calcsize = NULL;
     529                 :          0 :     PyObject *res = NULL;
     530                 :          0 :     PyObject *fmt = NULL;
     531                 :          0 :     Py_ssize_t itemsize = -1;
     532                 :            : 
     533                 :          0 :     calcsize = _PyImport_GetModuleAttrString("struct", "calcsize");
     534         [ #  # ]:          0 :     if (calcsize == NULL) {
     535                 :          0 :         goto done;
     536                 :            :     }
     537                 :            : 
     538                 :          0 :     fmt = PyUnicode_FromString(format);
     539         [ #  # ]:          0 :     if (fmt == NULL) {
     540                 :          0 :         goto done;
     541                 :            :     }
     542                 :            : 
     543                 :          0 :     res = PyObject_CallFunctionObjArgs(calcsize, fmt, NULL);
     544         [ #  # ]:          0 :     if (res == NULL) {
     545                 :          0 :         goto done;
     546                 :            :     }
     547                 :            : 
     548                 :          0 :     itemsize = PyLong_AsSsize_t(res);
     549         [ #  # ]:          0 :     if (itemsize < 0) {
     550                 :          0 :         goto done;
     551                 :            :     }
     552                 :            : 
     553                 :          0 : done:
     554                 :          0 :     Py_XDECREF(calcsize);
     555                 :          0 :     Py_XDECREF(fmt);
     556                 :          0 :     Py_XDECREF(res);
     557                 :          0 :     return itemsize;
     558                 :            : }
     559                 :            : 
     560                 :            : int
     561                 :          0 : PyBuffer_FromContiguous(const Py_buffer *view, const void *buf, Py_ssize_t len, char fort)
     562                 :            : {
     563                 :            :     int k;
     564                 :            :     void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
     565                 :            :     Py_ssize_t *indices, elements;
     566                 :            :     char *ptr;
     567                 :            :     const char *src;
     568                 :            : 
     569         [ #  # ]:          0 :     if (len > view->len) {
     570                 :          0 :         len = view->len;
     571                 :            :     }
     572                 :            : 
     573         [ #  # ]:          0 :     if (PyBuffer_IsContiguous(view, fort)) {
     574                 :            :         /* simplest copy is all that is needed */
     575                 :          0 :         memcpy(view->buf, buf, len);
     576                 :          0 :         return 0;
     577                 :            :     }
     578                 :            : 
     579                 :            :     /* Otherwise a more elaborate scheme is needed */
     580                 :            : 
     581                 :            :     /* view->ndim <= 64 */
     582                 :          0 :     indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
     583         [ #  # ]:          0 :     if (indices == NULL) {
     584                 :          0 :         PyErr_NoMemory();
     585                 :          0 :         return -1;
     586                 :            :     }
     587         [ #  # ]:          0 :     for (k=0; k<view->ndim;k++) {
     588                 :          0 :         indices[k] = 0;
     589                 :            :     }
     590                 :            : 
     591         [ #  # ]:          0 :     if (fort == 'F') {
     592                 :          0 :         addone = _Py_add_one_to_index_F;
     593                 :            :     }
     594                 :            :     else {
     595                 :          0 :         addone = _Py_add_one_to_index_C;
     596                 :            :     }
     597                 :          0 :     src = buf;
     598                 :            :     /* XXX : This is not going to be the fastest code in the world
     599                 :            :              several optimizations are possible.
     600                 :            :      */
     601                 :          0 :     elements = len / view->itemsize;
     602         [ #  # ]:          0 :     while (elements--) {
     603                 :          0 :         ptr = PyBuffer_GetPointer(view, indices);
     604                 :          0 :         memcpy(ptr, src, view->itemsize);
     605                 :          0 :         src += view->itemsize;
     606                 :          0 :         addone(view->ndim, indices, view->shape);
     607                 :            :     }
     608                 :            : 
     609                 :          0 :     PyMem_Free(indices);
     610                 :          0 :     return 0;
     611                 :            : }
     612                 :            : 
     613                 :          0 : int PyObject_CopyData(PyObject *dest, PyObject *src)
     614                 :            : {
     615                 :            :     Py_buffer view_dest, view_src;
     616                 :            :     int k;
     617                 :            :     Py_ssize_t *indices, elements;
     618                 :            :     char *dptr, *sptr;
     619                 :            : 
     620   [ #  #  #  # ]:          0 :     if (!PyObject_CheckBuffer(dest) ||
     621                 :          0 :         !PyObject_CheckBuffer(src)) {
     622                 :          0 :         PyErr_SetString(PyExc_TypeError,
     623                 :            :                         "both destination and source must be "\
     624                 :            :                         "bytes-like objects");
     625                 :          0 :         return -1;
     626                 :            :     }
     627                 :            : 
     628         [ #  # ]:          0 :     if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
     629         [ #  # ]:          0 :     if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
     630                 :          0 :         PyBuffer_Release(&view_dest);
     631                 :          0 :         return -1;
     632                 :            :     }
     633                 :            : 
     634         [ #  # ]:          0 :     if (view_dest.len < view_src.len) {
     635                 :          0 :         PyErr_SetString(PyExc_BufferError,
     636                 :            :                         "destination is too small to receive data from source");
     637                 :          0 :         PyBuffer_Release(&view_dest);
     638                 :          0 :         PyBuffer_Release(&view_src);
     639                 :          0 :         return -1;
     640                 :            :     }
     641                 :            : 
     642   [ #  #  #  # ]:          0 :     if ((PyBuffer_IsContiguous(&view_dest, 'C') &&
     643         [ #  # ]:          0 :          PyBuffer_IsContiguous(&view_src, 'C')) ||
     644         [ #  # ]:          0 :         (PyBuffer_IsContiguous(&view_dest, 'F') &&
     645                 :          0 :          PyBuffer_IsContiguous(&view_src, 'F'))) {
     646                 :            :         /* simplest copy is all that is needed */
     647                 :          0 :         memcpy(view_dest.buf, view_src.buf, view_src.len);
     648                 :          0 :         PyBuffer_Release(&view_dest);
     649                 :          0 :         PyBuffer_Release(&view_src);
     650                 :          0 :         return 0;
     651                 :            :     }
     652                 :            : 
     653                 :            :     /* Otherwise a more elaborate copy scheme is needed */
     654                 :            : 
     655                 :            :     /* XXX(nnorwitz): need to check for overflow! */
     656                 :          0 :     indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
     657         [ #  # ]:          0 :     if (indices == NULL) {
     658                 :          0 :         PyErr_NoMemory();
     659                 :          0 :         PyBuffer_Release(&view_dest);
     660                 :          0 :         PyBuffer_Release(&view_src);
     661                 :          0 :         return -1;
     662                 :            :     }
     663         [ #  # ]:          0 :     for (k=0; k<view_src.ndim;k++) {
     664                 :          0 :         indices[k] = 0;
     665                 :            :     }
     666                 :          0 :     elements = 1;
     667         [ #  # ]:          0 :     for (k=0; k<view_src.ndim; k++) {
     668                 :            :         /* XXX(nnorwitz): can this overflow? */
     669                 :          0 :         elements *= view_src.shape[k];
     670                 :            :     }
     671         [ #  # ]:          0 :     while (elements--) {
     672                 :          0 :         _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape);
     673                 :          0 :         dptr = PyBuffer_GetPointer(&view_dest, indices);
     674                 :          0 :         sptr = PyBuffer_GetPointer(&view_src, indices);
     675                 :          0 :         memcpy(dptr, sptr, view_src.itemsize);
     676                 :            :     }
     677                 :          0 :     PyMem_Free(indices);
     678                 :          0 :     PyBuffer_Release(&view_dest);
     679                 :          0 :     PyBuffer_Release(&view_src);
     680                 :          0 :     return 0;
     681                 :            : }
     682                 :            : 
     683                 :            : void
     684                 :          0 : PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
     685                 :            :                                Py_ssize_t *strides, int itemsize,
     686                 :            :                                char fort)
     687                 :            : {
     688                 :            :     int k;
     689                 :            :     Py_ssize_t sd;
     690                 :            : 
     691                 :          0 :     sd = itemsize;
     692         [ #  # ]:          0 :     if (fort == 'F') {
     693         [ #  # ]:          0 :         for (k=0; k<nd; k++) {
     694                 :          0 :             strides[k] = sd;
     695                 :          0 :             sd *= shape[k];
     696                 :            :         }
     697                 :            :     }
     698                 :            :     else {
     699         [ #  # ]:          0 :         for (k=nd-1; k>=0; k--) {
     700                 :          0 :             strides[k] = sd;
     701                 :          0 :             sd *= shape[k];
     702                 :            :         }
     703                 :            :     }
     704                 :          0 :     return;
     705                 :            : }
     706                 :            : 
     707                 :            : int
     708                 :      23918 : PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
     709                 :            :                   int readonly, int flags)
     710                 :            : {
     711         [ -  + ]:      23918 :     if (view == NULL) {
     712                 :          0 :         PyErr_SetString(PyExc_BufferError,
     713                 :            :                         "PyBuffer_FillInfo: view==NULL argument is obsolete");
     714                 :          0 :         return -1;
     715                 :            :     }
     716                 :            : 
     717   [ +  +  -  + ]:      23918 :     if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) &&
     718                 :            :         (readonly == 1)) {
     719                 :          0 :         PyErr_SetString(PyExc_BufferError,
     720                 :            :                         "Object is not writable.");
     721                 :          0 :         return -1;
     722                 :            :     }
     723                 :            : 
     724                 :      23918 :     view->obj = Py_XNewRef(obj);
     725                 :      23918 :     view->buf = buf;
     726                 :      23918 :     view->len = len;
     727                 :      23918 :     view->readonly = readonly;
     728                 :      23918 :     view->itemsize = 1;
     729                 :      23918 :     view->format = NULL;
     730         [ +  + ]:      23918 :     if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
     731                 :        554 :         view->format = "B";
     732                 :      23918 :     view->ndim = 1;
     733                 :      23918 :     view->shape = NULL;
     734         [ +  + ]:      23918 :     if ((flags & PyBUF_ND) == PyBUF_ND)
     735                 :       5406 :         view->shape = &(view->len);
     736                 :      23918 :     view->strides = NULL;
     737         [ +  + ]:      23918 :     if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
     738                 :        554 :         view->strides = &(view->itemsize);
     739                 :      23918 :     view->suboffsets = NULL;
     740                 :      23918 :     view->internal = NULL;
     741                 :      23918 :     return 0;
     742                 :            : }
     743                 :            : 
     744                 :            : void
     745                 :      38500 : PyBuffer_Release(Py_buffer *view)
     746                 :            : {
     747                 :      38500 :     PyObject *obj = view->obj;
     748                 :            :     PyBufferProcs *pb;
     749         [ +  + ]:      38500 :     if (obj == NULL)
     750                 :      14196 :         return;
     751                 :      24304 :     pb = Py_TYPE(obj)->tp_as_buffer;
     752   [ +  -  +  + ]:      24304 :     if (pb && pb->bf_releasebuffer) {
     753                 :       5403 :         pb->bf_releasebuffer(obj, view);
     754                 :            :     }
     755                 :      24304 :     view->obj = NULL;
     756                 :      24304 :     Py_DECREF(obj);
     757                 :            : }
     758                 :            : 
     759                 :            : PyObject *
     760                 :     304040 : PyObject_Format(PyObject *obj, PyObject *format_spec)
     761                 :            : {
     762                 :            :     PyObject *meth;
     763                 :     304040 :     PyObject *empty = NULL;
     764                 :     304040 :     PyObject *result = NULL;
     765                 :            : 
     766   [ +  +  -  + ]:     304040 :     if (format_spec != NULL && !PyUnicode_Check(format_spec)) {
     767                 :          0 :         PyErr_Format(PyExc_SystemError,
     768                 :            :                      "Format specifier must be a string, not %.200s",
     769                 :          0 :                      Py_TYPE(format_spec)->tp_name);
     770                 :          0 :         return NULL;
     771                 :            :     }
     772                 :            : 
     773                 :            :     /* Fast path for common types. */
     774   [ +  +  -  + ]:     304040 :     if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) {
     775         [ -  + ]:      35767 :         if (PyUnicode_CheckExact(obj)) {
     776                 :          0 :             return Py_NewRef(obj);
     777                 :            :         }
     778         [ +  + ]:      35767 :         if (PyLong_CheckExact(obj)) {
     779                 :      32635 :             return PyObject_Str(obj);
     780                 :            :         }
     781                 :            :     }
     782                 :            : 
     783                 :            :     /* If no format_spec is provided, use an empty string */
     784         [ +  + ]:     271405 :     if (format_spec == NULL) {
     785                 :       3132 :         empty = PyUnicode_New(0, 0);
     786                 :       3132 :         format_spec = empty;
     787                 :            :     }
     788                 :            : 
     789                 :            :     /* Find the (unbound!) __format__ method */
     790                 :     271405 :     meth = _PyObject_LookupSpecial(obj, &_Py_ID(__format__));
     791         [ -  + ]:     271405 :     if (meth == NULL) {
     792                 :          0 :         PyThreadState *tstate = _PyThreadState_GET();
     793         [ #  # ]:          0 :         if (!_PyErr_Occurred(tstate)) {
     794                 :          0 :             _PyErr_Format(tstate, PyExc_TypeError,
     795                 :            :                           "Type %.100s doesn't define __format__",
     796                 :          0 :                           Py_TYPE(obj)->tp_name);
     797                 :            :         }
     798                 :          0 :         goto done;
     799                 :            :     }
     800                 :            : 
     801                 :            :     /* And call it. */
     802                 :     271405 :     result = PyObject_CallOneArg(meth, format_spec);
     803                 :     271405 :     Py_DECREF(meth);
     804                 :            : 
     805   [ -  +  +  - ]:     271405 :     if (result && !PyUnicode_Check(result)) {
     806                 :          0 :         PyErr_Format(PyExc_TypeError,
     807                 :            :                      "__format__ must return a str, not %.200s",
     808                 :          0 :                      Py_TYPE(result)->tp_name);
     809                 :          0 :         Py_SETREF(result, NULL);
     810                 :          0 :         goto done;
     811                 :            :     }
     812                 :            : 
     813                 :     271405 : done:
     814                 :     271405 :     Py_XDECREF(empty);
     815                 :     271405 :     return result;
     816                 :            : }
     817                 :            : /* Operations on numbers */
     818                 :            : 
     819                 :            : int
     820                 :       1619 : PyNumber_Check(PyObject *o)
     821                 :            : {
     822         [ -  + ]:       1619 :     if (o == NULL)
     823                 :          0 :         return 0;
     824                 :       1619 :     PyNumberMethods *nb = Py_TYPE(o)->tp_as_number;
     825   [ +  -  +  +  :       1619 :     return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o));
          +  -  +  -  -  
                      + ]
     826                 :            : }
     827                 :            : 
     828                 :            : /* Binary operators */
     829                 :            : 
     830                 :            : #define NB_SLOT(x) offsetof(PyNumberMethods, x)
     831                 :            : #define NB_BINOP(nb_methods, slot) \
     832                 :            :         (*(binaryfunc*)(& ((char*)nb_methods)[slot]))
     833                 :            : #define NB_TERNOP(nb_methods, slot) \
     834                 :            :         (*(ternaryfunc*)(& ((char*)nb_methods)[slot]))
     835                 :            : 
     836                 :            : /*
     837                 :            :   Calling scheme used for binary operations:
     838                 :            : 
     839                 :            :   Order operations are tried until either a valid result or error:
     840                 :            :     w.op(v,w)[*], v.op(v,w), w.op(v,w)
     841                 :            : 
     842                 :            :   [*] only when Py_TYPE(v) != Py_TYPE(w) && Py_TYPE(w) is a subclass of
     843                 :            :       Py_TYPE(v)
     844                 :            :  */
     845                 :            : 
     846                 :            : static PyObject *
     847                 :    3178178 : binary_op1(PyObject *v, PyObject *w, const int op_slot
     848                 :            : #ifndef NDEBUG
     849                 :            :            , const char *op_name
     850                 :            : #endif
     851                 :            :            )
     852                 :            : {
     853                 :            :     binaryfunc slotv;
     854         [ +  + ]:    3178178 :     if (Py_TYPE(v)->tp_as_number != NULL) {
     855                 :    3176110 :         slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot);
     856                 :            :     }
     857                 :            :     else {
     858                 :       2068 :         slotv = NULL;
     859                 :            :     }
     860                 :            : 
     861                 :            :     binaryfunc slotw;
     862   [ +  +  +  + ]:    3178178 :     if (!Py_IS_TYPE(w, Py_TYPE(v)) && Py_TYPE(w)->tp_as_number != NULL) {
     863                 :     382394 :         slotw = NB_BINOP(Py_TYPE(w)->tp_as_number, op_slot);
     864         [ +  + ]:     382394 :         if (slotw == slotv) {
     865                 :       2846 :             slotw = NULL;
     866                 :            :         }
     867                 :            :     }
     868                 :            :     else {
     869                 :    2795784 :         slotw = NULL;
     870                 :            :     }
     871                 :            : 
     872         [ +  + ]:    3178178 :     if (slotv) {
     873                 :            :         PyObject *x;
     874   [ +  +  +  + ]:    3024457 :         if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) {
     875                 :        144 :             x = slotw(v, w);
     876         [ +  - ]:        144 :             if (x != Py_NotImplemented)
     877                 :        144 :                 return x;
     878                 :          0 :             Py_DECREF(x); /* can't do it */
     879                 :          0 :             slotw = NULL;
     880                 :            :         }
     881                 :    3024313 :         x = slotv(v, w);
     882                 :            :         assert(_Py_CheckSlotResult(v, op_name, x != NULL));
     883         [ +  + ]:    3024313 :         if (x != Py_NotImplemented) {
     884                 :    2817249 :             return x;
     885                 :            :         }
     886                 :     207064 :         Py_DECREF(x); /* can't do it */
     887                 :            :     }
     888         [ +  + ]:     360785 :     if (slotw) {
     889                 :     355194 :         PyObject *x = slotw(v, w);
     890                 :            :         assert(_Py_CheckSlotResult(w, op_name, x != NULL));
     891         [ +  + ]:     355194 :         if (x != Py_NotImplemented) {
     892                 :     207048 :             return x;
     893                 :            :         }
     894                 :     148146 :         Py_DECREF(x); /* can't do it */
     895                 :            :     }
     896                 :     153737 :     Py_RETURN_NOTIMPLEMENTED;
     897                 :            : }
     898                 :            : 
     899                 :            : #ifdef NDEBUG
     900                 :            : #  define BINARY_OP1(v, w, op_slot, op_name) binary_op1(v, w, op_slot)
     901                 :            : #else
     902                 :            : #  define BINARY_OP1(v, w, op_slot, op_name) binary_op1(v, w, op_slot, op_name)
     903                 :            : #endif
     904                 :            : 
     905                 :            : static PyObject *
     906                 :          4 : binop_type_error(PyObject *v, PyObject *w, const char *op_name)
     907                 :            : {
     908                 :          4 :     PyErr_Format(PyExc_TypeError,
     909                 :            :                  "unsupported operand type(s) for %.100s: "
     910                 :            :                  "'%.100s' and '%.100s'",
     911                 :            :                  op_name,
     912                 :          4 :                  Py_TYPE(v)->tp_name,
     913                 :          4 :                  Py_TYPE(w)->tp_name);
     914                 :          4 :     return NULL;
     915                 :            : }
     916                 :            : 
     917                 :            : static PyObject *
     918                 :    1049317 : binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
     919                 :            : {
     920                 :    1049317 :     PyObject *result = BINARY_OP1(v, w, op_slot, op_name);
     921         [ -  + ]:    1049317 :     if (result == Py_NotImplemented) {
     922                 :          0 :         Py_DECREF(result);
     923                 :            : 
     924   [ #  #  #  # ]:          0 :         if (op_slot == NB_SLOT(nb_rshift) &&
     925                 :          0 :             PyCFunction_CheckExact(v) &&
     926         [ #  # ]:          0 :             strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0)
     927                 :            :         {
     928                 :          0 :             PyErr_Format(PyExc_TypeError,
     929                 :            :                 "unsupported operand type(s) for %.100s: "
     930                 :            :                 "'%.100s' and '%.100s'. Did you mean \"print(<message>, "
     931                 :            :                 "file=<output_stream>)\"?",
     932                 :            :                 op_name,
     933                 :          0 :                 Py_TYPE(v)->tp_name,
     934                 :          0 :                 Py_TYPE(w)->tp_name);
     935                 :          0 :             return NULL;
     936                 :            :         }
     937                 :          0 :         return binop_type_error(v, w, op_name);
     938                 :            :     }
     939                 :    1049317 :     return result;
     940                 :            : }
     941                 :            : 
     942                 :            : 
     943                 :            : /*
     944                 :            :   Calling scheme used for ternary operations:
     945                 :            : 
     946                 :            :   Order operations are tried until either a valid result or error:
     947                 :            :     v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
     948                 :            :  */
     949                 :            : 
     950                 :            : static PyObject *
     951                 :     216773 : ternary_op(PyObject *v,
     952                 :            :            PyObject *w,
     953                 :            :            PyObject *z,
     954                 :            :            const int op_slot,
     955                 :            :            const char *op_name
     956                 :            :            )
     957                 :            : {
     958                 :     216773 :     PyNumberMethods *mv = Py_TYPE(v)->tp_as_number;
     959                 :     216773 :     PyNumberMethods *mw = Py_TYPE(w)->tp_as_number;
     960                 :            : 
     961                 :            :     ternaryfunc slotv;
     962         [ +  - ]:     216773 :     if (mv != NULL) {
     963                 :     216773 :         slotv = NB_TERNOP(mv, op_slot);
     964                 :            :     }
     965                 :            :     else {
     966                 :          0 :         slotv = NULL;
     967                 :            :     }
     968                 :            : 
     969                 :            :     ternaryfunc slotw;
     970   [ +  +  +  - ]:     216773 :     if (!Py_IS_TYPE(w, Py_TYPE(v)) && mw != NULL) {
     971                 :     205233 :         slotw = NB_TERNOP(mw, op_slot);
     972         [ -  + ]:     205233 :         if (slotw == slotv) {
     973                 :          0 :             slotw = NULL;
     974                 :            :         }
     975                 :            :     }
     976                 :            :     else {
     977                 :      11540 :         slotw = NULL;
     978                 :            :     }
     979                 :            : 
     980         [ +  - ]:     216773 :     if (slotv) {
     981                 :            :         PyObject *x;
     982   [ +  +  -  + ]:     216773 :         if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) {
     983                 :          0 :             x = slotw(v, w, z);
     984         [ #  # ]:          0 :             if (x != Py_NotImplemented) {
     985                 :          0 :                 return x;
     986                 :            :             }
     987                 :          0 :             Py_DECREF(x); /* can't do it */
     988                 :          0 :             slotw = NULL;
     989                 :            :         }
     990                 :     216773 :         x = slotv(v, w, z);
     991                 :            :         assert(_Py_CheckSlotResult(v, op_name, x != NULL));
     992         [ +  + ]:     216773 :         if (x != Py_NotImplemented) {
     993                 :     216771 :             return x;
     994                 :            :         }
     995                 :          2 :         Py_DECREF(x); /* can't do it */
     996                 :            :     }
     997         [ +  - ]:          2 :     if (slotw) {
     998                 :          2 :         PyObject *x = slotw(v, w, z);
     999                 :            :         assert(_Py_CheckSlotResult(w, op_name, x != NULL));
    1000         [ +  - ]:          2 :         if (x != Py_NotImplemented) {
    1001                 :          2 :             return x;
    1002                 :            :         }
    1003                 :          0 :         Py_DECREF(x); /* can't do it */
    1004                 :            :     }
    1005                 :            : 
    1006                 :          0 :     PyNumberMethods *mz = Py_TYPE(z)->tp_as_number;
    1007         [ #  # ]:          0 :     if (mz != NULL) {
    1008                 :          0 :         ternaryfunc slotz = NB_TERNOP(mz, op_slot);
    1009   [ #  #  #  # ]:          0 :         if (slotz == slotv || slotz == slotw) {
    1010                 :          0 :             slotz = NULL;
    1011                 :            :         }
    1012         [ #  # ]:          0 :         if (slotz) {
    1013                 :          0 :             PyObject *x = slotz(v, w, z);
    1014                 :            :             assert(_Py_CheckSlotResult(z, op_name, x != NULL));
    1015         [ #  # ]:          0 :             if (x != Py_NotImplemented) {
    1016                 :          0 :                 return x;
    1017                 :            :             }
    1018                 :          0 :             Py_DECREF(x); /* can't do it */
    1019                 :            :         }
    1020                 :            :     }
    1021                 :            : 
    1022         [ #  # ]:          0 :     if (z == Py_None) {
    1023                 :          0 :         PyErr_Format(
    1024                 :            :             PyExc_TypeError,
    1025                 :            :             "unsupported operand type(s) for %.100s: "
    1026                 :            :             "'%.100s' and '%.100s'",
    1027                 :            :             op_name,
    1028                 :          0 :             Py_TYPE(v)->tp_name,
    1029                 :          0 :             Py_TYPE(w)->tp_name);
    1030                 :            :     }
    1031                 :            :     else {
    1032                 :          0 :         PyErr_Format(
    1033                 :            :             PyExc_TypeError,
    1034                 :            :             "unsupported operand type(s) for %.100s: "
    1035                 :            :             "'%.100s', '%.100s', '%.100s'",
    1036                 :            :             op_name,
    1037                 :          0 :             Py_TYPE(v)->tp_name,
    1038                 :          0 :             Py_TYPE(w)->tp_name,
    1039                 :          0 :             Py_TYPE(z)->tp_name);
    1040                 :            :     }
    1041                 :          0 :     return NULL;
    1042                 :            : }
    1043                 :            : 
    1044                 :            : #define BINARY_FUNC(func, op, op_name) \
    1045                 :            :     PyObject * \
    1046                 :            :     func(PyObject *v, PyObject *w) { \
    1047                 :            :         return binary_op(v, w, NB_SLOT(op), op_name); \
    1048                 :            :     }
    1049                 :            : 
    1050                 :     260308 : BINARY_FUNC(PyNumber_Or, nb_or, "|")
    1051                 :          7 : BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
    1052                 :      92656 : BINARY_FUNC(PyNumber_And, nb_and, "&")
    1053                 :      49126 : BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
    1054                 :     509999 : BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
    1055                 :      14458 : BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
    1056                 :        148 : BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
    1057                 :            : 
    1058                 :            : PyObject *
    1059                 :     233885 : PyNumber_Add(PyObject *v, PyObject *w)
    1060                 :            : {
    1061                 :     233885 :     PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_add), "+");
    1062         [ +  + ]:     233885 :     if (result != Py_NotImplemented) {
    1063                 :     228798 :         return result;
    1064                 :            :     }
    1065                 :       5087 :     Py_DECREF(result);
    1066                 :            : 
    1067                 :       5087 :     PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence;
    1068   [ +  +  +  - ]:       5087 :     if (m && m->sq_concat) {
    1069                 :       5085 :         result = (*m->sq_concat)(v, w);
    1070                 :            :         assert(_Py_CheckSlotResult(v, "+", result != NULL));
    1071                 :       5085 :         return result;
    1072                 :            :     }
    1073                 :            : 
    1074                 :          2 :     return binop_type_error(v, w, "+");
    1075                 :            : }
    1076                 :            : 
    1077                 :            : static PyObject *
    1078                 :     148165 : sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
    1079                 :            : {
    1080                 :            :     Py_ssize_t count;
    1081         [ +  + ]:     148165 :     if (_PyIndex_Check(n)) {
    1082                 :     148159 :         count = PyNumber_AsSsize_t(n, PyExc_OverflowError);
    1083   [ -  +  -  - ]:     148159 :         if (count == -1 && PyErr_Occurred()) {
    1084                 :          0 :             return NULL;
    1085                 :            :         }
    1086                 :            :     }
    1087                 :            :     else {
    1088                 :          6 :         return type_error("can't multiply sequence by "
    1089                 :            :                           "non-int of type '%.200s'", n);
    1090                 :            :     }
    1091                 :     148159 :     PyObject *res = (*repeatfunc)(seq, count);
    1092                 :            :     assert(_Py_CheckSlotResult(seq, "*", res != NULL));
    1093                 :     148159 :     return res;
    1094                 :            : }
    1095                 :            : 
    1096                 :            : PyObject *
    1097                 :    1272786 : PyNumber_Multiply(PyObject *v, PyObject *w)
    1098                 :            : {
    1099                 :    1272786 :     PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_multiply), "*");
    1100         [ +  + ]:    1272786 :     if (result == Py_NotImplemented) {
    1101                 :     148167 :         PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence;
    1102                 :     148167 :         PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence;
    1103                 :     148167 :         Py_DECREF(result);
    1104   [ +  +  +  + ]:     148167 :         if  (mv && mv->sq_repeat) {
    1105                 :     148152 :             return sequence_repeat(mv->sq_repeat, v, w);
    1106                 :            :         }
    1107   [ +  -  +  + ]:         15 :         else if (mw && mw->sq_repeat) {
    1108                 :         13 :             return sequence_repeat(mw->sq_repeat, w, v);
    1109                 :            :         }
    1110                 :          2 :         result = binop_type_error(v, w, "*");
    1111                 :            :     }
    1112                 :    1124621 :     return result;
    1113                 :            : }
    1114                 :            : 
    1115                 :            : PyObject *
    1116                 :          0 : PyNumber_MatrixMultiply(PyObject *v, PyObject *w)
    1117                 :            : {
    1118                 :          0 :     return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@");
    1119                 :            : }
    1120                 :            : 
    1121                 :            : PyObject *
    1122                 :      89275 : PyNumber_FloorDivide(PyObject *v, PyObject *w)
    1123                 :            : {
    1124                 :      89275 :     return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
    1125                 :            : }
    1126                 :            : 
    1127                 :            : PyObject *
    1128                 :      33110 : PyNumber_TrueDivide(PyObject *v, PyObject *w)
    1129                 :            : {
    1130                 :      33110 :     return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
    1131                 :            : }
    1132                 :            : 
    1133                 :            : PyObject *
    1134                 :        230 : PyNumber_Remainder(PyObject *v, PyObject *w)
    1135                 :            : {
    1136                 :        230 :     return binary_op(v, w, NB_SLOT(nb_remainder), "%");
    1137                 :            : }
    1138                 :            : 
    1139                 :            : PyObject *
    1140                 :     216773 : PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
    1141                 :            : {
    1142                 :     216773 :     return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
    1143                 :            : }
    1144                 :            : 
    1145                 :            : PyObject *
    1146                 :     216707 : _PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs)
    1147                 :            : {
    1148                 :     216707 :     return PyNumber_Power(lhs, rhs, Py_None);
    1149                 :            : }
    1150                 :            : 
    1151                 :            : /* Binary in-place operators */
    1152                 :            : 
    1153                 :            : /* The in-place operators are defined to fall back to the 'normal',
    1154                 :            :    non in-place operations, if the in-place methods are not in place.
    1155                 :            : 
    1156                 :            :    - If the left hand object has the appropriate struct members, and
    1157                 :            :      they are filled, call the appropriate function and return the
    1158                 :            :      result.  No coercion is done on the arguments; the left-hand object
    1159                 :            :      is the one the operation is performed on, and it's up to the
    1160                 :            :      function to deal with the right-hand object.
    1161                 :            : 
    1162                 :            :    - Otherwise, in-place modification is not supported. Handle it exactly as
    1163                 :            :      a non in-place operation of the same kind.
    1164                 :            : 
    1165                 :            :    */
    1166                 :            : 
    1167                 :            : static PyObject *
    1168                 :     668726 : binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot
    1169                 :            : #ifndef NDEBUG
    1170                 :            :             , const char *op_name
    1171                 :            : #endif
    1172                 :            :             )
    1173                 :            : {
    1174                 :     668726 :     PyNumberMethods *mv = Py_TYPE(v)->tp_as_number;
    1175         [ +  + ]:     668726 :     if (mv != NULL) {
    1176                 :     668331 :         binaryfunc slot = NB_BINOP(mv, iop_slot);
    1177         [ +  + ]:     668331 :         if (slot) {
    1178                 :      46536 :             PyObject *x = (slot)(v, w);
    1179                 :            :             assert(_Py_CheckSlotResult(v, op_name, x != NULL));
    1180         [ +  - ]:      46536 :             if (x != Py_NotImplemented) {
    1181                 :      46536 :                 return x;
    1182                 :            :             }
    1183                 :          0 :             Py_DECREF(x);
    1184                 :            :         }
    1185                 :            :     }
    1186                 :            : #ifdef NDEBUG
    1187                 :     622190 :     return binary_op1(v, w, op_slot);
    1188                 :            : #else
    1189                 :            :     return binary_op1(v, w, op_slot, op_name);
    1190                 :            : #endif
    1191                 :            : }
    1192                 :            : 
    1193                 :            : #ifdef NDEBUG
    1194                 :            : #  define BINARY_IOP1(v, w, iop_slot, op_slot, op_name) binary_iop1(v, w, iop_slot, op_slot)
    1195                 :            : #else
    1196                 :            : #  define BINARY_IOP1(v, w, iop_slot, op_slot, op_name) binary_iop1(v, w, iop_slot, op_slot, op_name)
    1197                 :            : #endif
    1198                 :            : 
    1199                 :            : static PyObject *
    1200                 :     667145 : binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
    1201                 :            :                 const char *op_name)
    1202                 :            : {
    1203                 :     667145 :     PyObject *result = BINARY_IOP1(v, w, iop_slot, op_slot, op_name);
    1204         [ -  + ]:     667145 :     if (result == Py_NotImplemented) {
    1205                 :          0 :         Py_DECREF(result);
    1206                 :          0 :         return binop_type_error(v, w, op_name);
    1207                 :            :     }
    1208                 :     667145 :     return result;
    1209                 :            : }
    1210                 :            : 
    1211                 :            : static PyObject *
    1212                 :          0 : ternary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int op_slot,
    1213                 :            :                 const char *op_name)
    1214                 :            : {
    1215                 :          0 :     PyNumberMethods *mv = Py_TYPE(v)->tp_as_number;
    1216         [ #  # ]:          0 :     if (mv != NULL) {
    1217                 :          0 :         ternaryfunc slot = NB_TERNOP(mv, iop_slot);
    1218         [ #  # ]:          0 :         if (slot) {
    1219                 :          0 :             PyObject *x = (slot)(v, w, z);
    1220         [ #  # ]:          0 :             if (x != Py_NotImplemented) {
    1221                 :          0 :                 return x;
    1222                 :            :             }
    1223                 :          0 :             Py_DECREF(x);
    1224                 :            :         }
    1225                 :            :     }
    1226                 :          0 :     return ternary_op(v, w, z, op_slot, op_name);
    1227                 :            : }
    1228                 :            : 
    1229                 :            : #define INPLACE_BINOP(func, iop, op, op_name) \
    1230                 :            :     PyObject * \
    1231                 :            :     func(PyObject *v, PyObject *w) { \
    1232                 :            :         return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
    1233                 :            :     }
    1234                 :            : 
    1235                 :     110559 : INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
    1236                 :         15 : INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
    1237                 :         79 : INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
    1238                 :     520000 : INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
    1239                 :          0 : INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
    1240                 :          4 : INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
    1241                 :          0 : INPLACE_BINOP(PyNumber_InPlaceMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=")
    1242                 :      36488 : INPLACE_BINOP(PyNumber_InPlaceFloorDivide, nb_inplace_floor_divide, nb_floor_divide, "//=")
    1243                 :          0 : INPLACE_BINOP(PyNumber_InPlaceTrueDivide, nb_inplace_true_divide, nb_true_divide,  "/=")
    1244                 :          0 : INPLACE_BINOP(PyNumber_InPlaceRemainder, nb_inplace_remainder, nb_remainder, "%=")
    1245                 :            : 
    1246                 :            : PyObject *
    1247                 :       1524 : PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
    1248                 :            : {
    1249                 :       1524 :     PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_add),
    1250                 :            :                                    NB_SLOT(nb_add), "+=");
    1251         [ +  + ]:       1524 :     if (result == Py_NotImplemented) {
    1252                 :        483 :         PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence;
    1253                 :        483 :         Py_DECREF(result);
    1254         [ +  - ]:        483 :         if (m != NULL) {
    1255                 :        483 :             binaryfunc func = m->sq_inplace_concat;
    1256         [ +  + ]:        483 :             if (func == NULL)
    1257                 :        247 :                 func = m->sq_concat;
    1258         [ +  - ]:        483 :             if (func != NULL) {
    1259                 :        483 :                 result = func(v, w);
    1260                 :            :                 assert(_Py_CheckSlotResult(v, "+=", result != NULL));
    1261                 :        483 :                 return result;
    1262                 :            :             }
    1263                 :            :         }
    1264                 :          0 :         result = binop_type_error(v, w, "+=");
    1265                 :            :     }
    1266                 :       1041 :     return result;
    1267                 :            : }
    1268                 :            : 
    1269                 :            : PyObject *
    1270                 :         57 : PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
    1271                 :            : {
    1272                 :         57 :     PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_multiply),
    1273                 :            :                                    NB_SLOT(nb_multiply), "*=");
    1274         [ -  + ]:         57 :     if (result == Py_NotImplemented) {
    1275                 :          0 :         ssizeargfunc f = NULL;
    1276                 :          0 :         PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence;
    1277                 :          0 :         PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence;
    1278                 :          0 :         Py_DECREF(result);
    1279         [ #  # ]:          0 :         if (mv != NULL) {
    1280                 :          0 :             f = mv->sq_inplace_repeat;
    1281         [ #  # ]:          0 :             if (f == NULL)
    1282                 :          0 :                 f = mv->sq_repeat;
    1283         [ #  # ]:          0 :             if (f != NULL)
    1284                 :          0 :                 return sequence_repeat(f, v, w);
    1285                 :            :         }
    1286         [ #  # ]:          0 :         else if (mw != NULL) {
    1287                 :            :             /* Note that the right hand operand should not be
    1288                 :            :              * mutated in this case so sq_inplace_repeat is not
    1289                 :            :              * used. */
    1290         [ #  # ]:          0 :             if (mw->sq_repeat)
    1291                 :          0 :                 return sequence_repeat(mw->sq_repeat, w, v);
    1292                 :            :         }
    1293                 :          0 :         result = binop_type_error(v, w, "*=");
    1294                 :            :     }
    1295                 :         57 :     return result;
    1296                 :            : }
    1297                 :            : 
    1298                 :            : PyObject *
    1299                 :          0 : PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
    1300                 :            : {
    1301                 :          0 :     return ternary_iop(v, w, z, NB_SLOT(nb_inplace_power),
    1302                 :            :                                 NB_SLOT(nb_power), "**=");
    1303                 :            : }
    1304                 :            : 
    1305                 :            : PyObject *
    1306                 :          0 : _PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs)
    1307                 :            : {
    1308                 :          0 :     return PyNumber_InPlacePower(lhs, rhs, Py_None);
    1309                 :            : }
    1310                 :            : 
    1311                 :            : 
    1312                 :            : /* Unary operators and functions */
    1313                 :            : 
    1314                 :            : PyObject *
    1315                 :      45933 : PyNumber_Negative(PyObject *o)
    1316                 :            : {
    1317         [ -  + ]:      45933 :     if (o == NULL) {
    1318                 :          0 :         return null_error();
    1319                 :            :     }
    1320                 :            : 
    1321                 :      45933 :     PyNumberMethods *m = Py_TYPE(o)->tp_as_number;
    1322   [ +  -  +  - ]:      45933 :     if (m && m->nb_negative) {
    1323                 :      45933 :         PyObject *res = (*m->nb_negative)(o);
    1324                 :            :         assert(_Py_CheckSlotResult(o, "__neg__", res != NULL));
    1325                 :      45933 :         return res;
    1326                 :            :     }
    1327                 :            : 
    1328                 :          0 :     return type_error("bad operand type for unary -: '%.200s'", o);
    1329                 :            : }
    1330                 :            : 
    1331                 :            : PyObject *
    1332                 :         10 : PyNumber_Positive(PyObject *o)
    1333                 :            : {
    1334         [ -  + ]:         10 :     if (o == NULL) {
    1335                 :          0 :         return null_error();
    1336                 :            :     }
    1337                 :            : 
    1338                 :         10 :     PyNumberMethods *m = Py_TYPE(o)->tp_as_number;
    1339   [ +  -  +  - ]:         10 :     if (m && m->nb_positive) {
    1340                 :         10 :         PyObject *res = (*m->nb_positive)(o);
    1341                 :            :         assert(_Py_CheckSlotResult(o, "__pos__", res != NULL));
    1342                 :         10 :         return res;
    1343                 :            :     }
    1344                 :            : 
    1345                 :          0 :     return type_error("bad operand type for unary +: '%.200s'", o);
    1346                 :            : }
    1347                 :            : 
    1348                 :            : PyObject *
    1349                 :      18212 : PyNumber_Invert(PyObject *o)
    1350                 :            : {
    1351         [ -  + ]:      18212 :     if (o == NULL) {
    1352                 :          0 :         return null_error();
    1353                 :            :     }
    1354                 :            : 
    1355                 :      18212 :     PyNumberMethods *m = Py_TYPE(o)->tp_as_number;
    1356   [ +  -  +  - ]:      18212 :     if (m && m->nb_invert) {
    1357                 :      18212 :         PyObject *res = (*m->nb_invert)(o);
    1358                 :            :         assert(_Py_CheckSlotResult(o, "__invert__", res != NULL));
    1359                 :      18212 :         return res;
    1360                 :            :     }
    1361                 :            : 
    1362                 :          0 :     return type_error("bad operand type for unary ~: '%.200s'", o);
    1363                 :            : }
    1364                 :            : 
    1365                 :            : PyObject *
    1366                 :      81240 : PyNumber_Absolute(PyObject *o)
    1367                 :            : {
    1368         [ -  + ]:      81240 :     if (o == NULL) {
    1369                 :          0 :         return null_error();
    1370                 :            :     }
    1371                 :            : 
    1372                 :      81240 :     PyNumberMethods *m = Py_TYPE(o)->tp_as_number;
    1373   [ +  -  +  - ]:      81240 :     if (m && m->nb_absolute) {
    1374                 :      81240 :         PyObject *res = m->nb_absolute(o);
    1375                 :            :         assert(_Py_CheckSlotResult(o, "__abs__", res != NULL));
    1376                 :      81240 :         return res;
    1377                 :            :     }
    1378                 :            : 
    1379                 :          0 :     return type_error("bad operand type for abs(): '%.200s'", o);
    1380                 :            : }
    1381                 :            : 
    1382                 :            : 
    1383                 :            : int
    1384                 :       5731 : PyIndex_Check(PyObject *obj)
    1385                 :            : {
    1386                 :       5731 :     return _PyIndex_Check(obj);
    1387                 :            : }
    1388                 :            : 
    1389                 :            : 
    1390                 :            : /* Return a Python int from the object item.
    1391                 :            :    Can return an instance of int subclass.
    1392                 :            :    Raise TypeError if the result is not an int
    1393                 :            :    or if the object cannot be interpreted as an index.
    1394                 :            : */
    1395                 :            : PyObject *
    1396                 :    1147679 : _PyNumber_Index(PyObject *item)
    1397                 :            : {
    1398         [ -  + ]:    1147679 :     if (item == NULL) {
    1399                 :          0 :         return null_error();
    1400                 :            :     }
    1401                 :            : 
    1402         [ +  + ]:    1147679 :     if (PyLong_Check(item)) {
    1403                 :    1146198 :         return Py_NewRef(item);
    1404                 :            :     }
    1405         [ +  + ]:       1481 :     if (!_PyIndex_Check(item)) {
    1406                 :       1459 :         PyErr_Format(PyExc_TypeError,
    1407                 :            :                      "'%.200s' object cannot be interpreted "
    1408                 :       1459 :                      "as an integer", Py_TYPE(item)->tp_name);
    1409                 :       1459 :         return NULL;
    1410                 :            :     }
    1411                 :            : 
    1412                 :         22 :     PyObject *result = Py_TYPE(item)->tp_as_number->nb_index(item);
    1413                 :            :     assert(_Py_CheckSlotResult(item, "__index__", result != NULL));
    1414   [ +  -  +  - ]:         22 :     if (!result || PyLong_CheckExact(result)) {
    1415                 :         22 :         return result;
    1416                 :            :     }
    1417                 :            : 
    1418         [ #  # ]:          0 :     if (!PyLong_Check(result)) {
    1419                 :          0 :         PyErr_Format(PyExc_TypeError,
    1420                 :            :                      "__index__ returned non-int (type %.200s)",
    1421                 :          0 :                      Py_TYPE(result)->tp_name);
    1422                 :          0 :         Py_DECREF(result);
    1423                 :          0 :         return NULL;
    1424                 :            :     }
    1425                 :            :     /* Issue #17576: warn if 'result' not of exact type int. */
    1426         [ #  # ]:          0 :     if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
    1427                 :            :             "__index__ returned non-int (type %.200s).  "
    1428                 :            :             "The ability to return an instance of a strict subclass of int "
    1429                 :            :             "is deprecated, and may be removed in a future version of Python.",
    1430                 :          0 :             Py_TYPE(result)->tp_name)) {
    1431                 :          0 :         Py_DECREF(result);
    1432                 :          0 :         return NULL;
    1433                 :            :     }
    1434                 :          0 :     return result;
    1435                 :            : }
    1436                 :            : 
    1437                 :            : /* Return an exact Python int from the object item.
    1438                 :            :    Raise TypeError if the result is not an int
    1439                 :            :    or if the object cannot be interpreted as an index.
    1440                 :            : */
    1441                 :            : PyObject *
    1442                 :     213811 : PyNumber_Index(PyObject *item)
    1443                 :            : {
    1444                 :     213811 :     PyObject *result = _PyNumber_Index(item);
    1445   [ +  +  +  + ]:     213811 :     if (result != NULL && !PyLong_CheckExact(result)) {
    1446                 :         40 :         Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));
    1447                 :            :     }
    1448                 :     213811 :     return result;
    1449                 :            : }
    1450                 :            : 
    1451                 :            : /* Return an error on Overflow only if err is not NULL*/
    1452                 :            : 
    1453                 :            : Py_ssize_t
    1454                 :     826810 : PyNumber_AsSsize_t(PyObject *item, PyObject *err)
    1455                 :            : {
    1456                 :            :     Py_ssize_t result;
    1457                 :            :     PyObject *runerr;
    1458                 :     826810 :     PyObject *value = _PyNumber_Index(item);
    1459         [ -  + ]:     826810 :     if (value == NULL)
    1460                 :          0 :         return -1;
    1461                 :            : 
    1462                 :            :     /* We're done if PyLong_AsSsize_t() returns without error. */
    1463                 :     826810 :     result = PyLong_AsSsize_t(value);
    1464         [ +  + ]:     826810 :     if (result != -1)
    1465                 :     824865 :         goto finish;
    1466                 :            : 
    1467                 :       1945 :     PyThreadState *tstate = _PyThreadState_GET();
    1468                 :       1945 :     runerr = _PyErr_Occurred(tstate);
    1469         [ +  - ]:       1945 :     if (!runerr) {
    1470                 :       1945 :         goto finish;
    1471                 :            :     }
    1472                 :            : 
    1473                 :            :     /* Error handling code -- only manage OverflowError differently */
    1474         [ #  # ]:          0 :     if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) {
    1475                 :          0 :         goto finish;
    1476                 :            :     }
    1477                 :          0 :     _PyErr_Clear(tstate);
    1478                 :            : 
    1479                 :            :     /* If no error-handling desired then the default clipping
    1480                 :            :        is sufficient. */
    1481         [ #  # ]:          0 :     if (!err) {
    1482                 :            :         assert(PyLong_Check(value));
    1483                 :            :         /* Whether or not it is less than or equal to
    1484                 :            :            zero is determined by the sign of ob_size
    1485                 :            :         */
    1486         [ #  # ]:          0 :         if (_PyLong_Sign(value) < 0)
    1487                 :          0 :             result = PY_SSIZE_T_MIN;
    1488                 :            :         else
    1489                 :          0 :             result = PY_SSIZE_T_MAX;
    1490                 :            :     }
    1491                 :            :     else {
    1492                 :            :         /* Otherwise replace the error with caller's error object. */
    1493                 :          0 :         _PyErr_Format(tstate, err,
    1494                 :            :                       "cannot fit '%.200s' into an index-sized integer",
    1495                 :          0 :                       Py_TYPE(item)->tp_name);
    1496                 :            :     }
    1497                 :            : 
    1498                 :     826810 :  finish:
    1499                 :     826810 :     Py_DECREF(value);
    1500                 :     826810 :     return result;
    1501                 :            : }
    1502                 :            : 
    1503                 :            : 
    1504                 :            : PyObject *
    1505                 :     533142 : PyNumber_Long(PyObject *o)
    1506                 :            : {
    1507                 :            :     PyObject *result;
    1508                 :            :     PyNumberMethods *m;
    1509                 :            :     PyObject *trunc_func;
    1510                 :            :     Py_buffer view;
    1511                 :            : 
    1512         [ -  + ]:     533142 :     if (o == NULL) {
    1513                 :          0 :         return null_error();
    1514                 :            :     }
    1515                 :            : 
    1516         [ +  + ]:     533142 :     if (PyLong_CheckExact(o)) {
    1517                 :       1274 :         return Py_NewRef(o);
    1518                 :            :     }
    1519                 :     531868 :     m = Py_TYPE(o)->tp_as_number;
    1520   [ +  -  +  + ]:     531868 :     if (m && m->nb_int) { /* This should include subclasses of int */
    1521                 :            :         /* Convert using the nb_int slot, which should return something
    1522                 :            :            of exact type int. */
    1523                 :     531027 :         result = m->nb_int(o);
    1524                 :            :         assert(_Py_CheckSlotResult(o, "__int__", result != NULL));
    1525   [ +  -  +  - ]:     531027 :         if (!result || PyLong_CheckExact(result)) {
    1526                 :     531027 :             return result;
    1527                 :            :         }
    1528                 :            : 
    1529         [ #  # ]:          0 :         if (!PyLong_Check(result)) {
    1530                 :          0 :             PyErr_Format(PyExc_TypeError,
    1531                 :            :                          "__int__ returned non-int (type %.200s)",
    1532                 :          0 :                          Py_TYPE(result)->tp_name);
    1533                 :          0 :             Py_DECREF(result);
    1534                 :          0 :             return NULL;
    1535                 :            :         }
    1536                 :            :         /* Issue #17576: warn if 'result' not of exact type int. */
    1537         [ #  # ]:          0 :         if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
    1538                 :            :                 "__int__ returned non-int (type %.200s).  "
    1539                 :            :                 "The ability to return an instance of a strict subclass of int "
    1540                 :            :                 "is deprecated, and may be removed in a future version of Python.",
    1541                 :          0 :                 Py_TYPE(result)->tp_name)) {
    1542                 :          0 :             Py_DECREF(result);
    1543                 :          0 :             return NULL;
    1544                 :            :         }
    1545                 :          0 :         Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));
    1546                 :          0 :         return result;
    1547                 :            :     }
    1548   [ +  -  -  + ]:        841 :     if (m && m->nb_index) {
    1549                 :          0 :         return PyNumber_Index(o);
    1550                 :            :     }
    1551                 :        841 :     trunc_func = _PyObject_LookupSpecial(o, &_Py_ID(__trunc__));
    1552         [ -  + ]:        841 :     if (trunc_func) {
    1553         [ #  # ]:          0 :         if (PyErr_WarnEx(PyExc_DeprecationWarning,
    1554                 :            :                 "The delegation of int() to __trunc__ is deprecated.", 1)) {
    1555                 :          0 :             Py_DECREF(trunc_func);
    1556                 :          0 :             return NULL;
    1557                 :            :         }
    1558                 :          0 :         result = _PyObject_CallNoArgs(trunc_func);
    1559                 :          0 :         Py_DECREF(trunc_func);
    1560   [ #  #  #  # ]:          0 :         if (result == NULL || PyLong_CheckExact(result)) {
    1561                 :          0 :             return result;
    1562                 :            :         }
    1563         [ #  # ]:          0 :         if (PyLong_Check(result)) {
    1564                 :          0 :             Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));
    1565                 :          0 :             return result;
    1566                 :            :         }
    1567                 :            :         /* __trunc__ is specified to return an Integral type,
    1568                 :            :            but int() needs to return an int. */
    1569         [ #  # ]:          0 :         if (!PyIndex_Check(result)) {
    1570                 :          0 :             PyErr_Format(
    1571                 :            :                 PyExc_TypeError,
    1572                 :            :                 "__trunc__ returned non-Integral (type %.200s)",
    1573                 :          0 :                 Py_TYPE(result)->tp_name);
    1574                 :          0 :             Py_DECREF(result);
    1575                 :          0 :             return NULL;
    1576                 :            :         }
    1577                 :          0 :         Py_SETREF(result, PyNumber_Index(result));
    1578                 :          0 :         return result;
    1579                 :            :     }
    1580         [ -  + ]:        841 :     if (PyErr_Occurred())
    1581                 :          0 :         return NULL;
    1582                 :            : 
    1583         [ +  - ]:        841 :     if (PyUnicode_Check(o))
    1584                 :            :         /* The below check is done in PyLong_FromUnicodeObject(). */
    1585                 :        841 :         return PyLong_FromUnicodeObject(o, 10);
    1586                 :            : 
    1587         [ #  # ]:          0 :     if (PyBytes_Check(o))
    1588                 :            :         /* need to do extra error checking that PyLong_FromString()
    1589                 :            :          * doesn't do.  In particular int('9\x005') must raise an
    1590                 :            :          * exception, not truncate at the null.
    1591                 :            :          */
    1592                 :          0 :         return _PyLong_FromBytes(PyBytes_AS_STRING(o),
    1593                 :            :                                  PyBytes_GET_SIZE(o), 10);
    1594                 :            : 
    1595         [ #  # ]:          0 :     if (PyByteArray_Check(o))
    1596                 :          0 :         return _PyLong_FromBytes(PyByteArray_AS_STRING(o),
    1597                 :            :                                  PyByteArray_GET_SIZE(o), 10);
    1598                 :            : 
    1599         [ #  # ]:          0 :     if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) {
    1600                 :            :         PyObject *bytes;
    1601                 :            : 
    1602                 :            :         /* Copy to NUL-terminated buffer. */
    1603                 :          0 :         bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len);
    1604         [ #  # ]:          0 :         if (bytes == NULL) {
    1605                 :          0 :             PyBuffer_Release(&view);
    1606                 :          0 :             return NULL;
    1607                 :            :         }
    1608                 :          0 :         result = _PyLong_FromBytes(PyBytes_AS_STRING(bytes),
    1609                 :            :                                    PyBytes_GET_SIZE(bytes), 10);
    1610                 :          0 :         Py_DECREF(bytes);
    1611                 :          0 :         PyBuffer_Release(&view);
    1612                 :          0 :         return result;
    1613                 :            :     }
    1614                 :            : 
    1615                 :          0 :     return type_error("int() argument must be a string, a bytes-like object "
    1616                 :            :                       "or a real number, not '%.200s'", o);
    1617                 :            : }
    1618                 :            : 
    1619                 :            : PyObject *
    1620                 :       6150 : PyNumber_Float(PyObject *o)
    1621                 :            : {
    1622         [ -  + ]:       6150 :     if (o == NULL) {
    1623                 :          0 :         return null_error();
    1624                 :            :     }
    1625                 :            : 
    1626         [ +  + ]:       6150 :     if (PyFloat_CheckExact(o)) {
    1627                 :          4 :         return Py_NewRef(o);
    1628                 :            :     }
    1629                 :            : 
    1630                 :       6146 :     PyNumberMethods *m = Py_TYPE(o)->tp_as_number;
    1631   [ +  -  +  - ]:       6146 :     if (m && m->nb_float) { /* This should include subclasses of float */
    1632                 :       6146 :         PyObject *res = m->nb_float(o);
    1633                 :            :         assert(_Py_CheckSlotResult(o, "__float__", res != NULL));
    1634   [ +  -  +  - ]:       6146 :         if (!res || PyFloat_CheckExact(res)) {
    1635                 :       6146 :             return res;
    1636                 :            :         }
    1637                 :            : 
    1638         [ #  # ]:          0 :         if (!PyFloat_Check(res)) {
    1639                 :          0 :             PyErr_Format(PyExc_TypeError,
    1640                 :            :                          "%.50s.__float__ returned non-float (type %.50s)",
    1641                 :          0 :                          Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name);
    1642                 :          0 :             Py_DECREF(res);
    1643                 :          0 :             return NULL;
    1644                 :            :         }
    1645                 :            :         /* Issue #26983: warn if 'res' not of exact type float. */
    1646         [ #  # ]:          0 :         if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
    1647                 :            :                 "%.50s.__float__ returned non-float (type %.50s).  "
    1648                 :            :                 "The ability to return an instance of a strict subclass of float "
    1649                 :            :                 "is deprecated, and may be removed in a future version of Python.",
    1650                 :          0 :                 Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name)) {
    1651                 :          0 :             Py_DECREF(res);
    1652                 :          0 :             return NULL;
    1653                 :            :         }
    1654                 :          0 :         double val = PyFloat_AS_DOUBLE(res);
    1655                 :          0 :         Py_DECREF(res);
    1656                 :          0 :         return PyFloat_FromDouble(val);
    1657                 :            :     }
    1658                 :            : 
    1659   [ #  #  #  # ]:          0 :     if (m && m->nb_index) {
    1660                 :          0 :         PyObject *res = _PyNumber_Index(o);
    1661         [ #  # ]:          0 :         if (!res) {
    1662                 :          0 :             return NULL;
    1663                 :            :         }
    1664                 :          0 :         double val = PyLong_AsDouble(res);
    1665                 :          0 :         Py_DECREF(res);
    1666   [ #  #  #  # ]:          0 :         if (val == -1.0 && PyErr_Occurred()) {
    1667                 :          0 :             return NULL;
    1668                 :            :         }
    1669                 :          0 :         return PyFloat_FromDouble(val);
    1670                 :            :     }
    1671                 :            : 
    1672                 :            :     /* A float subclass with nb_float == NULL */
    1673         [ #  # ]:          0 :     if (PyFloat_Check(o)) {
    1674                 :          0 :         return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o));
    1675                 :            :     }
    1676                 :          0 :     return PyFloat_FromString(o);
    1677                 :            : }
    1678                 :            : 
    1679                 :            : 
    1680                 :            : PyObject *
    1681                 :       2004 : PyNumber_ToBase(PyObject *n, int base)
    1682                 :            : {
    1683   [ +  +  +  -  :       2004 :     if (!(base == 2 || base == 8 || base == 10 || base == 16)) {
             -  +  -  - ]
    1684                 :          0 :         PyErr_SetString(PyExc_SystemError,
    1685                 :            :                         "PyNumber_ToBase: base must be 2, 8, 10 or 16");
    1686                 :          0 :         return NULL;
    1687                 :            :     }
    1688                 :       2004 :     PyObject *index = _PyNumber_Index(n);
    1689         [ -  + ]:       2004 :     if (!index)
    1690                 :          0 :         return NULL;
    1691                 :       2004 :     PyObject *res = _PyLong_Format(index, base);
    1692                 :       2004 :     Py_DECREF(index);
    1693                 :       2004 :     return res;
    1694                 :            : }
    1695                 :            : 
    1696                 :            : 
    1697                 :            : /* Operations on sequences */
    1698                 :            : 
    1699                 :            : int
    1700                 :       1144 : PySequence_Check(PyObject *s)
    1701                 :            : {
    1702         [ -  + ]:       1144 :     if (PyDict_Check(s))
    1703                 :          0 :         return 0;
    1704         [ +  + ]:       2284 :     return Py_TYPE(s)->tp_as_sequence &&
    1705         [ +  + ]:       1140 :         Py_TYPE(s)->tp_as_sequence->sq_item != NULL;
    1706                 :            : }
    1707                 :            : 
    1708                 :            : Py_ssize_t
    1709                 :         29 : PySequence_Size(PyObject *s)
    1710                 :            : {
    1711         [ -  + ]:         29 :     if (s == NULL) {
    1712                 :          0 :         null_error();
    1713                 :          0 :         return -1;
    1714                 :            :     }
    1715                 :            : 
    1716                 :         29 :     PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence;
    1717   [ +  -  +  - ]:         29 :     if (m && m->sq_length) {
    1718                 :         29 :         Py_ssize_t len = m->sq_length(s);
    1719                 :            :         assert(_Py_CheckSlotResult(s, "__len__", len >= 0));
    1720                 :         29 :         return len;
    1721                 :            :     }
    1722                 :            : 
    1723   [ #  #  #  # ]:          0 :     if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_length) {
    1724                 :          0 :         type_error("%.200s is not a sequence", s);
    1725                 :          0 :         return -1;
    1726                 :            :     }
    1727                 :          0 :     type_error("object of type '%.200s' has no len()", s);
    1728                 :          0 :     return -1;
    1729                 :            : }
    1730                 :            : 
    1731                 :            : #undef PySequence_Length
    1732                 :            : Py_ssize_t
    1733                 :          0 : PySequence_Length(PyObject *s)
    1734                 :            : {
    1735                 :          0 :     return PySequence_Size(s);
    1736                 :            : }
    1737                 :            : #define PySequence_Length PySequence_Size
    1738                 :            : 
    1739                 :            : PyObject *
    1740                 :         73 : PySequence_Concat(PyObject *s, PyObject *o)
    1741                 :            : {
    1742   [ +  -  -  + ]:         73 :     if (s == NULL || o == NULL) {
    1743                 :          0 :         return null_error();
    1744                 :            :     }
    1745                 :            : 
    1746                 :         73 :     PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence;
    1747   [ +  -  +  - ]:         73 :     if (m && m->sq_concat) {
    1748                 :         73 :         PyObject *res = m->sq_concat(s, o);
    1749                 :            :         assert(_Py_CheckSlotResult(s, "+", res != NULL));
    1750                 :         73 :         return res;
    1751                 :            :     }
    1752                 :            : 
    1753                 :            :     /* Instances of user classes defining an __add__() method only
    1754                 :            :        have an nb_add slot, not an sq_concat slot.      So we fall back
    1755                 :            :        to nb_add if both arguments appear to be sequences. */
    1756   [ #  #  #  # ]:          0 :     if (PySequence_Check(s) && PySequence_Check(o)) {
    1757                 :          0 :         PyObject *result = BINARY_OP1(s, o, NB_SLOT(nb_add), "+");
    1758         [ #  # ]:          0 :         if (result != Py_NotImplemented)
    1759                 :          0 :             return result;
    1760                 :          0 :         Py_DECREF(result);
    1761                 :            :     }
    1762                 :          0 :     return type_error("'%.200s' object can't be concatenated", s);
    1763                 :            : }
    1764                 :            : 
    1765                 :            : PyObject *
    1766                 :          0 : PySequence_Repeat(PyObject *o, Py_ssize_t count)
    1767                 :            : {
    1768         [ #  # ]:          0 :     if (o == NULL) {
    1769                 :          0 :         return null_error();
    1770                 :            :     }
    1771                 :            : 
    1772                 :          0 :     PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
    1773   [ #  #  #  # ]:          0 :     if (m && m->sq_repeat) {
    1774                 :          0 :         PyObject *res = m->sq_repeat(o, count);
    1775                 :            :         assert(_Py_CheckSlotResult(o, "*", res != NULL));
    1776                 :          0 :         return res;
    1777                 :            :     }
    1778                 :            : 
    1779                 :            :     /* Instances of user classes defining a __mul__() method only
    1780                 :            :        have an nb_multiply slot, not an sq_repeat slot. so we fall back
    1781                 :            :        to nb_multiply if o appears to be a sequence. */
    1782         [ #  # ]:          0 :     if (PySequence_Check(o)) {
    1783                 :            :         PyObject *n, *result;
    1784                 :          0 :         n = PyLong_FromSsize_t(count);
    1785         [ #  # ]:          0 :         if (n == NULL)
    1786                 :          0 :             return NULL;
    1787                 :          0 :         result = BINARY_OP1(o, n, NB_SLOT(nb_multiply), "*");
    1788                 :          0 :         Py_DECREF(n);
    1789         [ #  # ]:          0 :         if (result != Py_NotImplemented)
    1790                 :          0 :             return result;
    1791                 :          0 :         Py_DECREF(result);
    1792                 :            :     }
    1793                 :          0 :     return type_error("'%.200s' object can't be repeated", o);
    1794                 :            : }
    1795                 :            : 
    1796                 :            : PyObject *
    1797                 :          0 : PySequence_InPlaceConcat(PyObject *s, PyObject *o)
    1798                 :            : {
    1799   [ #  #  #  # ]:          0 :     if (s == NULL || o == NULL) {
    1800                 :          0 :         return null_error();
    1801                 :            :     }
    1802                 :            : 
    1803                 :          0 :     PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence;
    1804   [ #  #  #  # ]:          0 :     if (m && m->sq_inplace_concat) {
    1805                 :          0 :         PyObject *res = m->sq_inplace_concat(s, o);
    1806                 :            :         assert(_Py_CheckSlotResult(s, "+=", res != NULL));
    1807                 :          0 :         return res;
    1808                 :            :     }
    1809   [ #  #  #  # ]:          0 :     if (m && m->sq_concat) {
    1810                 :          0 :         PyObject *res = m->sq_concat(s, o);
    1811                 :            :         assert(_Py_CheckSlotResult(s, "+", res != NULL));
    1812                 :          0 :         return res;
    1813                 :            :     }
    1814                 :            : 
    1815   [ #  #  #  # ]:          0 :     if (PySequence_Check(s) && PySequence_Check(o)) {
    1816                 :          0 :         PyObject *result = BINARY_IOP1(s, o, NB_SLOT(nb_inplace_add),
    1817                 :            :                                        NB_SLOT(nb_add), "+=");
    1818         [ #  # ]:          0 :         if (result != Py_NotImplemented)
    1819                 :          0 :             return result;
    1820                 :          0 :         Py_DECREF(result);
    1821                 :            :     }
    1822                 :          0 :     return type_error("'%.200s' object can't be concatenated", s);
    1823                 :            : }
    1824                 :            : 
    1825                 :            : PyObject *
    1826                 :          0 : PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
    1827                 :            : {
    1828         [ #  # ]:          0 :     if (o == NULL) {
    1829                 :          0 :         return null_error();
    1830                 :            :     }
    1831                 :            : 
    1832                 :          0 :     PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
    1833   [ #  #  #  # ]:          0 :     if (m && m->sq_inplace_repeat) {
    1834                 :          0 :         PyObject *res = m->sq_inplace_repeat(o, count);
    1835                 :            :         assert(_Py_CheckSlotResult(o, "*=", res != NULL));
    1836                 :          0 :         return res;
    1837                 :            :     }
    1838   [ #  #  #  # ]:          0 :     if (m && m->sq_repeat) {
    1839                 :          0 :         PyObject *res = m->sq_repeat(o, count);
    1840                 :            :         assert(_Py_CheckSlotResult(o, "*", res != NULL));
    1841                 :          0 :         return res;
    1842                 :            :     }
    1843                 :            : 
    1844         [ #  # ]:          0 :     if (PySequence_Check(o)) {
    1845                 :            :         PyObject *n, *result;
    1846                 :          0 :         n = PyLong_FromSsize_t(count);
    1847         [ #  # ]:          0 :         if (n == NULL)
    1848                 :          0 :             return NULL;
    1849                 :          0 :         result = BINARY_IOP1(o, n, NB_SLOT(nb_inplace_multiply),
    1850                 :            :                              NB_SLOT(nb_multiply), "*=");
    1851                 :          0 :         Py_DECREF(n);
    1852         [ #  # ]:          0 :         if (result != Py_NotImplemented)
    1853                 :          0 :             return result;
    1854                 :          0 :         Py_DECREF(result);
    1855                 :            :     }
    1856                 :          0 :     return type_error("'%.200s' object can't be repeated", o);
    1857                 :            : }
    1858                 :            : 
    1859                 :            : PyObject *
    1860                 :      16394 : PySequence_GetItem(PyObject *s, Py_ssize_t i)
    1861                 :            : {
    1862         [ -  + ]:      16394 :     if (s == NULL) {
    1863                 :          0 :         return null_error();
    1864                 :            :     }
    1865                 :            : 
    1866                 :      16394 :     PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence;
    1867   [ +  -  +  - ]:      16394 :     if (m && m->sq_item) {
    1868         [ -  + ]:      16394 :         if (i < 0) {
    1869         [ #  # ]:          0 :             if (m->sq_length) {
    1870                 :          0 :                 Py_ssize_t l = (*m->sq_length)(s);
    1871                 :            :                 assert(_Py_CheckSlotResult(s, "__len__", l >= 0));
    1872         [ #  # ]:          0 :                 if (l < 0) {
    1873                 :          0 :                     return NULL;
    1874                 :            :                 }
    1875                 :          0 :                 i += l;
    1876                 :            :             }
    1877                 :            :         }
    1878                 :      16394 :         PyObject *res = m->sq_item(s, i);
    1879                 :            :         assert(_Py_CheckSlotResult(s, "__getitem__", res != NULL));
    1880                 :      16394 :         return res;
    1881                 :            :     }
    1882                 :            : 
    1883   [ #  #  #  # ]:          0 :     if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_subscript) {
    1884                 :          0 :         return type_error("%.200s is not a sequence", s);
    1885                 :            :     }
    1886                 :          0 :     return type_error("'%.200s' object does not support indexing", s);
    1887                 :            : }
    1888                 :            : 
    1889                 :            : PyObject *
    1890                 :        775 : PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
    1891                 :            : {
    1892         [ -  + ]:        775 :     if (!s) {
    1893                 :          0 :         return null_error();
    1894                 :            :     }
    1895                 :            : 
    1896                 :        775 :     PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping;
    1897   [ +  -  +  - ]:        775 :     if (mp && mp->mp_subscript) {
    1898                 :        775 :         PyObject *slice = _PySlice_FromIndices(i1, i2);
    1899         [ -  + ]:        775 :         if (!slice) {
    1900                 :          0 :             return NULL;
    1901                 :            :         }
    1902                 :        775 :         PyObject *res = mp->mp_subscript(s, slice);
    1903                 :            :         assert(_Py_CheckSlotResult(s, "__getitem__", res != NULL));
    1904                 :        775 :         Py_DECREF(slice);
    1905                 :        775 :         return res;
    1906                 :            :     }
    1907                 :            : 
    1908                 :          0 :     return type_error("'%.200s' object is unsliceable", s);
    1909                 :            : }
    1910                 :            : 
    1911                 :            : int
    1912                 :          0 : PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o)
    1913                 :            : {
    1914         [ #  # ]:          0 :     if (s == NULL) {
    1915                 :          0 :         null_error();
    1916                 :          0 :         return -1;
    1917                 :            :     }
    1918                 :            : 
    1919                 :          0 :     PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence;
    1920   [ #  #  #  # ]:          0 :     if (m && m->sq_ass_item) {
    1921         [ #  # ]:          0 :         if (i < 0) {
    1922         [ #  # ]:          0 :             if (m->sq_length) {
    1923                 :          0 :                 Py_ssize_t l = (*m->sq_length)(s);
    1924                 :            :                 assert(_Py_CheckSlotResult(s, "__len__", l >= 0));
    1925         [ #  # ]:          0 :                 if (l < 0) {
    1926                 :          0 :                     return -1;
    1927                 :            :                 }
    1928                 :          0 :                 i += l;
    1929                 :            :             }
    1930                 :            :         }
    1931                 :          0 :         int res = m->sq_ass_item(s, i, o);
    1932                 :            :         assert(_Py_CheckSlotResult(s, "__setitem__", res >= 0));
    1933                 :          0 :         return res;
    1934                 :            :     }
    1935                 :            : 
    1936   [ #  #  #  # ]:          0 :     if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) {
    1937                 :          0 :         type_error("%.200s is not a sequence", s);
    1938                 :          0 :         return -1;
    1939                 :            :     }
    1940                 :          0 :     type_error("'%.200s' object does not support item assignment", s);
    1941                 :          0 :     return -1;
    1942                 :            : }
    1943                 :            : 
    1944                 :            : int
    1945                 :       7722 : PySequence_DelItem(PyObject *s, Py_ssize_t i)
    1946                 :            : {
    1947         [ -  + ]:       7722 :     if (s == NULL) {
    1948                 :          0 :         null_error();
    1949                 :          0 :         return -1;
    1950                 :            :     }
    1951                 :            : 
    1952                 :       7722 :     PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence;
    1953   [ +  -  +  - ]:       7722 :     if (m && m->sq_ass_item) {
    1954         [ -  + ]:       7722 :         if (i < 0) {
    1955         [ #  # ]:          0 :             if (m->sq_length) {
    1956                 :          0 :                 Py_ssize_t l = (*m->sq_length)(s);
    1957                 :            :                 assert(_Py_CheckSlotResult(s, "__len__", l >= 0));
    1958         [ #  # ]:          0 :                 if (l < 0) {
    1959                 :          0 :                     return -1;
    1960                 :            :                 }
    1961                 :          0 :                 i += l;
    1962                 :            :             }
    1963                 :            :         }
    1964                 :       7722 :         int res = m->sq_ass_item(s, i, (PyObject *)NULL);
    1965                 :            :         assert(_Py_CheckSlotResult(s, "__delitem__", res >= 0));
    1966                 :       7722 :         return res;
    1967                 :            :     }
    1968                 :            : 
    1969   [ #  #  #  # ]:          0 :     if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) {
    1970                 :          0 :         type_error("%.200s is not a sequence", s);
    1971                 :          0 :         return -1;
    1972                 :            :     }
    1973                 :          0 :     type_error("'%.200s' object doesn't support item deletion", s);
    1974                 :          0 :     return -1;
    1975                 :            : }
    1976                 :            : 
    1977                 :            : int
    1978                 :          0 : PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
    1979                 :            : {
    1980         [ #  # ]:          0 :     if (s == NULL) {
    1981                 :          0 :         null_error();
    1982                 :          0 :         return -1;
    1983                 :            :     }
    1984                 :            : 
    1985                 :          0 :     PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping;
    1986   [ #  #  #  # ]:          0 :     if (mp && mp->mp_ass_subscript) {
    1987                 :          0 :         PyObject *slice = _PySlice_FromIndices(i1, i2);
    1988         [ #  # ]:          0 :         if (!slice)
    1989                 :          0 :             return -1;
    1990                 :          0 :         int res = mp->mp_ass_subscript(s, slice, o);
    1991                 :            :         assert(_Py_CheckSlotResult(s, "__setitem__", res >= 0));
    1992                 :          0 :         Py_DECREF(slice);
    1993                 :          0 :         return res;
    1994                 :            :     }
    1995                 :            : 
    1996                 :          0 :     type_error("'%.200s' object doesn't support slice assignment", s);
    1997                 :          0 :     return -1;
    1998                 :            : }
    1999                 :            : 
    2000                 :            : int
    2001                 :          0 : PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
    2002                 :            : {
    2003         [ #  # ]:          0 :     if (s == NULL) {
    2004                 :          0 :         null_error();
    2005                 :          0 :         return -1;
    2006                 :            :     }
    2007                 :            : 
    2008                 :          0 :     PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping;
    2009   [ #  #  #  # ]:          0 :     if (mp && mp->mp_ass_subscript) {
    2010                 :          0 :         PyObject *slice = _PySlice_FromIndices(i1, i2);
    2011         [ #  # ]:          0 :         if (!slice) {
    2012                 :          0 :             return -1;
    2013                 :            :         }
    2014                 :          0 :         int res = mp->mp_ass_subscript(s, slice, NULL);
    2015                 :            :         assert(_Py_CheckSlotResult(s, "__delitem__", res >= 0));
    2016                 :          0 :         Py_DECREF(slice);
    2017                 :          0 :         return res;
    2018                 :            :     }
    2019                 :          0 :     type_error("'%.200s' object doesn't support slice deletion", s);
    2020                 :          0 :     return -1;
    2021                 :            : }
    2022                 :            : 
    2023                 :            : PyObject *
    2024                 :      25192 : PySequence_Tuple(PyObject *v)
    2025                 :            : {
    2026                 :            :     PyObject *it;  /* iter(v) */
    2027                 :            :     Py_ssize_t n;             /* guess for result tuple size */
    2028                 :      25192 :     PyObject *result = NULL;
    2029                 :            :     Py_ssize_t j;
    2030                 :            : 
    2031         [ -  + ]:      25192 :     if (v == NULL) {
    2032                 :          0 :         return null_error();
    2033                 :            :     }
    2034                 :            : 
    2035                 :            :     /* Special-case the common tuple and list cases, for efficiency. */
    2036         [ +  + ]:      25192 :     if (PyTuple_CheckExact(v)) {
    2037                 :            :         /* Note that we can't know whether it's safe to return
    2038                 :            :            a tuple *subclass* instance as-is, hence the restriction
    2039                 :            :            to exact tuples here.  In contrast, lists always make
    2040                 :            :            a copy, so there's no need for exactness below. */
    2041                 :      12746 :         return Py_NewRef(v);
    2042                 :            :     }
    2043         [ +  + ]:      12446 :     if (PyList_CheckExact(v))
    2044                 :       9341 :         return PyList_AsTuple(v);
    2045                 :            : 
    2046                 :            :     /* Get iterator. */
    2047                 :       3105 :     it = PyObject_GetIter(v);
    2048         [ +  + ]:       3105 :     if (it == NULL)
    2049                 :          1 :         return NULL;
    2050                 :            : 
    2051                 :            :     /* Guess result size and allocate space. */
    2052                 :       3104 :     n = PyObject_LengthHint(v, 10);
    2053         [ -  + ]:       3104 :     if (n == -1)
    2054                 :          0 :         goto Fail;
    2055                 :       3104 :     result = PyTuple_New(n);
    2056         [ -  + ]:       3104 :     if (result == NULL)
    2057                 :          0 :         goto Fail;
    2058                 :            : 
    2059                 :            :     /* Fill the tuple. */
    2060                 :     423109 :     for (j = 0; ; ++j) {
    2061                 :     423109 :         PyObject *item = PyIter_Next(it);
    2062         [ +  + ]:     423109 :         if (item == NULL) {
    2063         [ -  + ]:       3104 :             if (PyErr_Occurred())
    2064                 :          0 :                 goto Fail;
    2065                 :       3104 :             break;
    2066                 :            :         }
    2067         [ +  + ]:     420005 :         if (j >= n) {
    2068                 :        763 :             size_t newn = (size_t)n;
    2069                 :            :             /* The over-allocation strategy can grow a bit faster
    2070                 :            :                than for lists because unlike lists the
    2071                 :            :                over-allocation isn't permanent -- we reclaim
    2072                 :            :                the excess before the end of this routine.
    2073                 :            :                So, grow by ten and then add 25%.
    2074                 :            :             */
    2075                 :        763 :             newn += 10u;
    2076                 :        763 :             newn += newn >> 2;
    2077         [ -  + ]:        763 :             if (newn > PY_SSIZE_T_MAX) {
    2078                 :            :                 /* Check for overflow */
    2079                 :          0 :                 PyErr_NoMemory();
    2080                 :          0 :                 Py_DECREF(item);
    2081                 :          0 :                 goto Fail;
    2082                 :            :             }
    2083                 :        763 :             n = (Py_ssize_t)newn;
    2084         [ -  + ]:        763 :             if (_PyTuple_Resize(&result, n) != 0) {
    2085                 :          0 :                 Py_DECREF(item);
    2086                 :          0 :                 goto Fail;
    2087                 :            :             }
    2088                 :            :         }
    2089                 :     420005 :         PyTuple_SET_ITEM(result, j, item);
    2090                 :            :     }
    2091                 :            : 
    2092                 :            :     /* Cut tuple back if guess was too large. */
    2093   [ +  +  -  + ]:       5198 :     if (j < n &&
    2094                 :       2094 :         _PyTuple_Resize(&result, j) != 0)
    2095                 :          0 :         goto Fail;
    2096                 :            : 
    2097                 :       3104 :     Py_DECREF(it);
    2098                 :       3104 :     return result;
    2099                 :            : 
    2100                 :          0 : Fail:
    2101                 :          0 :     Py_XDECREF(result);
    2102                 :          0 :     Py_DECREF(it);
    2103                 :          0 :     return NULL;
    2104                 :            : }
    2105                 :            : 
    2106                 :            : PyObject *
    2107                 :      20546 : PySequence_List(PyObject *v)
    2108                 :            : {
    2109                 :            :     PyObject *result;  /* result list */
    2110                 :            :     PyObject *rv;          /* return value from PyList_Extend */
    2111                 :            : 
    2112         [ -  + ]:      20546 :     if (v == NULL) {
    2113                 :          0 :         return null_error();
    2114                 :            :     }
    2115                 :            : 
    2116                 :      20546 :     result = PyList_New(0);
    2117         [ -  + ]:      20546 :     if (result == NULL)
    2118                 :          0 :         return NULL;
    2119                 :            : 
    2120                 :      20546 :     rv = _PyList_Extend((PyListObject *)result, v);
    2121         [ -  + ]:      20546 :     if (rv == NULL) {
    2122                 :          0 :         Py_DECREF(result);
    2123                 :          0 :         return NULL;
    2124                 :            :     }
    2125                 :      20546 :     Py_DECREF(rv);
    2126                 :      20546 :     return result;
    2127                 :            : }
    2128                 :            : 
    2129                 :            : PyObject *
    2130                 :      57161 : PySequence_Fast(PyObject *v, const char *m)
    2131                 :            : {
    2132                 :            :     PyObject *it;
    2133                 :            : 
    2134         [ -  + ]:      57161 :     if (v == NULL) {
    2135                 :          0 :         return null_error();
    2136                 :            :     }
    2137                 :            : 
    2138   [ +  +  +  + ]:      57161 :     if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) {
    2139                 :      40603 :         return Py_NewRef(v);
    2140                 :            :     }
    2141                 :            : 
    2142                 :      16558 :     it = PyObject_GetIter(v);
    2143         [ -  + ]:      16558 :     if (it == NULL) {
    2144                 :          0 :         PyThreadState *tstate = _PyThreadState_GET();
    2145         [ #  # ]:          0 :         if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
    2146                 :          0 :             _PyErr_SetString(tstate, PyExc_TypeError, m);
    2147                 :            :         }
    2148                 :          0 :         return NULL;
    2149                 :            :     }
    2150                 :            : 
    2151                 :      16558 :     v = PySequence_List(it);
    2152                 :      16558 :     Py_DECREF(it);
    2153                 :            : 
    2154                 :      16558 :     return v;
    2155                 :            : }
    2156                 :            : 
    2157                 :            : /* Iterate over seq.  Result depends on the operation:
    2158                 :            :    PY_ITERSEARCH_COUNT:  -1 if error, else # of times obj appears in seq.
    2159                 :            :    PY_ITERSEARCH_INDEX:  0-based index of first occurrence of obj in seq;
    2160                 :            :     set ValueError and return -1 if none found; also return -1 on error.
    2161                 :            :    Py_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on error.
    2162                 :            : */
    2163                 :            : Py_ssize_t
    2164                 :          0 : _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
    2165                 :            : {
    2166                 :            :     Py_ssize_t n;
    2167                 :            :     int wrapped;  /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */
    2168                 :            :     PyObject *it;  /* iter(seq) */
    2169                 :            : 
    2170   [ #  #  #  # ]:          0 :     if (seq == NULL || obj == NULL) {
    2171                 :          0 :         null_error();
    2172                 :          0 :         return -1;
    2173                 :            :     }
    2174                 :            : 
    2175                 :          0 :     it = PyObject_GetIter(seq);
    2176         [ #  # ]:          0 :     if (it == NULL) {
    2177         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
    2178                 :          0 :             type_error("argument of type '%.200s' is not iterable", seq);
    2179                 :            :         }
    2180                 :          0 :         return -1;
    2181                 :            :     }
    2182                 :            : 
    2183                 :          0 :     n = wrapped = 0;
    2184                 :          0 :     for (;;) {
    2185                 :            :         int cmp;
    2186                 :          0 :         PyObject *item = PyIter_Next(it);
    2187         [ #  # ]:          0 :         if (item == NULL) {
    2188         [ #  # ]:          0 :             if (PyErr_Occurred())
    2189                 :          0 :                 goto Fail;
    2190                 :          0 :             break;
    2191                 :            :         }
    2192                 :            : 
    2193                 :          0 :         cmp = PyObject_RichCompareBool(item, obj, Py_EQ);
    2194                 :          0 :         Py_DECREF(item);
    2195         [ #  # ]:          0 :         if (cmp < 0)
    2196                 :          0 :             goto Fail;
    2197         [ #  # ]:          0 :         if (cmp > 0) {
    2198   [ #  #  #  # ]:          0 :             switch (operation) {
    2199                 :          0 :             case PY_ITERSEARCH_COUNT:
    2200         [ #  # ]:          0 :                 if (n == PY_SSIZE_T_MAX) {
    2201                 :          0 :                     PyErr_SetString(PyExc_OverflowError,
    2202                 :            :                            "count exceeds C integer size");
    2203                 :          0 :                     goto Fail;
    2204                 :            :                 }
    2205                 :          0 :                 ++n;
    2206                 :          0 :                 break;
    2207                 :            : 
    2208                 :          0 :             case PY_ITERSEARCH_INDEX:
    2209         [ #  # ]:          0 :                 if (wrapped) {
    2210                 :          0 :                     PyErr_SetString(PyExc_OverflowError,
    2211                 :            :                            "index exceeds C integer size");
    2212                 :          0 :                     goto Fail;
    2213                 :            :                 }
    2214                 :          0 :                 goto Done;
    2215                 :            : 
    2216                 :          0 :             case PY_ITERSEARCH_CONTAINS:
    2217                 :          0 :                 n = 1;
    2218                 :          0 :                 goto Done;
    2219                 :            : 
    2220                 :          0 :             default:
    2221                 :          0 :                 Py_UNREACHABLE();
    2222                 :            :             }
    2223                 :          0 :         }
    2224                 :            : 
    2225         [ #  # ]:          0 :         if (operation == PY_ITERSEARCH_INDEX) {
    2226         [ #  # ]:          0 :             if (n == PY_SSIZE_T_MAX)
    2227                 :          0 :                 wrapped = 1;
    2228                 :          0 :             ++n;
    2229                 :            :         }
    2230                 :            :     }
    2231                 :            : 
    2232         [ #  # ]:          0 :     if (operation != PY_ITERSEARCH_INDEX)
    2233                 :          0 :         goto Done;
    2234                 :            : 
    2235                 :          0 :     PyErr_SetString(PyExc_ValueError,
    2236                 :            :                     "sequence.index(x): x not in sequence");
    2237                 :            :     /* fall into failure code */
    2238                 :          0 : Fail:
    2239                 :          0 :     n = -1;
    2240                 :            :     /* fall through */
    2241                 :          0 : Done:
    2242                 :          0 :     Py_DECREF(it);
    2243                 :          0 :     return n;
    2244                 :            : 
    2245                 :            : }
    2246                 :            : 
    2247                 :            : /* Return # of times o appears in s. */
    2248                 :            : Py_ssize_t
    2249                 :          0 : PySequence_Count(PyObject *s, PyObject *o)
    2250                 :            : {
    2251                 :          0 :     return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT);
    2252                 :            : }
    2253                 :            : 
    2254                 :            : /* Return -1 if error; 1 if ob in seq; 0 if ob not in seq.
    2255                 :            :  * Use sq_contains if possible, else defer to _PySequence_IterSearch().
    2256                 :            :  */
    2257                 :            : int
    2258                 :      71080 : PySequence_Contains(PyObject *seq, PyObject *ob)
    2259                 :            : {
    2260                 :      71080 :     PySequenceMethods *sqm = Py_TYPE(seq)->tp_as_sequence;
    2261   [ +  -  +  - ]:      71080 :     if (sqm != NULL && sqm->sq_contains != NULL) {
    2262                 :      71080 :         int res = (*sqm->sq_contains)(seq, ob);
    2263                 :            :         assert(_Py_CheckSlotResult(seq, "__contains__", res >= 0));
    2264                 :      71080 :         return res;
    2265                 :            :     }
    2266                 :          0 :     Py_ssize_t result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
    2267                 :          0 :     return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
    2268                 :            : }
    2269                 :            : 
    2270                 :            : /* Backwards compatibility */
    2271                 :            : #undef PySequence_In
    2272                 :            : int
    2273                 :          0 : PySequence_In(PyObject *w, PyObject *v)
    2274                 :            : {
    2275                 :          0 :     return PySequence_Contains(w, v);
    2276                 :            : }
    2277                 :            : 
    2278                 :            : Py_ssize_t
    2279                 :          0 : PySequence_Index(PyObject *s, PyObject *o)
    2280                 :            : {
    2281                 :          0 :     return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX);
    2282                 :            : }
    2283                 :            : 
    2284                 :            : /* Operations on mappings */
    2285                 :            : 
    2286                 :            : int
    2287                 :       8390 : PyMapping_Check(PyObject *o)
    2288                 :            : {
    2289   [ +  -  +  + ]:      16776 :     return o && Py_TYPE(o)->tp_as_mapping &&
    2290         [ +  - ]:       8386 :         Py_TYPE(o)->tp_as_mapping->mp_subscript;
    2291                 :            : }
    2292                 :            : 
    2293                 :            : Py_ssize_t
    2294                 :        374 : PyMapping_Size(PyObject *o)
    2295                 :            : {
    2296         [ -  + ]:        374 :     if (o == NULL) {
    2297                 :          0 :         null_error();
    2298                 :          0 :         return -1;
    2299                 :            :     }
    2300                 :            : 
    2301                 :        374 :     PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping;
    2302   [ +  -  +  - ]:        374 :     if (m && m->mp_length) {
    2303                 :        374 :         Py_ssize_t len = m->mp_length(o);
    2304                 :            :         assert(_Py_CheckSlotResult(o, "__len__", len >= 0));
    2305                 :        374 :         return len;
    2306                 :            :     }
    2307                 :            : 
    2308   [ #  #  #  # ]:          0 :     if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) {
    2309                 :          0 :         type_error("%.200s is not a mapping", o);
    2310                 :          0 :         return -1;
    2311                 :            :     }
    2312                 :            :     /* PyMapping_Size() can be called from PyObject_Size(). */
    2313                 :          0 :     type_error("object of type '%.200s' has no len()", o);
    2314                 :          0 :     return -1;
    2315                 :            : }
    2316                 :            : 
    2317                 :            : #undef PyMapping_Length
    2318                 :            : Py_ssize_t
    2319                 :          0 : PyMapping_Length(PyObject *o)
    2320                 :            : {
    2321                 :          0 :     return PyMapping_Size(o);
    2322                 :            : }
    2323                 :            : #define PyMapping_Length PyMapping_Size
    2324                 :            : 
    2325                 :            : PyObject *
    2326                 :        120 : PyMapping_GetItemString(PyObject *o, const char *key)
    2327                 :            : {
    2328                 :            :     PyObject *okey, *r;
    2329                 :            : 
    2330         [ -  + ]:        120 :     if (key == NULL) {
    2331                 :          0 :         return null_error();
    2332                 :            :     }
    2333                 :            : 
    2334                 :        120 :     okey = PyUnicode_FromString(key);
    2335         [ -  + ]:        120 :     if (okey == NULL)
    2336                 :          0 :         return NULL;
    2337                 :        120 :     r = PyObject_GetItem(o, okey);
    2338                 :        120 :     Py_DECREF(okey);
    2339                 :        120 :     return r;
    2340                 :            : }
    2341                 :            : 
    2342                 :            : int
    2343                 :         40 : PyMapping_SetItemString(PyObject *o, const char *key, PyObject *value)
    2344                 :            : {
    2345                 :            :     PyObject *okey;
    2346                 :            :     int r;
    2347                 :            : 
    2348         [ -  + ]:         40 :     if (key == NULL) {
    2349                 :          0 :         null_error();
    2350                 :          0 :         return -1;
    2351                 :            :     }
    2352                 :            : 
    2353                 :         40 :     okey = PyUnicode_FromString(key);
    2354         [ -  + ]:         40 :     if (okey == NULL)
    2355                 :          0 :         return -1;
    2356                 :         40 :     r = PyObject_SetItem(o, okey, value);
    2357                 :         40 :     Py_DECREF(okey);
    2358                 :         40 :     return r;
    2359                 :            : }
    2360                 :            : 
    2361                 :            : int
    2362                 :          0 : PyMapping_HasKeyString(PyObject *o, const char *key)
    2363                 :            : {
    2364                 :            :     PyObject *v;
    2365                 :            : 
    2366                 :          0 :     v = PyMapping_GetItemString(o, key);
    2367         [ #  # ]:          0 :     if (v) {
    2368                 :          0 :         Py_DECREF(v);
    2369                 :          0 :         return 1;
    2370                 :            :     }
    2371                 :          0 :     PyErr_Clear();
    2372                 :          0 :     return 0;
    2373                 :            : }
    2374                 :            : 
    2375                 :            : int
    2376                 :          0 : PyMapping_HasKey(PyObject *o, PyObject *key)
    2377                 :            : {
    2378                 :            :     PyObject *v;
    2379                 :            : 
    2380                 :          0 :     v = PyObject_GetItem(o, key);
    2381         [ #  # ]:          0 :     if (v) {
    2382                 :          0 :         Py_DECREF(v);
    2383                 :          0 :         return 1;
    2384                 :            :     }
    2385                 :          0 :     PyErr_Clear();
    2386                 :          0 :     return 0;
    2387                 :            : }
    2388                 :            : 
    2389                 :            : /* This function is quite similar to PySequence_Fast(), but specialized to be
    2390                 :            :    a helper for PyMapping_Keys(), PyMapping_Items() and PyMapping_Values().
    2391                 :            :  */
    2392                 :            : static PyObject *
    2393                 :       1031 : method_output_as_list(PyObject *o, PyObject *meth)
    2394                 :            : {
    2395                 :            :     PyObject *it, *result, *meth_output;
    2396                 :            : 
    2397                 :            :     assert(o != NULL);
    2398                 :       1031 :     meth_output = PyObject_CallMethodNoArgs(o, meth);
    2399   [ +  -  -  + ]:       1031 :     if (meth_output == NULL || PyList_CheckExact(meth_output)) {
    2400                 :          0 :         return meth_output;
    2401                 :            :     }
    2402                 :       1031 :     it = PyObject_GetIter(meth_output);
    2403         [ -  + ]:       1031 :     if (it == NULL) {
    2404                 :          0 :         PyThreadState *tstate = _PyThreadState_GET();
    2405         [ #  # ]:          0 :         if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
    2406                 :          0 :             _PyErr_Format(tstate, PyExc_TypeError,
    2407                 :            :                           "%.200s.%U() returned a non-iterable (type %.200s)",
    2408                 :          0 :                           Py_TYPE(o)->tp_name,
    2409                 :            :                           meth,
    2410                 :          0 :                           Py_TYPE(meth_output)->tp_name);
    2411                 :            :         }
    2412                 :          0 :         Py_DECREF(meth_output);
    2413                 :          0 :         return NULL;
    2414                 :            :     }
    2415                 :       1031 :     Py_DECREF(meth_output);
    2416                 :       1031 :     result = PySequence_List(it);
    2417                 :       1031 :     Py_DECREF(it);
    2418                 :       1031 :     return result;
    2419                 :            : }
    2420                 :            : 
    2421                 :            : PyObject *
    2422                 :        178 : PyMapping_Keys(PyObject *o)
    2423                 :            : {
    2424         [ -  + ]:        178 :     if (o == NULL) {
    2425                 :          0 :         return null_error();
    2426                 :            :     }
    2427         [ +  + ]:        178 :     if (PyDict_CheckExact(o)) {
    2428                 :        109 :         return PyDict_Keys(o);
    2429                 :            :     }
    2430                 :         69 :     return method_output_as_list(o, &_Py_ID(keys));
    2431                 :            : }
    2432                 :            : 
    2433                 :            : PyObject *
    2434                 :        962 : PyMapping_Items(PyObject *o)
    2435                 :            : {
    2436         [ -  + ]:        962 :     if (o == NULL) {
    2437                 :          0 :         return null_error();
    2438                 :            :     }
    2439         [ -  + ]:        962 :     if (PyDict_CheckExact(o)) {
    2440                 :          0 :         return PyDict_Items(o);
    2441                 :            :     }
    2442                 :        962 :     return method_output_as_list(o, &_Py_ID(items));
    2443                 :            : }
    2444                 :            : 
    2445                 :            : PyObject *
    2446                 :          0 : PyMapping_Values(PyObject *o)
    2447                 :            : {
    2448         [ #  # ]:          0 :     if (o == NULL) {
    2449                 :          0 :         return null_error();
    2450                 :            :     }
    2451         [ #  # ]:          0 :     if (PyDict_CheckExact(o)) {
    2452                 :          0 :         return PyDict_Values(o);
    2453                 :            :     }
    2454                 :          0 :     return method_output_as_list(o, &_Py_ID(values));
    2455                 :            : }
    2456                 :            : 
    2457                 :            : /* isinstance(), issubclass() */
    2458                 :            : 
    2459                 :            : /* abstract_get_bases() has logically 4 return states:
    2460                 :            :  *
    2461                 :            :  * 1. getattr(cls, '__bases__') could raise an AttributeError
    2462                 :            :  * 2. getattr(cls, '__bases__') could raise some other exception
    2463                 :            :  * 3. getattr(cls, '__bases__') could return a tuple
    2464                 :            :  * 4. getattr(cls, '__bases__') could return something other than a tuple
    2465                 :            :  *
    2466                 :            :  * Only state #3 is a non-error state and only it returns a non-NULL object
    2467                 :            :  * (it returns the retrieved tuple).
    2468                 :            :  *
    2469                 :            :  * Any raised AttributeErrors are masked by clearing the exception and
    2470                 :            :  * returning NULL.  If an object other than a tuple comes out of __bases__,
    2471                 :            :  * then again, the return value is NULL.  So yes, these two situations
    2472                 :            :  * produce exactly the same results: NULL is returned and no error is set.
    2473                 :            :  *
    2474                 :            :  * If some exception other than AttributeError is raised, then NULL is also
    2475                 :            :  * returned, but the exception is not cleared.  That's because we want the
    2476                 :            :  * exception to be propagated along.
    2477                 :            :  *
    2478                 :            :  * Callers are expected to test for PyErr_Occurred() when the return value
    2479                 :            :  * is NULL to decide whether a valid exception should be propagated or not.
    2480                 :            :  * When there's no exception to propagate, it's customary for the caller to
    2481                 :            :  * set a TypeError.
    2482                 :            :  */
    2483                 :            : static PyObject *
    2484                 :          0 : abstract_get_bases(PyObject *cls)
    2485                 :            : {
    2486                 :            :     PyObject *bases;
    2487                 :            : 
    2488                 :          0 :     (void)_PyObject_LookupAttr(cls, &_Py_ID(__bases__), &bases);
    2489   [ #  #  #  # ]:          0 :     if (bases != NULL && !PyTuple_Check(bases)) {
    2490                 :          0 :         Py_DECREF(bases);
    2491                 :          0 :         return NULL;
    2492                 :            :     }
    2493                 :          0 :     return bases;
    2494                 :            : }
    2495                 :            : 
    2496                 :            : 
    2497                 :            : static int
    2498                 :          0 : abstract_issubclass(PyObject *derived, PyObject *cls)
    2499                 :            : {
    2500                 :          0 :     PyObject *bases = NULL;
    2501                 :            :     Py_ssize_t i, n;
    2502                 :          0 :     int r = 0;
    2503                 :            : 
    2504                 :            :     while (1) {
    2505         [ #  # ]:          0 :         if (derived == cls) {
    2506                 :          0 :             Py_XDECREF(bases); /* See below comment */
    2507                 :          0 :             return 1;
    2508                 :            :         }
    2509                 :            :         /* Use XSETREF to drop bases reference *after* finishing with
    2510                 :            :            derived; bases might be the only reference to it.
    2511                 :            :            XSETREF is used instead of SETREF, because bases is NULL on the
    2512                 :            :            first iteration of the loop.
    2513                 :            :         */
    2514                 :          0 :         Py_XSETREF(bases, abstract_get_bases(derived));
    2515         [ #  # ]:          0 :         if (bases == NULL) {
    2516         [ #  # ]:          0 :             if (PyErr_Occurred())
    2517                 :          0 :                 return -1;
    2518                 :          0 :             return 0;
    2519                 :            :         }
    2520                 :          0 :         n = PyTuple_GET_SIZE(bases);
    2521         [ #  # ]:          0 :         if (n == 0) {
    2522                 :          0 :             Py_DECREF(bases);
    2523                 :          0 :             return 0;
    2524                 :            :         }
    2525                 :            :         /* Avoid recursivity in the single inheritance case */
    2526         [ #  # ]:          0 :         if (n == 1) {
    2527                 :          0 :             derived = PyTuple_GET_ITEM(bases, 0);
    2528                 :          0 :             continue;
    2529                 :            :         }
    2530                 :          0 :         break;
    2531                 :            :     }
    2532                 :            :     assert(n >= 2);
    2533         [ #  # ]:          0 :     if (_Py_EnterRecursiveCall(" in __issubclass__")) {
    2534                 :          0 :         Py_DECREF(bases);
    2535                 :          0 :         return -1;
    2536                 :            :     }
    2537         [ #  # ]:          0 :     for (i = 0; i < n; i++) {
    2538                 :          0 :         r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
    2539         [ #  # ]:          0 :         if (r != 0) {
    2540                 :          0 :             break;
    2541                 :            :         }
    2542                 :            :     }
    2543                 :          0 :     _Py_LeaveRecursiveCall();
    2544                 :          0 :     Py_DECREF(bases);
    2545                 :          0 :     return r;
    2546                 :            : }
    2547                 :            : 
    2548                 :            : static int
    2549                 :          0 : check_class(PyObject *cls, const char *error)
    2550                 :            : {
    2551                 :          0 :     PyObject *bases = abstract_get_bases(cls);
    2552         [ #  # ]:          0 :     if (bases == NULL) {
    2553                 :            :         /* Do not mask errors. */
    2554                 :          0 :         PyThreadState *tstate = _PyThreadState_GET();
    2555         [ #  # ]:          0 :         if (!_PyErr_Occurred(tstate)) {
    2556                 :          0 :             _PyErr_SetString(tstate, PyExc_TypeError, error);
    2557                 :            :         }
    2558                 :          0 :         return 0;
    2559                 :            :     }
    2560                 :          0 :     Py_DECREF(bases);
    2561                 :          0 :     return -1;
    2562                 :            : }
    2563                 :            : 
    2564                 :            : static int
    2565                 :      36972 : object_isinstance(PyObject *inst, PyObject *cls)
    2566                 :            : {
    2567                 :            :     PyObject *icls;
    2568                 :            :     int retval;
    2569         [ +  - ]:      36972 :     if (PyType_Check(cls)) {
    2570                 :      36972 :         retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
    2571         [ +  + ]:      36972 :         if (retval == 0) {
    2572                 :      36252 :             retval = _PyObject_LookupAttr(inst, &_Py_ID(__class__), &icls);
    2573         [ +  - ]:      36252 :             if (icls != NULL) {
    2574   [ -  +  -  - ]:      36252 :                 if (icls != (PyObject *)(Py_TYPE(inst)) && PyType_Check(icls)) {
    2575                 :          0 :                     retval = PyType_IsSubtype(
    2576                 :            :                         (PyTypeObject *)icls,
    2577                 :            :                         (PyTypeObject *)cls);
    2578                 :            :                 }
    2579                 :            :                 else {
    2580                 :      36252 :                     retval = 0;
    2581                 :            :                 }
    2582                 :      36252 :                 Py_DECREF(icls);
    2583                 :            :             }
    2584                 :            :         }
    2585                 :            :     }
    2586                 :            :     else {
    2587         [ #  # ]:          0 :         if (!check_class(cls,
    2588                 :            :             "isinstance() arg 2 must be a type, a tuple of types, or a union"))
    2589                 :          0 :             return -1;
    2590                 :          0 :         retval = _PyObject_LookupAttr(inst, &_Py_ID(__class__), &icls);
    2591         [ #  # ]:          0 :         if (icls != NULL) {
    2592                 :          0 :             retval = abstract_issubclass(icls, cls);
    2593                 :          0 :             Py_DECREF(icls);
    2594                 :            :         }
    2595                 :            :     }
    2596                 :            : 
    2597                 :      36972 :     return retval;
    2598                 :            : }
    2599                 :            : 
    2600                 :            : static int
    2601                 :     633245 : object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls)
    2602                 :            : {
    2603                 :            :     /* Quick test for an exact match */
    2604         [ +  + ]:     633245 :     if (Py_IS_TYPE(inst, (PyTypeObject *)cls)) {
    2605                 :     488792 :         return 1;
    2606                 :            :     }
    2607                 :            : 
    2608                 :            :     /* We know what type's __instancecheck__ does. */
    2609         [ +  + ]:     144453 :     if (PyType_CheckExact(cls)) {
    2610                 :      30829 :         return object_isinstance(inst, cls);
    2611                 :            :     }
    2612                 :            : 
    2613         [ -  + ]:     113624 :     if (_PyUnion_Check(cls)) {
    2614                 :          0 :         cls = _Py_union_args(cls);
    2615                 :            :     }
    2616                 :            : 
    2617         [ +  + ]:     113624 :     if (PyTuple_Check(cls)) {
    2618                 :            :         /* Not a general sequence -- that opens up the road to
    2619                 :            :            recursion and stack overflow. */
    2620         [ -  + ]:      37228 :         if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) {
    2621                 :          0 :             return -1;
    2622                 :            :         }
    2623                 :      37228 :         Py_ssize_t n = PyTuple_GET_SIZE(cls);
    2624                 :      37228 :         int r = 0;
    2625         [ +  + ]:      50105 :         for (Py_ssize_t i = 0; i < n; ++i) {
    2626                 :      44058 :             PyObject *item = PyTuple_GET_ITEM(cls, i);
    2627                 :      44058 :             r = object_recursive_isinstance(tstate, inst, item);
    2628         [ +  + ]:      44058 :             if (r != 0) {
    2629                 :            :                 /* either found it, or got an error */
    2630                 :      31181 :                 break;
    2631                 :            :             }
    2632                 :            :         }
    2633                 :      37228 :         _Py_LeaveRecursiveCallTstate(tstate);
    2634                 :      37228 :         return r;
    2635                 :            :     }
    2636                 :            : 
    2637                 :      76396 :     PyObject *checker = _PyObject_LookupSpecial(cls, &_Py_ID(__instancecheck__));
    2638         [ +  - ]:      76396 :     if (checker != NULL) {
    2639         [ -  + ]:      76396 :         if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) {
    2640                 :          0 :             Py_DECREF(checker);
    2641                 :          0 :             return -1;
    2642                 :            :         }
    2643                 :            : 
    2644                 :      76396 :         PyObject *res = PyObject_CallOneArg(checker, inst);
    2645                 :      76396 :         _Py_LeaveRecursiveCallTstate(tstate);
    2646                 :      76396 :         Py_DECREF(checker);
    2647                 :            : 
    2648         [ -  + ]:      76396 :         if (res == NULL) {
    2649                 :          0 :             return -1;
    2650                 :            :         }
    2651                 :      76396 :         int ok = PyObject_IsTrue(res);
    2652                 :      76396 :         Py_DECREF(res);
    2653                 :            : 
    2654                 :      76396 :         return ok;
    2655                 :            :     }
    2656         [ #  # ]:          0 :     else if (_PyErr_Occurred(tstate)) {
    2657                 :          0 :         return -1;
    2658                 :            :     }
    2659                 :            : 
    2660                 :            :     /* cls has no __instancecheck__() method */
    2661                 :          0 :     return object_isinstance(inst, cls);
    2662                 :            : }
    2663                 :            : 
    2664                 :            : 
    2665                 :            : int
    2666                 :     589187 : PyObject_IsInstance(PyObject *inst, PyObject *cls)
    2667                 :            : {
    2668                 :     589187 :     PyThreadState *tstate = _PyThreadState_GET();
    2669                 :     589187 :     return object_recursive_isinstance(tstate, inst, cls);
    2670                 :            : }
    2671                 :            : 
    2672                 :            : 
    2673                 :            : static  int
    2674                 :      17673 : recursive_issubclass(PyObject *derived, PyObject *cls)
    2675                 :            : {
    2676   [ +  -  +  - ]:      17673 :     if (PyType_Check(cls) && PyType_Check(derived)) {
    2677                 :            :         /* Fast path (non-recursive) */
    2678                 :      17673 :         return PyType_IsSubtype((PyTypeObject *)derived, (PyTypeObject *)cls);
    2679                 :            :     }
    2680         [ #  # ]:          0 :     if (!check_class(derived,
    2681                 :            :                      "issubclass() arg 1 must be a class"))
    2682                 :          0 :         return -1;
    2683                 :            : 
    2684   [ #  #  #  # ]:          0 :     if (!_PyUnion_Check(cls) && !check_class(cls,
    2685                 :            :                             "issubclass() arg 2 must be a class,"
    2686                 :            :                             " a tuple of classes, or a union")) {
    2687                 :          0 :         return -1;
    2688                 :            :     }
    2689                 :            : 
    2690                 :          0 :     return abstract_issubclass(derived, cls);
    2691                 :            : }
    2692                 :            : 
    2693                 :            : static int
    2694                 :       5687 : object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
    2695                 :            : {
    2696                 :            :     PyObject *checker;
    2697                 :            : 
    2698                 :            :     /* We know what type's __subclasscheck__ does. */
    2699         [ +  + ]:       5687 :     if (PyType_CheckExact(cls)) {
    2700                 :            :         /* Quick test for an exact match */
    2701         [ +  + ]:       4090 :         if (derived == cls)
    2702                 :       2615 :             return 1;
    2703                 :       1475 :         return recursive_issubclass(derived, cls);
    2704                 :            :     }
    2705                 :            : 
    2706         [ -  + ]:       1597 :     if (_PyUnion_Check(cls)) {
    2707                 :          0 :         cls = _Py_union_args(cls);
    2708                 :            :     }
    2709                 :            : 
    2710         [ +  + ]:       1597 :     if (PyTuple_Check(cls)) {
    2711                 :            : 
    2712         [ -  + ]:         21 :         if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) {
    2713                 :          0 :             return -1;
    2714                 :            :         }
    2715                 :         21 :         Py_ssize_t n = PyTuple_GET_SIZE(cls);
    2716                 :         21 :         int r = 0;
    2717         [ +  + ]:         60 :         for (Py_ssize_t i = 0; i < n; ++i) {
    2718                 :         42 :             PyObject *item = PyTuple_GET_ITEM(cls, i);
    2719                 :         42 :             r = object_issubclass(tstate, derived, item);
    2720         [ +  + ]:         42 :             if (r != 0)
    2721                 :            :                 /* either found it, or got an error */
    2722                 :          3 :                 break;
    2723                 :            :         }
    2724                 :         21 :         _Py_LeaveRecursiveCallTstate(tstate);
    2725                 :         21 :         return r;
    2726                 :            :     }
    2727                 :            : 
    2728                 :       1576 :     checker = _PyObject_LookupSpecial(cls, &_Py_ID(__subclasscheck__));
    2729         [ +  - ]:       1576 :     if (checker != NULL) {
    2730                 :       1576 :         int ok = -1;
    2731         [ -  + ]:       1576 :         if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) {
    2732                 :          0 :             Py_DECREF(checker);
    2733                 :          0 :             return ok;
    2734                 :            :         }
    2735                 :       1576 :         PyObject *res = PyObject_CallOneArg(checker, derived);
    2736                 :       1576 :         _Py_LeaveRecursiveCallTstate(tstate);
    2737                 :       1576 :         Py_DECREF(checker);
    2738         [ +  - ]:       1576 :         if (res != NULL) {
    2739                 :       1576 :             ok = PyObject_IsTrue(res);
    2740                 :       1576 :             Py_DECREF(res);
    2741                 :            :         }
    2742                 :       1576 :         return ok;
    2743                 :            :     }
    2744         [ #  # ]:          0 :     else if (_PyErr_Occurred(tstate)) {
    2745                 :          0 :         return -1;
    2746                 :            :     }
    2747                 :            : 
    2748                 :            :     /* Probably never reached anymore. */
    2749                 :          0 :     return recursive_issubclass(derived, cls);
    2750                 :            : }
    2751                 :            : 
    2752                 :            : 
    2753                 :            : int
    2754                 :       5645 : PyObject_IsSubclass(PyObject *derived, PyObject *cls)
    2755                 :            : {
    2756                 :       5645 :     PyThreadState *tstate = _PyThreadState_GET();
    2757                 :       5645 :     return object_issubclass(tstate, derived, cls);
    2758                 :            : }
    2759                 :            : 
    2760                 :            : 
    2761                 :            : int
    2762                 :       6143 : _PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
    2763                 :            : {
    2764                 :       6143 :     return object_isinstance(inst, cls);
    2765                 :            : }
    2766                 :            : 
    2767                 :            : int
    2768                 :      16198 : _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls)
    2769                 :            : {
    2770                 :      16198 :     return recursive_issubclass(derived, cls);
    2771                 :            : }
    2772                 :            : 
    2773                 :            : 
    2774                 :            : PyObject *
    2775                 :    2499224 : PyObject_GetIter(PyObject *o)
    2776                 :            : {
    2777                 :    2499224 :     PyTypeObject *t = Py_TYPE(o);
    2778                 :            :     getiterfunc f;
    2779                 :            : 
    2780                 :    2499224 :     f = t->tp_iter;
    2781         [ +  + ]:    2499224 :     if (f == NULL) {
    2782         [ +  + ]:        609 :         if (PySequence_Check(o))
    2783                 :        527 :             return PySeqIter_New(o);
    2784                 :         82 :         return type_error("'%.200s' object is not iterable", o);
    2785                 :            :     }
    2786                 :            :     else {
    2787                 :    2498615 :         PyObject *res = (*f)(o);
    2788   [ +  -  -  + ]:    2498615 :         if (res != NULL && !PyIter_Check(res)) {
    2789                 :          0 :             PyErr_Format(PyExc_TypeError,
    2790                 :            :                          "iter() returned non-iterator "
    2791                 :            :                          "of type '%.100s'",
    2792                 :          0 :                          Py_TYPE(res)->tp_name);
    2793                 :          0 :             Py_SETREF(res, NULL);
    2794                 :            :         }
    2795                 :    2498615 :         return res;
    2796                 :            :     }
    2797                 :            : }
    2798                 :            : 
    2799                 :            : PyObject *
    2800                 :          0 : PyObject_GetAIter(PyObject *o) {
    2801                 :          0 :     PyTypeObject *t = Py_TYPE(o);
    2802                 :            :     unaryfunc f;
    2803                 :            : 
    2804   [ #  #  #  # ]:          0 :     if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) {
    2805                 :          0 :         return type_error("'%.200s' object is not an async iterable", o);
    2806                 :            :     }
    2807                 :          0 :     f = t->tp_as_async->am_aiter;
    2808                 :          0 :     PyObject *it = (*f)(o);
    2809   [ #  #  #  # ]:          0 :     if (it != NULL && !PyAIter_Check(it)) {
    2810                 :          0 :         PyErr_Format(PyExc_TypeError,
    2811                 :            :                      "aiter() returned not an async iterator of type '%.100s'",
    2812                 :          0 :                      Py_TYPE(it)->tp_name);
    2813                 :          0 :         Py_SETREF(it, NULL);
    2814                 :            :     }
    2815                 :          0 :     return it;
    2816                 :            : }
    2817                 :            : 
    2818                 :            : int
    2819                 :    2695476 : PyIter_Check(PyObject *obj)
    2820                 :            : {
    2821                 :    2695476 :     PyTypeObject *tp = Py_TYPE(obj);
    2822         [ +  - ]:    5390952 :     return (tp->tp_iternext != NULL &&
    2823         [ +  - ]:    2695476 :             tp->tp_iternext != &_PyObject_NextNotImplemented);
    2824                 :            : }
    2825                 :            : 
    2826                 :            : int
    2827                 :          0 : PyAIter_Check(PyObject *obj)
    2828                 :            : {
    2829                 :          0 :     PyTypeObject *tp = Py_TYPE(obj);
    2830                 :          0 :     return (tp->tp_as_async != NULL &&
    2831   [ #  #  #  # ]:          0 :             tp->tp_as_async->am_anext != NULL &&
    2832         [ #  # ]:          0 :             tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented);
    2833                 :            : }
    2834                 :            : 
    2835                 :            : /* Return next item.
    2836                 :            :  * If an error occurs, return NULL.  PyErr_Occurred() will be true.
    2837                 :            :  * If the iteration terminates normally, return NULL and clear the
    2838                 :            :  * PyExc_StopIteration exception (if it was set).  PyErr_Occurred()
    2839                 :            :  * will be false.
    2840                 :            :  * Else return the next object.  PyErr_Occurred() will be false.
    2841                 :            :  */
    2842                 :            : PyObject *
    2843                 :    1702468 : PyIter_Next(PyObject *iter)
    2844                 :            : {
    2845                 :            :     PyObject *result;
    2846                 :    1702468 :     result = (*Py_TYPE(iter)->tp_iternext)(iter);
    2847         [ +  + ]:    1702468 :     if (result == NULL) {
    2848                 :     276009 :         PyThreadState *tstate = _PyThreadState_GET();
    2849         [ -  + ]:     276009 :         if (_PyErr_Occurred(tstate)
    2850         [ #  # ]:          0 :             && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration))
    2851                 :            :         {
    2852                 :          0 :             _PyErr_Clear(tstate);
    2853                 :            :         }
    2854                 :            :     }
    2855                 :    1702468 :     return result;
    2856                 :            : }
    2857                 :            : 
    2858                 :            : PySendResult
    2859                 :          0 : PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result)
    2860                 :            : {
    2861                 :            :     assert(arg != NULL);
    2862                 :            :     assert(result != NULL);
    2863   [ #  #  #  # ]:          0 :     if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) {
    2864                 :          0 :         PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result);
    2865                 :            :         assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR));
    2866                 :          0 :         return res;
    2867                 :            :     }
    2868   [ #  #  #  # ]:          0 :     if (arg == Py_None && PyIter_Check(iter)) {
    2869                 :          0 :         *result = Py_TYPE(iter)->tp_iternext(iter);
    2870                 :            :     }
    2871                 :            :     else {
    2872                 :          0 :         *result = PyObject_CallMethodOneArg(iter, &_Py_ID(send), arg);
    2873                 :            :     }
    2874         [ #  # ]:          0 :     if (*result != NULL) {
    2875                 :          0 :         return PYGEN_NEXT;
    2876                 :            :     }
    2877         [ #  # ]:          0 :     if (_PyGen_FetchStopIterationValue(result) == 0) {
    2878                 :          0 :         return PYGEN_RETURN;
    2879                 :            :     }
    2880                 :          0 :     return PYGEN_ERROR;
    2881                 :            : }
    2882                 :            : 
    2883                 :            : /*
    2884                 :            :  * Flatten a sequence of bytes() objects into a C array of
    2885                 :            :  * NULL terminated string pointers with a NULL char* terminating the array.
    2886                 :            :  * (ie: an argv or env list)
    2887                 :            :  *
    2888                 :            :  * Memory allocated for the returned list is allocated using PyMem_Malloc()
    2889                 :            :  * and MUST be freed by _Py_FreeCharPArray().
    2890                 :            :  */
    2891                 :            : char *const *
    2892                 :          0 : _PySequence_BytesToCharpArray(PyObject* self)
    2893                 :            : {
    2894                 :            :     char **array;
    2895                 :            :     Py_ssize_t i, argc;
    2896                 :          0 :     PyObject *item = NULL;
    2897                 :            :     Py_ssize_t size;
    2898                 :            : 
    2899                 :          0 :     argc = PySequence_Size(self);
    2900         [ #  # ]:          0 :     if (argc == -1)
    2901                 :          0 :         return NULL;
    2902                 :            : 
    2903                 :            :     assert(argc >= 0);
    2904                 :            : 
    2905         [ #  # ]:          0 :     if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) {
    2906                 :          0 :         PyErr_NoMemory();
    2907                 :          0 :         return NULL;
    2908                 :            :     }
    2909                 :            : 
    2910                 :          0 :     array = PyMem_Malloc((argc + 1) * sizeof(char *));
    2911         [ #  # ]:          0 :     if (array == NULL) {
    2912                 :          0 :         PyErr_NoMemory();
    2913                 :          0 :         return NULL;
    2914                 :            :     }
    2915         [ #  # ]:          0 :     for (i = 0; i < argc; ++i) {
    2916                 :            :         char *data;
    2917                 :          0 :         item = PySequence_GetItem(self, i);
    2918         [ #  # ]:          0 :         if (item == NULL) {
    2919                 :            :             /* NULL terminate before freeing. */
    2920                 :          0 :             array[i] = NULL;
    2921                 :          0 :             goto fail;
    2922                 :            :         }
    2923                 :            :         /* check for embedded null bytes */
    2924         [ #  # ]:          0 :         if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) {
    2925                 :            :             /* NULL terminate before freeing. */
    2926                 :          0 :             array[i] = NULL;
    2927                 :          0 :             goto fail;
    2928                 :            :         }
    2929                 :          0 :         size = PyBytes_GET_SIZE(item) + 1;
    2930                 :          0 :         array[i] = PyMem_Malloc(size);
    2931         [ #  # ]:          0 :         if (!array[i]) {
    2932                 :          0 :             PyErr_NoMemory();
    2933                 :          0 :             goto fail;
    2934                 :            :         }
    2935                 :          0 :         memcpy(array[i], data, size);
    2936                 :          0 :         Py_DECREF(item);
    2937                 :            :     }
    2938                 :          0 :     array[argc] = NULL;
    2939                 :            : 
    2940                 :          0 :     return array;
    2941                 :            : 
    2942                 :          0 : fail:
    2943                 :          0 :     Py_XDECREF(item);
    2944                 :          0 :     _Py_FreeCharPArray(array);
    2945                 :          0 :     return NULL;
    2946                 :            : }
    2947                 :            : 
    2948                 :            : 
    2949                 :            : /* Free's a NULL terminated char** array of C strings. */
    2950                 :            : void
    2951                 :          0 : _Py_FreeCharPArray(char *const array[])
    2952                 :            : {
    2953                 :            :     Py_ssize_t i;
    2954         [ #  # ]:          0 :     for (i = 0; array[i] != NULL; ++i) {
    2955                 :          0 :         PyMem_Free(array[i]);
    2956                 :            :     }
    2957                 :          0 :     PyMem_Free((void*)array);
    2958                 :          0 : }

Generated by: LCOV version 1.14