@@ -9,18 +9,28 @@ typedef struct {
9
9
const char * name ;
10
10
void * context ;
11
11
PyCapsule_Destructor destructor ;
12
+ traverseproc traverse_func ;
13
+ inquiry clear_func ;
12
14
} PyCapsule ;
13
15
14
16
15
17
16
18
static int
17
- _is_legal_capsule (PyCapsule * capsule , const char * invalid_capsule )
19
+ _is_legal_capsule (PyObject * op , const char * invalid_capsule )
18
20
{
19
- if (!capsule || !PyCapsule_CheckExact (capsule ) || capsule -> pointer == NULL ) {
20
- PyErr_SetString (PyExc_ValueError , invalid_capsule );
21
- return 0 ;
21
+ if (!op || !PyCapsule_CheckExact (op )) {
22
+ goto error ;
23
+ }
24
+ PyCapsule * capsule = (PyCapsule * )op ;
25
+
26
+ if (capsule -> pointer == NULL ) {
27
+ goto error ;
22
28
}
23
29
return 1 ;
30
+
31
+ error :
32
+ PyErr_SetString (PyExc_ValueError , invalid_capsule );
33
+ return 0 ;
24
34
}
25
35
26
36
#define is_legal_capsule (capsule , name ) \
@@ -50,7 +60,7 @@ PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
50
60
return NULL ;
51
61
}
52
62
53
- capsule = PyObject_New (PyCapsule , & PyCapsule_Type );
63
+ capsule = PyObject_GC_New (PyCapsule , & PyCapsule_Type );
54
64
if (capsule == NULL ) {
55
65
return NULL ;
56
66
}
@@ -59,15 +69,18 @@ PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
59
69
capsule -> name = name ;
60
70
capsule -> context = NULL ;
61
71
capsule -> destructor = destructor ;
72
+ capsule -> traverse_func = NULL ;
73
+ capsule -> clear_func = NULL ;
74
+ // Only track the capsule if _PyCapsule_SetTraverse() is called
62
75
63
76
return (PyObject * )capsule ;
64
77
}
65
78
66
79
67
80
int
68
- PyCapsule_IsValid (PyObject * o , const char * name )
81
+ PyCapsule_IsValid (PyObject * op , const char * name )
69
82
{
70
- PyCapsule * capsule = (PyCapsule * )o ;
83
+ PyCapsule * capsule = (PyCapsule * )op ;
71
84
72
85
return (capsule != NULL &&
73
86
PyCapsule_CheckExact (capsule ) &&
@@ -77,13 +90,12 @@ PyCapsule_IsValid(PyObject *o, const char *name)
77
90
78
91
79
92
void *
80
- PyCapsule_GetPointer (PyObject * o , const char * name )
93
+ PyCapsule_GetPointer (PyObject * op , const char * name )
81
94
{
82
- PyCapsule * capsule = (PyCapsule * )o ;
83
-
84
- if (!is_legal_capsule (capsule , "PyCapsule_GetPointer" )) {
95
+ if (!is_legal_capsule (op , "PyCapsule_GetPointer" )) {
85
96
return NULL ;
86
97
}
98
+ PyCapsule * capsule = (PyCapsule * )op ;
87
99
88
100
if (!name_matches (name , capsule -> name )) {
89
101
PyErr_SetString (PyExc_ValueError , "PyCapsule_GetPointer called with incorrect name" );
@@ -95,52 +107,48 @@ PyCapsule_GetPointer(PyObject *o, const char *name)
95
107
96
108
97
109
const char *
98
- PyCapsule_GetName (PyObject * o )
110
+ PyCapsule_GetName (PyObject * op )
99
111
{
100
- PyCapsule * capsule = (PyCapsule * )o ;
101
-
102
- if (!is_legal_capsule (capsule , "PyCapsule_GetName" )) {
112
+ if (!is_legal_capsule (op , "PyCapsule_GetName" )) {
103
113
return NULL ;
104
114
}
115
+ PyCapsule * capsule = (PyCapsule * )op ;
105
116
return capsule -> name ;
106
117
}
107
118
108
119
109
120
PyCapsule_Destructor
110
- PyCapsule_GetDestructor (PyObject * o )
121
+ PyCapsule_GetDestructor (PyObject * op )
111
122
{
112
- PyCapsule * capsule = (PyCapsule * )o ;
113
-
114
- if (!is_legal_capsule (capsule , "PyCapsule_GetDestructor" )) {
123
+ if (!is_legal_capsule (op , "PyCapsule_GetDestructor" )) {
115
124
return NULL ;
116
125
}
126
+ PyCapsule * capsule = (PyCapsule * )op ;
117
127
return capsule -> destructor ;
118
128
}
119
129
120
130
121
131
void *
122
- PyCapsule_GetContext (PyObject * o )
132
+ PyCapsule_GetContext (PyObject * op )
123
133
{
124
- PyCapsule * capsule = (PyCapsule * )o ;
125
-
126
- if (!is_legal_capsule (capsule , "PyCapsule_GetContext" )) {
134
+ if (!is_legal_capsule (op , "PyCapsule_GetContext" )) {
127
135
return NULL ;
128
136
}
137
+ PyCapsule * capsule = (PyCapsule * )op ;
129
138
return capsule -> context ;
130
139
}
131
140
132
141
133
142
int
134
- PyCapsule_SetPointer (PyObject * o , void * pointer )
143
+ PyCapsule_SetPointer (PyObject * op , void * pointer )
135
144
{
136
- PyCapsule * capsule = (PyCapsule * )o ;
137
-
138
- if (!pointer ) {
139
- PyErr_SetString (PyExc_ValueError , "PyCapsule_SetPointer called with null pointer" );
145
+ if (!is_legal_capsule (op , "PyCapsule_SetPointer" )) {
140
146
return -1 ;
141
147
}
148
+ PyCapsule * capsule = (PyCapsule * )op ;
142
149
143
- if (!is_legal_capsule (capsule , "PyCapsule_SetPointer" )) {
150
+ if (!pointer ) {
151
+ PyErr_SetString (PyExc_ValueError , "PyCapsule_SetPointer called with null pointer" );
144
152
return -1 ;
145
153
}
146
154
@@ -150,47 +158,62 @@ PyCapsule_SetPointer(PyObject *o, void *pointer)
150
158
151
159
152
160
int
153
- PyCapsule_SetName (PyObject * o , const char * name )
161
+ PyCapsule_SetName (PyObject * op , const char * name )
154
162
{
155
- PyCapsule * capsule = (PyCapsule * )o ;
156
-
157
- if (!is_legal_capsule (capsule , "PyCapsule_SetName" )) {
163
+ if (!is_legal_capsule (op , "PyCapsule_SetName" )) {
158
164
return -1 ;
159
165
}
166
+ PyCapsule * capsule = (PyCapsule * )op ;
160
167
161
168
capsule -> name = name ;
162
169
return 0 ;
163
170
}
164
171
165
172
166
173
int
167
- PyCapsule_SetDestructor (PyObject * o , PyCapsule_Destructor destructor )
174
+ PyCapsule_SetDestructor (PyObject * op , PyCapsule_Destructor destructor )
168
175
{
169
- PyCapsule * capsule = (PyCapsule * )o ;
170
-
171
- if (!is_legal_capsule (capsule , "PyCapsule_SetDestructor" )) {
176
+ if (!is_legal_capsule (op , "PyCapsule_SetDestructor" )) {
172
177
return -1 ;
173
178
}
179
+ PyCapsule * capsule = (PyCapsule * )op ;
174
180
175
181
capsule -> destructor = destructor ;
176
182
return 0 ;
177
183
}
178
184
179
185
180
186
int
181
- PyCapsule_SetContext (PyObject * o , void * context )
187
+ PyCapsule_SetContext (PyObject * op , void * context )
182
188
{
183
- PyCapsule * capsule = (PyCapsule * )o ;
184
-
185
- if (!is_legal_capsule (capsule , "PyCapsule_SetContext" )) {
189
+ if (!is_legal_capsule (op , "PyCapsule_SetContext" )) {
186
190
return -1 ;
187
191
}
192
+ PyCapsule * capsule = (PyCapsule * )op ;
188
193
189
194
capsule -> context = context ;
190
195
return 0 ;
191
196
}
192
197
193
198
199
+ int
200
+ _PyCapsule_SetTraverse (PyObject * op , traverseproc traverse_func , inquiry clear_func )
201
+ {
202
+ if (!is_legal_capsule (op , "_PyCapsule_SetTraverse" )) {
203
+ return -1 ;
204
+ }
205
+ PyCapsule * capsule = (PyCapsule * )op ;
206
+
207
+ if (!PyObject_GC_IsTracked (op )) {
208
+ PyObject_GC_Track (op );
209
+ }
210
+
211
+ capsule -> traverse_func = traverse_func ;
212
+ capsule -> clear_func = clear_func ;
213
+ return 0 ;
214
+ }
215
+
216
+
194
217
void *
195
218
PyCapsule_Import (const char * name , int no_block )
196
219
{
@@ -249,13 +272,14 @@ PyCapsule_Import(const char *name, int no_block)
249
272
250
273
251
274
static void
252
- capsule_dealloc (PyObject * o )
275
+ capsule_dealloc (PyObject * op )
253
276
{
254
- PyCapsule * capsule = (PyCapsule * )o ;
277
+ PyCapsule * capsule = (PyCapsule * )op ;
278
+ PyObject_GC_UnTrack (op );
255
279
if (capsule -> destructor ) {
256
- capsule -> destructor (o );
280
+ capsule -> destructor (op );
257
281
}
258
- PyObject_Free ( o );
282
+ PyObject_GC_Del ( op );
259
283
}
260
284
261
285
@@ -279,6 +303,29 @@ capsule_repr(PyObject *o)
279
303
}
280
304
281
305
306
+ static int
307
+ capsule_traverse (PyCapsule * capsule , visitproc visit , void * arg )
308
+ {
309
+ if (capsule -> traverse_func ) {
310
+ return capsule -> traverse_func ((PyObject * )capsule , visit , arg );
311
+ }
312
+ else {
313
+ return 0 ;
314
+ }
315
+ }
316
+
317
+
318
+ static int
319
+ capsule_clear (PyCapsule * capsule )
320
+ {
321
+ if (capsule -> clear_func ) {
322
+ return capsule -> clear_func ((PyObject * )capsule );
323
+ }
324
+ else {
325
+ return 0 ;
326
+ }
327
+ }
328
+
282
329
283
330
PyDoc_STRVAR (PyCapsule_Type__doc__ ,
284
331
"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
@@ -293,27 +340,14 @@ Python import mechanism to link to one another.\n\
293
340
294
341
PyTypeObject PyCapsule_Type = {
295
342
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*/
343
+ .tp_name = "PyCapsule" ,
344
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,
345
+ .tp_basicsize = sizeof (PyCapsule ),
346
+ .tp_dealloc = capsule_dealloc ,
347
+ .tp_repr = capsule_repr ,
348
+ .tp_doc = PyCapsule_Type__doc__ ,
349
+ .tp_traverse = (traverseproc )capsule_traverse ,
350
+ .tp_clear = (inquiry )capsule_clear ,
317
351
};
318
352
319
353
0 commit comments