(root)/
Python-3.11.7/
Objects/
capsule.c
       1  /* Wrap void * pointers to be passed between C modules */
       2  
       3  #include "Python.h"
       4  
       5  /* Internal structure of PyCapsule */
       6  typedef struct {
       7      PyObject_HEAD
       8      void *pointer;
       9      const char *name;
      10      void *context;
      11      PyCapsule_Destructor destructor;
      12  } PyCapsule;
      13  
      14  
      15  
      16  static int
      17  _is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
      18  {
      19      if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
      20          PyErr_SetString(PyExc_ValueError, invalid_capsule);
      21          return 0;
      22      }
      23      return 1;
      24  }
      25  
      26  #define is_legal_capsule(capsule, name) \
      27      (_is_legal_capsule(capsule, \
      28       name " called with invalid PyCapsule object"))
      29  
      30  
      31  static int
      32  name_matches(const char *name1, const char *name2) {
      33      /* if either is NULL, */
      34      if (!name1 || !name2) {
      35          /* they're only the same if they're both NULL. */
      36          return name1 == name2;
      37      }
      38      return !strcmp(name1, name2);
      39  }
      40  
      41  
      42  
      43  PyObject *
      44  PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
      45  {
      46      PyCapsule *capsule;
      47  
      48      if (!pointer) {
      49          PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
      50          return NULL;
      51      }
      52  
      53      capsule = PyObject_New(PyCapsule, &PyCapsule_Type);
      54      if (capsule == NULL) {
      55          return NULL;
      56      }
      57  
      58      capsule->pointer = pointer;
      59      capsule->name = name;
      60      capsule->context = NULL;
      61      capsule->destructor = destructor;
      62  
      63      return (PyObject *)capsule;
      64  }
      65  
      66  
      67  int
      68  PyCapsule_IsValid(PyObject *o, const char *name)
      69  {
      70      PyCapsule *capsule = (PyCapsule *)o;
      71  
      72      return (capsule != NULL &&
      73              PyCapsule_CheckExact(capsule) &&
      74              capsule->pointer != NULL &&
      75              name_matches(capsule->name, name));
      76  }
      77  
      78  
      79  void *
      80  PyCapsule_GetPointer(PyObject *o, const char *name)
      81  {
      82      PyCapsule *capsule = (PyCapsule *)o;
      83  
      84      if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
      85          return NULL;
      86      }
      87  
      88      if (!name_matches(name, capsule->name)) {
      89          PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
      90          return NULL;
      91      }
      92  
      93      return capsule->pointer;
      94  }
      95  
      96  
      97  const char *
      98  PyCapsule_GetName(PyObject *o)
      99  {
     100      PyCapsule *capsule = (PyCapsule *)o;
     101  
     102      if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
     103          return NULL;
     104      }
     105      return capsule->name;
     106  }
     107  
     108  
     109  PyCapsule_Destructor
     110  PyCapsule_GetDestructor(PyObject *o)
     111  {
     112      PyCapsule *capsule = (PyCapsule *)o;
     113  
     114      if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
     115          return NULL;
     116      }
     117      return capsule->destructor;
     118  }
     119  
     120  
     121  void *
     122  PyCapsule_GetContext(PyObject *o)
     123  {
     124      PyCapsule *capsule = (PyCapsule *)o;
     125  
     126      if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
     127          return NULL;
     128      }
     129      return capsule->context;
     130  }
     131  
     132  
     133  int
     134  PyCapsule_SetPointer(PyObject *o, void *pointer)
     135  {
     136      PyCapsule *capsule = (PyCapsule *)o;
     137  
     138      if (!pointer) {
     139          PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
     140          return -1;
     141      }
     142  
     143      if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
     144          return -1;
     145      }
     146  
     147      capsule->pointer = pointer;
     148      return 0;
     149  }
     150  
     151  
     152  int
     153  PyCapsule_SetName(PyObject *o, const char *name)
     154  {
     155      PyCapsule *capsule = (PyCapsule *)o;
     156  
     157      if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
     158          return -1;
     159      }
     160  
     161      capsule->name = name;
     162      return 0;
     163  }
     164  
     165  
     166  int
     167  PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
     168  {
     169      PyCapsule *capsule = (PyCapsule *)o;
     170  
     171      if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
     172          return -1;
     173      }
     174  
     175      capsule->destructor = destructor;
     176      return 0;
     177  }
     178  
     179  
     180  int
     181  PyCapsule_SetContext(PyObject *o, void *context)
     182  {
     183      PyCapsule *capsule = (PyCapsule *)o;
     184  
     185      if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
     186          return -1;
     187      }
     188  
     189      capsule->context = context;
     190      return 0;
     191  }
     192  
     193  
     194  void *
     195  PyCapsule_Import(const char *name, int no_block)
     196  {
     197      PyObject *object = NULL;
     198      void *return_value = NULL;
     199      char *trace;
     200      size_t name_length = (strlen(name) + 1) * sizeof(char);
     201      char *name_dup = (char *)PyMem_Malloc(name_length);
     202  
     203      if (!name_dup) {
     204          return PyErr_NoMemory();
     205      }
     206  
     207      memcpy(name_dup, name, name_length);
     208  
     209      trace = name_dup;
     210      while (trace) {
     211          char *dot = strchr(trace, '.');
     212          if (dot) {
     213              *dot++ = '\0';
     214          }
     215  
     216          if (object == NULL) {
     217              object = PyImport_ImportModule(trace);
     218              if (!object) {
     219                  PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
     220              }
     221          } else {
     222              PyObject *object2 = PyObject_GetAttrString(object, trace);
     223              Py_DECREF(object);
     224              object = object2;
     225          }
     226          if (!object) {
     227              goto EXIT;
     228          }
     229  
     230          trace = dot;
     231      }
     232  
     233      /* compare attribute name to module.name by hand */
     234      if (PyCapsule_IsValid(object, name)) {
     235          PyCapsule *capsule = (PyCapsule *)object;
     236          return_value = capsule->pointer;
     237      } else {
     238          PyErr_Format(PyExc_AttributeError,
     239              "PyCapsule_Import \"%s\" is not valid",
     240              name);
     241      }
     242  
     243  EXIT:
     244      Py_XDECREF(object);
     245      if (name_dup) {
     246          PyMem_Free(name_dup);
     247      }
     248      return return_value;
     249  }
     250  
     251  
     252  static void
     253  capsule_dealloc(PyObject *o)
     254  {
     255      PyCapsule *capsule = (PyCapsule *)o;
     256      if (capsule->destructor) {
     257          capsule->destructor(o);
     258      }
     259      PyObject_Free(o);
     260  }
     261  
     262  
     263  static PyObject *
     264  capsule_repr(PyObject *o)
     265  {
     266      PyCapsule *capsule = (PyCapsule *)o;
     267      const char *name;
     268      const char *quote;
     269  
     270      if (capsule->name) {
     271          quote = "\"";
     272          name = capsule->name;
     273      } else {
     274          quote = "";
     275          name = "NULL";
     276      }
     277  
     278      return PyUnicode_FromFormat("<capsule object %s%s%s at %p>",
     279          quote, name, quote, capsule);
     280  }
     281  
     282  
     283  
     284  PyDoc_STRVAR(PyCapsule_Type__doc__,
     285  "Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
     286  object.  They're a way of passing data through the Python interpreter\n\
     287  without creating your own custom type.\n\
     288  \n\
     289  Capsules are used for communication between extension modules.\n\
     290  They provide a way for an extension module to export a C interface\n\
     291  to other extension modules, so that extension modules can use the\n\
     292  Python import mechanism to link to one another.\n\
     293  ");
     294  
     295  PyTypeObject PyCapsule_Type = {
     296      PyVarObject_HEAD_INIT(&PyType_Type, 0)
     297      "PyCapsule",                /*tp_name*/
     298      sizeof(PyCapsule),          /*tp_basicsize*/
     299      0,                          /*tp_itemsize*/
     300      /* methods */
     301      capsule_dealloc, /*tp_dealloc*/
     302      0,                          /*tp_vectorcall_offset*/
     303      0,                          /*tp_getattr*/
     304      0,                          /*tp_setattr*/
     305      0,                          /*tp_as_async*/
     306      capsule_repr, /*tp_repr*/
     307      0,                          /*tp_as_number*/
     308      0,                          /*tp_as_sequence*/
     309      0,                          /*tp_as_mapping*/
     310      0,                          /*tp_hash*/
     311      0,                          /*tp_call*/
     312      0,                          /*tp_str*/
     313      0,                          /*tp_getattro*/
     314      0,                          /*tp_setattro*/
     315      0,                          /*tp_as_buffer*/
     316      0,                          /*tp_flags*/
     317      PyCapsule_Type__doc__       /*tp_doc*/
     318  };
     319  
     320