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