LCOV - code coverage report
Current view: | top level - Objects - interpreteridobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 0 | 101 | 0.0 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 0 | 12 | 0.0 %
|  |  | Branches: | 0 | 66 | 0.0 %

               Branch data     Line data    Source code
           1                 :            : /* InterpreterID object */
           2                 :            :
           3                 :            : #include "Python.h"
           4                 :            : #include "pycore_abstract.h"   // _PyIndex_Check()
           5                 :            : #include "pycore_interp.h"     // _PyInterpreterState_LookUpID()
           6                 :            : #include "pycore_interpreteridobject.h"
           7                 :            :
           8                 :            :
           9                 :            : typedef struct interpid {
          10                 :            :     PyObject_HEAD
          11                 :            :     int64_t id;
          12                 :            : } interpid;
          13                 :            :
          14                 :            : static interpid *
          15                 :          0 : newinterpid(PyTypeObject *cls, int64_t id, int force)
          16                 :            : {
          17                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_LookUpID(id);
          18         [ #  # ]:          0 :     if (interp == NULL) {
          19         [ #  # ]:          0 :         if (force) {
          20                 :          0 :             PyErr_Clear();
          21                 :            :         }
          22                 :            :         else {
          23                 :          0 :             return NULL;
          24                 :            :         }
          25                 :            :     }
          26                 :            :
          27         [ #  # ]:          0 :     if (interp != NULL) {
          28         [ #  # ]:          0 :         if (_PyInterpreterState_IDIncref(interp) < 0) {
          29                 :          0 :             return NULL;
          30                 :            :         }
          31                 :            :     }
          32                 :            :
          33                 :          0 :     interpid *self = PyObject_New(interpid, cls);
          34         [ #  # ]:          0 :     if (self == NULL) {
          35         [ #  # ]:          0 :         if (interp != NULL) {
          36                 :          0 :             _PyInterpreterState_IDDecref(interp);
          37                 :            :         }
          38                 :          0 :         return NULL;
          39                 :            :     }
          40                 :          0 :     self->id = id;
          41                 :            :
          42                 :          0 :     return self;
          43                 :            : }
          44                 :            :
          45                 :            : static int
          46                 :          0 : interp_id_converter(PyObject *arg, void *ptr)
          47                 :            : {
          48                 :            :     int64_t id;
          49         [ #  # ]:          0 :     if (PyObject_TypeCheck(arg, &_PyInterpreterID_Type)) {
          50                 :          0 :         id = ((interpid *)arg)->id;
          51                 :            :     }
          52         [ #  # ]:          0 :     else if (_PyIndex_Check(arg)) {
          53                 :          0 :         id = PyLong_AsLongLong(arg);
          54   [ #  #  #  # ]:          0 :         if (id == -1 && PyErr_Occurred()) {
          55                 :          0 :             return 0;
          56                 :            :         }
          57         [ #  # ]:          0 :         if (id < 0) {
          58                 :          0 :             PyErr_Format(PyExc_ValueError,
          59                 :            :                          "interpreter ID must be a non-negative int, got %R", arg);
          60                 :          0 :             return 0;
          61                 :            :         }
          62                 :            :     }
          63                 :            :     else {
          64                 :          0 :         PyErr_Format(PyExc_TypeError,
          65                 :            :                      "interpreter ID must be an int, got %.100s",
          66                 :          0 :                      Py_TYPE(arg)->tp_name);
          67                 :          0 :         return 0;
          68                 :            :     }
          69                 :          0 :     *(int64_t *)ptr = id;
          70                 :          0 :     return 1;
          71                 :            : }
          72                 :            :
          73                 :            : static PyObject *
          74                 :          0 : interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds)
          75                 :            : {
          76                 :            :     static char *kwlist[] = {"id", "force", NULL};
          77                 :            :     int64_t id;
          78                 :          0 :     int force = 0;
          79         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(args, kwds,
          80                 :            :                                      "O&|$p:InterpreterID.__init__", kwlist,
          81                 :            :                                      interp_id_converter, &id, &force)) {
          82                 :          0 :         return NULL;
          83                 :            :     }
          84                 :            :
          85                 :          0 :     return (PyObject *)newinterpid(cls, id, force);
          86                 :            : }
          87                 :            :
          88                 :            : static void
          89                 :          0 : interpid_dealloc(PyObject *v)
          90                 :            : {
          91                 :          0 :     int64_t id = ((interpid *)v)->id;
          92                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_LookUpID(id);
          93         [ #  # ]:          0 :     if (interp != NULL) {
          94                 :          0 :         _PyInterpreterState_IDDecref(interp);
          95                 :            :     }
          96                 :            :     else {
          97                 :            :         // already deleted
          98                 :          0 :         PyErr_Clear();
          99                 :            :     }
         100                 :          0 :     Py_TYPE(v)->tp_free(v);
         101                 :          0 : }
         102                 :            :
         103                 :            : static PyObject *
         104                 :          0 : interpid_repr(PyObject *self)
         105                 :            : {
         106                 :          0 :     PyTypeObject *type = Py_TYPE(self);
         107                 :          0 :     const char *name = _PyType_Name(type);
         108                 :          0 :     interpid *id = (interpid *)self;
         109                 :          0 :     return PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id);
         110                 :            : }
         111                 :            :
         112                 :            : static PyObject *
         113                 :          0 : interpid_str(PyObject *self)
         114                 :            : {
         115                 :          0 :     interpid *id = (interpid *)self;
         116                 :          0 :     return PyUnicode_FromFormat("%" PRId64 "", id->id);
         117                 :            : }
         118                 :            :
         119                 :            : static PyObject *
         120                 :          0 : interpid_int(PyObject *self)
         121                 :            : {
         122                 :          0 :     interpid *id = (interpid *)self;
         123                 :          0 :     return PyLong_FromLongLong(id->id);
         124                 :            : }
         125                 :            :
         126                 :            : static PyNumberMethods interpid_as_number = {
         127                 :            :      0,                       /* nb_add */
         128                 :            :      0,                       /* nb_subtract */
         129                 :            :      0,                       /* nb_multiply */
         130                 :            :      0,                       /* nb_remainder */
         131                 :            :      0,                       /* nb_divmod */
         132                 :            :      0,                       /* nb_power */
         133                 :            :      0,                       /* nb_negative */
         134                 :            :      0,                       /* nb_positive */
         135                 :            :      0,                       /* nb_absolute */
         136                 :            :      0,                       /* nb_bool */
         137                 :            :      0,                       /* nb_invert */
         138                 :            :      0,                       /* nb_lshift */
         139                 :            :      0,                       /* nb_rshift */
         140                 :            :      0,                       /* nb_and */
         141                 :            :      0,                       /* nb_xor */
         142                 :            :      0,                       /* nb_or */
         143                 :            :      (unaryfunc)interpid_int, /* nb_int */
         144                 :            :      0,                       /* nb_reserved */
         145                 :            :      0,                       /* nb_float */
         146                 :            :
         147                 :            :      0,                       /* nb_inplace_add */
         148                 :            :      0,                       /* nb_inplace_subtract */
         149                 :            :      0,                       /* nb_inplace_multiply */
         150                 :            :      0,                       /* nb_inplace_remainder */
         151                 :            :      0,                       /* nb_inplace_power */
         152                 :            :      0,                       /* nb_inplace_lshift */
         153                 :            :      0,                       /* nb_inplace_rshift */
         154                 :            :      0,                       /* nb_inplace_and */
         155                 :            :      0,                       /* nb_inplace_xor */
         156                 :            :      0,                       /* nb_inplace_or */
         157                 :            :
         158                 :            :      0,                       /* nb_floor_divide */
         159                 :            :      0,                       /* nb_true_divide */
         160                 :            :      0,                       /* nb_inplace_floor_divide */
         161                 :            :      0,                       /* nb_inplace_true_divide */
         162                 :            :
         163                 :            :      (unaryfunc)interpid_int, /* nb_index */
         164                 :            : };
         165                 :            :
         166                 :            : static Py_hash_t
         167                 :          0 : interpid_hash(PyObject *self)
         168                 :            : {
         169                 :          0 :     interpid *id = (interpid *)self;
         170                 :          0 :     PyObject *obj = PyLong_FromLongLong(id->id);
         171         [ #  # ]:          0 :     if (obj == NULL) {
         172                 :          0 :         return -1;
         173                 :            :     }
         174                 :          0 :     Py_hash_t hash = PyObject_Hash(obj);
         175                 :          0 :     Py_DECREF(obj);
         176                 :          0 :     return hash;
         177                 :            : }
         178                 :            :
         179                 :            : static PyObject *
         180                 :          0 : interpid_richcompare(PyObject *self, PyObject *other, int op)
         181                 :            : {
         182   [ #  #  #  # ]:          0 :     if (op != Py_EQ && op != Py_NE) {
         183                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
         184                 :            :     }
         185                 :            :
         186         [ #  # ]:          0 :     if (!PyObject_TypeCheck(self, &_PyInterpreterID_Type)) {
         187                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
         188                 :            :     }
         189                 :            :
         190                 :          0 :     interpid *id = (interpid *)self;
         191                 :            :     int equal;
         192         [ #  # ]:          0 :     if (PyObject_TypeCheck(other, &_PyInterpreterID_Type)) {
         193                 :          0 :         interpid *otherid = (interpid *)other;
         194                 :          0 :         equal = (id->id == otherid->id);
         195                 :            :     }
         196         [ #  # ]:          0 :     else if (PyLong_CheckExact(other)) {
         197                 :            :         /* Fast path */
         198                 :            :         int overflow;
         199                 :          0 :         long long otherid = PyLong_AsLongLongAndOverflow(other, &overflow);
         200   [ #  #  #  # ]:          0 :         if (otherid == -1 && PyErr_Occurred()) {
         201                 :          0 :             return NULL;
         202                 :            :         }
         203   [ #  #  #  #  :          0 :         equal = !overflow && (otherid >= 0) && (id->id == otherid);
                       #  # ]
         204                 :            :     }
         205         [ #  # ]:          0 :     else if (PyNumber_Check(other)) {
         206                 :          0 :         PyObject *pyid = PyLong_FromLongLong(id->id);
         207         [ #  # ]:          0 :         if (pyid == NULL) {
         208                 :          0 :             return NULL;
         209                 :            :         }
         210                 :          0 :         PyObject *res = PyObject_RichCompare(pyid, other, op);
         211                 :          0 :         Py_DECREF(pyid);
         212                 :          0 :         return res;
         213                 :            :     }
         214                 :            :     else {
         215                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
         216                 :            :     }
         217                 :            :
         218   [ #  #  #  #  :          0 :     if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) {
                 #  #  #  # ]
         219                 :          0 :         Py_RETURN_TRUE;
         220                 :            :     }
         221                 :          0 :     Py_RETURN_FALSE;
         222                 :            : }
         223                 :            :
         224                 :            : PyDoc_STRVAR(interpid_doc,
         225                 :            : "A interpreter ID identifies a interpreter and may be used as an int.");
         226                 :            :
         227                 :            : PyTypeObject _PyInterpreterID_Type = {
         228                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         229                 :            :     "InterpreterID",   /* tp_name */
         230                 :            :     sizeof(interpid),               /* tp_basicsize */
         231                 :            :     0,                              /* tp_itemsize */
         232                 :            :     (destructor)interpid_dealloc,   /* tp_dealloc */
         233                 :            :     0,                              /* tp_vectorcall_offset */
         234                 :            :     0,                              /* tp_getattr */
         235                 :            :     0,                              /* tp_setattr */
         236                 :            :     0,                              /* tp_as_async */
         237                 :            :     (reprfunc)interpid_repr,        /* tp_repr */
         238                 :            :     &interpid_as_number,            /* tp_as_number */
         239                 :            :     0,                              /* tp_as_sequence */
         240                 :            :     0,                              /* tp_as_mapping */
         241                 :            :     interpid_hash,                  /* tp_hash */
         242                 :            :     0,                              /* tp_call */
         243                 :            :     (reprfunc)interpid_str,         /* tp_str */
         244                 :            :     0,                              /* tp_getattro */
         245                 :            :     0,                              /* tp_setattro */
         246                 :            :     0,                              /* tp_as_buffer */
         247                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
         248                 :            :     interpid_doc,                   /* tp_doc */
         249                 :            :     0,                              /* tp_traverse */
         250                 :            :     0,                              /* tp_clear */
         251                 :            :     interpid_richcompare,           /* tp_richcompare */
         252                 :            :     0,                              /* tp_weaklistoffset */
         253                 :            :     0,                              /* tp_iter */
         254                 :            :     0,                              /* tp_iternext */
         255                 :            :     0,                              /* tp_methods */
         256                 :            :     0,                              /* tp_members */
         257                 :            :     0,                              /* tp_getset */
         258                 :            :     0,                              /* tp_base */
         259                 :            :     0,                              /* tp_dict */
         260                 :            :     0,                              /* tp_descr_get */
         261                 :            :     0,                              /* tp_descr_set */
         262                 :            :     0,                              /* tp_dictoffset */
         263                 :            :     0,                              /* tp_init */
         264                 :            :     0,                              /* tp_alloc */
         265                 :            :     interpid_new,                   /* tp_new */
         266                 :            : };
         267                 :            :
         268                 :          0 : PyObject *_PyInterpreterID_New(int64_t id)
         269                 :            : {
         270                 :          0 :     return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0);
         271                 :            : }
         272                 :            :
         273                 :            : PyObject *
         274                 :          0 : _PyInterpreterState_GetIDObject(PyInterpreterState *interp)
         275                 :            : {
         276         [ #  # ]:          0 :     if (_PyInterpreterState_IDInitref(interp) != 0) {
         277                 :          0 :         return NULL;
         278                 :            :     };
         279                 :          0 :     int64_t id = PyInterpreterState_GetID(interp);
         280         [ #  # ]:          0 :     if (id < 0) {
         281                 :          0 :         return NULL;
         282                 :            :     }
         283                 :          0 :     return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0);
         284                 :            : }
         285                 :            :
         286                 :            : PyInterpreterState *
         287                 :          0 : _PyInterpreterID_LookUp(PyObject *requested_id)
         288                 :            : {
         289                 :            :     int64_t id;
         290         [ #  # ]:          0 :     if (!interp_id_converter(requested_id, &id)) {
         291                 :          0 :         return NULL;
         292                 :            :     }
         293                 :          0 :     return _PyInterpreterState_LookUpID(id);
         294                 :            : }

Generated by: LCOV version 1.14