(root)/
Python-3.12.0/
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_SETREF(object, object2);
     224          }
     225          if (!object) {
     226              goto EXIT;
     227          }
     228  
     229          trace = dot;
     230      }
     231  
     232      /* compare attribute name to module.name by hand */
     233      if (PyCapsule_IsValid(object, name)) {
     234          PyCapsule *capsule = (PyCapsule *)object;
     235          return_value = capsule->pointer;
     236      } else {
     237          PyErr_Format(PyExc_AttributeError,
     238              "PyCapsule_Import \"%s\" is not valid",
     239              name);
     240      }
     241  
     242  EXIT:
     243      Py_XDECREF(object);
     244      if (name_dup) {
     245          PyMem_Free(name_dup);
     246      }
     247      return return_value;
     248  }
     249  
     250  
     251  static void
     252  capsule_dealloc(PyObject *o)
     253  {
     254      PyCapsule *capsule = (PyCapsule *)o;
     255      if (capsule->destructor) {
     256          capsule->destructor(o);
     257      }
     258      PyObject_Free(o);
     259  }
     260  
     261  
     262  static PyObject *
     263  capsule_repr(PyObject *o)
     264  {
     265      PyCapsule *capsule = (PyCapsule *)o;
     266      const char *name;
     267      const char *quote;
     268  
     269      if (capsule->name) {
     270          quote = "\"";
     271          name = capsule->name;
     272      } else {
     273          quote = "";
     274          name = "NULL";
     275      }
     276  
     277      return PyUnicode_FromFormat("<capsule object %s%s%s at %p>",
     278          quote, name, quote, capsule);
     279  }
     280  
     281  
     282  
     283  PyDoc_STRVAR(PyCapsule_Type__doc__,
     284  "Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
     285  object.  They're a way of passing data through the Python interpreter\n\
     286  without creating your own custom type.\n\
     287  \n\
     288  Capsules are used for communication between extension modules.\n\
     289  They provide a way for an extension module to export a C interface\n\
     290  to other extension modules, so that extension modules can use the\n\
     291  Python import mechanism to link to one another.\n\
     292  ");
     293  
     294  PyTypeObject PyCapsule_Type = {
     295      PyVarObject_HEAD_INIT(&PyType_Type, 0)
     296      "PyCapsule",                /*tp_name*/
     297      sizeof(PyCapsule),          /*tp_basicsize*/
     298      0,                          /*tp_itemsize*/
     299      /* methods */
     300      capsule_dealloc, /*tp_dealloc*/
     301      0,                          /*tp_vectorcall_offset*/
     302      0,                          /*tp_getattr*/
     303      0,                          /*tp_setattr*/
     304      0,                          /*tp_as_async*/
     305      capsule_repr, /*tp_repr*/
     306      0,                          /*tp_as_number*/
     307      0,                          /*tp_as_sequence*/
     308      0,                          /*tp_as_mapping*/
     309      0,                          /*tp_hash*/
     310      0,                          /*tp_call*/
     311      0,                          /*tp_str*/
     312      0,                          /*tp_getattro*/
     313      0,                          /*tp_setattro*/
     314      0,                          /*tp_as_buffer*/
     315      0,                          /*tp_flags*/
     316      PyCapsule_Type__doc__       /*tp_doc*/
     317  };
     318  
     319