blob: f43b68d607f733d7968af629d035a2a054eafeb3 [file] [log] [blame]
Fred Drake8844d522001-10-05 21:52:26 +00001#include "Python.h"
2#include "structmember.h"
3
4
5#define GET_WEAKREFS_LISTPTR(o) \
6 ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
7
Fred Drake8844d522001-10-05 21:52:26 +00008
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009Py_ssize_t
Fred Drake8844d522001-10-05 21:52:26 +000010_PyWeakref_GetWeakrefCount(PyWeakReference *head)
11{
Thomas Wouters0e3f5912006-08-11 14:57:12 +000012 Py_ssize_t count = 0;
Fred Drake8844d522001-10-05 21:52:26 +000013
14 while (head != NULL) {
15 ++count;
16 head = head->wr_next;
17 }
18 return count;
19}
20
21
Fred Drake0a4dd392004-07-02 18:57:45 +000022static void
23init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback)
24{
25 self->hash = -1;
26 self->wr_object = ob;
27 Py_XINCREF(callback);
28 self->wr_callback = callback;
29}
30
Fred Drake8844d522001-10-05 21:52:26 +000031static PyWeakReference *
Neil Schemenauer38a89162002-03-27 15:18:21 +000032new_weakref(PyObject *ob, PyObject *callback)
Fred Drake8844d522001-10-05 21:52:26 +000033{
34 PyWeakReference *result;
35
Neil Schemenauer38a89162002-03-27 15:18:21 +000036 result = PyObject_GC_New(PyWeakReference, &_PyWeakref_RefType);
37 if (result) {
Fred Drake0a4dd392004-07-02 18:57:45 +000038 init_weakref(result, ob, callback);
Neil Schemenauer38a89162002-03-27 15:18:21 +000039 PyObject_GC_Track(result);
40 }
Fred Drake8844d522001-10-05 21:52:26 +000041 return result;
42}
43
44
45/* This function clears the passed-in reference and removes it from the
46 * list of weak references for the referent. This is the only code that
47 * removes an item from the doubly-linked list of weak references for an
48 * object; it is also responsible for clearing the callback slot.
49 */
50static void
51clear_weakref(PyWeakReference *self)
52{
53 PyObject *callback = self->wr_callback;
54
55 if (PyWeakref_GET_OBJECT(self) != Py_None) {
56 PyWeakReference **list = GET_WEAKREFS_LISTPTR(
57 PyWeakref_GET_OBJECT(self));
58
59 if (*list == self)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000060 /* If 'self' is the end of the list (and thus self->wr_next == NULL)
61 then the weakref list itself (and thus the value of *list) will
62 end up being set to NULL. */
Fred Drake8844d522001-10-05 21:52:26 +000063 *list = self->wr_next;
64 self->wr_object = Py_None;
Fred Drake8844d522001-10-05 21:52:26 +000065 if (self->wr_prev != NULL)
66 self->wr_prev->wr_next = self->wr_next;
67 if (self->wr_next != NULL)
68 self->wr_next->wr_prev = self->wr_prev;
69 self->wr_prev = NULL;
70 self->wr_next = NULL;
Tim Peters403a2032003-11-20 21:21:46 +000071 }
72 if (callback != NULL) {
73 Py_DECREF(callback);
74 self->wr_callback = NULL;
Fred Drake8844d522001-10-05 21:52:26 +000075 }
76}
77
Tim Peters403a2032003-11-20 21:21:46 +000078/* Cyclic gc uses this to *just* clear the passed-in reference, leaving
79 * the callback intact and uncalled. It must be possible to call self's
80 * tp_dealloc() after calling this, so self has to be left in a sane enough
81 * state for that to work. We expect tp_dealloc to decref the callback
82 * then. The reason for not letting clear_weakref() decref the callback
83 * right now is that if the callback goes away, that may in turn trigger
84 * another callback (if a weak reference to the callback exists) -- running
85 * arbitrary Python code in the middle of gc is a disaster. The convolution
86 * here allows gc to delay triggering such callbacks until the world is in
87 * a sane state again.
88 */
89void
90_PyWeakref_ClearRef(PyWeakReference *self)
91{
92 PyObject *callback;
93
94 assert(self != NULL);
95 assert(PyWeakref_Check(self));
96 /* Preserve and restore the callback around clear_weakref. */
97 callback = self->wr_callback;
98 self->wr_callback = NULL;
99 clear_weakref(self);
100 self->wr_callback = callback;
101}
Fred Drake8844d522001-10-05 21:52:26 +0000102
103static void
Fred Drake0a4dd392004-07-02 18:57:45 +0000104weakref_dealloc(PyObject *self)
Fred Drake8844d522001-10-05 21:52:26 +0000105{
Fred Drake0a4dd392004-07-02 18:57:45 +0000106 PyObject_GC_UnTrack(self);
107 clear_weakref((PyWeakReference *) self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000108 Py_TYPE(self)->tp_free(self);
Fred Drake8844d522001-10-05 21:52:26 +0000109}
110
111
112static int
113gc_traverse(PyWeakReference *self, visitproc visit, void *arg)
114{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000115 Py_VISIT(self->wr_callback);
Fred Drake8844d522001-10-05 21:52:26 +0000116 return 0;
117}
118
119
120static int
121gc_clear(PyWeakReference *self)
122{
123 clear_weakref(self);
124 return 0;
125}
126
127
128static PyObject *
129weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
130{
Martin v. Löwis15e62742006-02-27 16:46:16 +0000131 static char *kwlist[] = {NULL};
Fred Drake8844d522001-10-05 21:52:26 +0000132
Martin v. Löwis15e62742006-02-27 16:46:16 +0000133 if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", kwlist)) {
Fred Drake8844d522001-10-05 21:52:26 +0000134 PyObject *object = PyWeakref_GET_OBJECT(self);
135 Py_INCREF(object);
136 return (object);
137 }
138 return NULL;
139}
140
141
142static long
143weakref_hash(PyWeakReference *self)
144{
145 if (self->hash != -1)
146 return self->hash;
147 if (PyWeakref_GET_OBJECT(self) == Py_None) {
148 PyErr_SetString(PyExc_TypeError, "weak object has gone away");
149 return -1;
150 }
151 self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self));
152 return self->hash;
153}
Tim Peters403a2032003-11-20 21:21:46 +0000154
Fred Drake8844d522001-10-05 21:52:26 +0000155
156static PyObject *
157weakref_repr(PyWeakReference *self)
158{
159 char buffer[256];
160 if (PyWeakref_GET_OBJECT(self) == Py_None) {
Guido van Rossumc1f6e8c2003-04-16 21:13:23 +0000161 PyOS_snprintf(buffer, sizeof(buffer), "<weakref at %p; dead>", self);
Fred Drake8844d522001-10-05 21:52:26 +0000162 }
163 else {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000164 char *name = NULL;
165 PyObject *nameobj = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self),
166 "__name__");
167 if (nameobj == NULL)
168 PyErr_Clear();
169 else if (PyUnicode_Check(nameobj))
170 name = _PyUnicode_AsString(nameobj);
Barry Warsawd5867562001-11-28 21:01:56 +0000171 PyOS_snprintf(buffer, sizeof(buffer),
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000172 name ? "<weakref at %p; to '%.50s' at %p (%s)>"
173 : "<weakref at %p; to '%.50s' at %p>",
174 self,
175 Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name,
176 PyWeakref_GET_OBJECT(self),
177 name);
178 Py_XDECREF(nameobj);
Fred Drake8844d522001-10-05 21:52:26 +0000179 }
Walter Dörwald1ab83302007-05-18 17:15:44 +0000180 return PyUnicode_FromString(buffer);
Fred Drake8844d522001-10-05 21:52:26 +0000181}
182
183/* Weak references only support equality, not ordering. Two weak references
184 are equal if the underlying objects are equal. If the underlying object has
185 gone away, they are equal if they are identical. */
186
187static PyObject *
188weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
189{
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000190 if ((op != Py_EQ && op != Py_NE) ||
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000191 !PyWeakref_Check(self) ||
192 !PyWeakref_Check(other)) {
Fred Drake8844d522001-10-05 21:52:26 +0000193 Py_INCREF(Py_NotImplemented);
194 return Py_NotImplemented;
195 }
196 if (PyWeakref_GET_OBJECT(self) == Py_None
197 || PyWeakref_GET_OBJECT(other) == Py_None) {
198 PyObject *res = self==other ? Py_True : Py_False;
199 Py_INCREF(res);
200 return res;
201 }
202 return PyObject_RichCompare(PyWeakref_GET_OBJECT(self),
203 PyWeakref_GET_OBJECT(other), op);
204}
205
Fred Drake0a4dd392004-07-02 18:57:45 +0000206/* Given the head of an object's list of weak references, extract the
207 * two callback-less refs (ref and proxy). Used to determine if the
208 * shared references exist and to determine the back link for newly
209 * inserted references.
210 */
211static void
212get_basic_refs(PyWeakReference *head,
213 PyWeakReference **refp, PyWeakReference **proxyp)
214{
215 *refp = NULL;
216 *proxyp = NULL;
217
218 if (head != NULL && head->wr_callback == NULL) {
219 /* We need to be careful that the "basic refs" aren't
220 subclasses of the main types. That complicates this a
221 little. */
222 if (PyWeakref_CheckRefExact(head)) {
223 *refp = head;
224 head = head->wr_next;
225 }
226 if (head != NULL
227 && head->wr_callback == NULL
228 && PyWeakref_CheckProxy(head)) {
229 *proxyp = head;
230 /* head = head->wr_next; */
231 }
232 }
233}
234
235/* Insert 'newref' in the list after 'prev'. Both must be non-NULL. */
236static void
237insert_after(PyWeakReference *newref, PyWeakReference *prev)
238{
239 newref->wr_prev = prev;
240 newref->wr_next = prev->wr_next;
241 if (prev->wr_next != NULL)
242 prev->wr_next->wr_prev = newref;
243 prev->wr_next = newref;
244}
245
246/* Insert 'newref' at the head of the list; 'list' points to the variable
247 * that stores the head.
248 */
249static void
250insert_head(PyWeakReference *newref, PyWeakReference **list)
251{
252 PyWeakReference *next = *list;
253
254 newref->wr_prev = NULL;
255 newref->wr_next = next;
256 if (next != NULL)
257 next->wr_prev = newref;
258 *list = newref;
259}
260
261static int
262parse_weakref_init_args(char *funcname, PyObject *args, PyObject *kwargs,
263 PyObject **obp, PyObject **callbackp)
264{
265 /* XXX Should check that kwargs == NULL or is empty. */
266 return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp);
267}
268
269static PyObject *
270weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
271{
272 PyWeakReference *self = NULL;
273 PyObject *ob, *callback = NULL;
274
275 if (parse_weakref_init_args("__new__", args, kwargs, &ob, &callback)) {
276 PyWeakReference *ref, *proxy;
277 PyWeakReference **list;
278
Christian Heimes90aa7642007-12-19 02:45:37 +0000279 if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
Fred Drake0a4dd392004-07-02 18:57:45 +0000280 PyErr_Format(PyExc_TypeError,
281 "cannot create weak reference to '%s' object",
Christian Heimes90aa7642007-12-19 02:45:37 +0000282 Py_TYPE(ob)->tp_name);
Fred Drake0a4dd392004-07-02 18:57:45 +0000283 return NULL;
284 }
285 if (callback == Py_None)
286 callback = NULL;
287 list = GET_WEAKREFS_LISTPTR(ob);
288 get_basic_refs(*list, &ref, &proxy);
289 if (callback == NULL && type == &_PyWeakref_RefType) {
290 if (ref != NULL) {
291 /* We can re-use an existing reference. */
292 Py_INCREF(ref);
293 return (PyObject *)ref;
294 }
295 }
296 /* We have to create a new reference. */
297 /* Note: the tp_alloc() can trigger cyclic GC, so the weakref
298 list on ob can be mutated. This means that the ref and
299 proxy pointers we got back earlier may have been collected,
300 so we need to compute these values again before we use
301 them. */
302 self = (PyWeakReference *) (type->tp_alloc(type, 0));
303 if (self != NULL) {
304 init_weakref(self, ob, callback);
305 if (callback == NULL && type == &_PyWeakref_RefType) {
306 insert_head(self, list);
307 }
308 else {
309 PyWeakReference *prev;
310
311 get_basic_refs(*list, &ref, &proxy);
312 prev = (proxy == NULL) ? ref : proxy;
313 if (prev == NULL)
314 insert_head(self, list);
315 else
316 insert_after(self, prev);
317 }
318 }
319 }
320 return (PyObject *)self;
321}
322
323static int
324weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs)
325{
326 PyObject *tmp;
327
328 if (parse_weakref_init_args("__init__", args, kwargs, &tmp, &tmp))
329 return 0;
330 else
Benjamin Peterson9aa42992008-09-10 21:57:34 +0000331 return -1;
Fred Drake0a4dd392004-07-02 18:57:45 +0000332}
333
Fred Drake8844d522001-10-05 21:52:26 +0000334
335PyTypeObject
336_PyWeakref_RefType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000337 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Fred Drake8844d522001-10-05 21:52:26 +0000338 "weakref",
339 sizeof(PyWeakReference),
340 0,
Fred Drake0a4dd392004-07-02 18:57:45 +0000341 weakref_dealloc, /*tp_dealloc*/
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000342 0, /*tp_print*/
Fred Drake8844d522001-10-05 21:52:26 +0000343 0, /*tp_getattr*/
344 0, /*tp_setattr*/
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000345 0, /*tp_reserved*/
Fred Drake8844d522001-10-05 21:52:26 +0000346 (reprfunc)weakref_repr, /*tp_repr*/
347 0, /*tp_as_number*/
348 0, /*tp_as_sequence*/
349 0, /*tp_as_mapping*/
Fred Drake0a4dd392004-07-02 18:57:45 +0000350 (hashfunc)weakref_hash, /*tp_hash*/
Fred Drake8844d522001-10-05 21:52:26 +0000351 (ternaryfunc)weakref_call, /*tp_call*/
352 0, /*tp_str*/
353 0, /*tp_getattro*/
354 0, /*tp_setattro*/
355 0, /*tp_as_buffer*/
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000356 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
Fred Drake0a4dd392004-07-02 18:57:45 +0000357 | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Fred Drake8844d522001-10-05 21:52:26 +0000358 0, /*tp_doc*/
359 (traverseproc)gc_traverse, /*tp_traverse*/
360 (inquiry)gc_clear, /*tp_clear*/
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000361 (richcmpfunc)weakref_richcompare, /*tp_richcompare*/
Fred Drake0a4dd392004-07-02 18:57:45 +0000362 0, /*tp_weaklistoffset*/
363 0, /*tp_iter*/
364 0, /*tp_iternext*/
365 0, /*tp_methods*/
366 0, /*tp_members*/
367 0, /*tp_getset*/
368 0, /*tp_base*/
369 0, /*tp_dict*/
370 0, /*tp_descr_get*/
371 0, /*tp_descr_set*/
372 0, /*tp_dictoffset*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 weakref___init__, /*tp_init*/
Fred Drake0a4dd392004-07-02 18:57:45 +0000374 PyType_GenericAlloc, /*tp_alloc*/
375 weakref___new__, /*tp_new*/
376 PyObject_GC_Del, /*tp_free*/
Fred Drake8844d522001-10-05 21:52:26 +0000377};
378
379
380static int
381proxy_checkref(PyWeakReference *proxy)
382{
383 if (PyWeakref_GET_OBJECT(proxy) == Py_None) {
384 PyErr_SetString(PyExc_ReferenceError,
385 "weakly-referenced object no longer exists");
386 return 0;
387 }
388 return 1;
389}
390
391
Fred Drake73006d02001-10-18 18:04:18 +0000392/* If a parameter is a proxy, check that it is still "live" and wrap it,
393 * replacing the original value with the raw object. Raises ReferenceError
394 * if the param is a dead proxy.
395 */
396#define UNWRAP(o) \
397 if (PyWeakref_CheckProxy(o)) { \
398 if (!proxy_checkref((PyWeakReference *)o)) \
399 return NULL; \
400 o = PyWeakref_GET_OBJECT(o); \
401 }
402
Fred Drake2a908f62001-12-19 16:44:30 +0000403#define UNWRAP_I(o) \
404 if (PyWeakref_CheckProxy(o)) { \
405 if (!proxy_checkref((PyWeakReference *)o)) \
406 return -1; \
407 o = PyWeakref_GET_OBJECT(o); \
408 }
409
Fred Drake8844d522001-10-05 21:52:26 +0000410#define WRAP_UNARY(method, generic) \
411 static PyObject * \
Fred Drake73006d02001-10-18 18:04:18 +0000412 method(PyObject *proxy) { \
413 UNWRAP(proxy); \
414 return generic(proxy); \
Fred Drake8844d522001-10-05 21:52:26 +0000415 }
416
417#define WRAP_BINARY(method, generic) \
418 static PyObject * \
Fred Drake73006d02001-10-18 18:04:18 +0000419 method(PyObject *x, PyObject *y) { \
420 UNWRAP(x); \
421 UNWRAP(y); \
422 return generic(x, y); \
Fred Drake8844d522001-10-05 21:52:26 +0000423 }
424
Fred Drake31f4d1f2001-10-18 19:21:46 +0000425/* Note that the third arg needs to be checked for NULL since the tp_call
426 * slot can receive NULL for this arg.
Fred Drake73006d02001-10-18 18:04:18 +0000427 */
Fred Drake8844d522001-10-05 21:52:26 +0000428#define WRAP_TERNARY(method, generic) \
429 static PyObject * \
Fred Drake73006d02001-10-18 18:04:18 +0000430 method(PyObject *proxy, PyObject *v, PyObject *w) { \
431 UNWRAP(proxy); \
Fred Drake31f4d1f2001-10-18 19:21:46 +0000432 UNWRAP(v); \
Fred Drake73006d02001-10-18 18:04:18 +0000433 if (w != NULL) \
434 UNWRAP(w); \
435 return generic(proxy, v, w); \
Fred Drake8844d522001-10-05 21:52:26 +0000436 }
437
Benjamin Petersona1f9c042009-11-19 03:10:36 +0000438#define WRAP_METHOD(method, special) \
439 static PyObject * \
440 method(PyObject *proxy) { \
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000441 UNWRAP(proxy); \
442 return PyObject_CallMethod(proxy, special, ""); \
443 }
Benjamin Petersona1f9c042009-11-19 03:10:36 +0000444
Fred Drake8844d522001-10-05 21:52:26 +0000445
446/* direct slots */
447
448WRAP_BINARY(proxy_getattr, PyObject_GetAttr)
449WRAP_UNARY(proxy_str, PyObject_Str)
450WRAP_TERNARY(proxy_call, PyEval_CallObjectWithKeywords)
451
Fred Drake8844d522001-10-05 21:52:26 +0000452static PyObject *
453proxy_repr(PyWeakReference *proxy)
454{
455 char buf[160];
Barry Warsawd5867562001-11-28 21:01:56 +0000456 PyOS_snprintf(buf, sizeof(buf),
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000457 "<weakproxy at %p to %.100s at %p>", proxy,
458 Py_TYPE(PyWeakref_GET_OBJECT(proxy))->tp_name,
459 PyWeakref_GET_OBJECT(proxy));
Walter Dörwald1ab83302007-05-18 17:15:44 +0000460 return PyUnicode_FromString(buf);
Fred Drake8844d522001-10-05 21:52:26 +0000461}
462
463
464static int
465proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value)
466{
467 if (!proxy_checkref(proxy))
468 return -1;
469 return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value);
470}
471
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000472static PyObject *
473proxy_richcompare(PyObject *proxy, PyObject *v, int op)
Fred Drake8844d522001-10-05 21:52:26 +0000474{
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000475 UNWRAP(proxy);
476 UNWRAP(v);
477 return PyObject_RichCompare(proxy, v, op);
Fred Drake8844d522001-10-05 21:52:26 +0000478}
479
480/* number slots */
481WRAP_BINARY(proxy_add, PyNumber_Add)
482WRAP_BINARY(proxy_sub, PyNumber_Subtract)
483WRAP_BINARY(proxy_mul, PyNumber_Multiply)
Georg Brandlb533e262008-05-25 18:19:30 +0000484WRAP_BINARY(proxy_floor_div, PyNumber_FloorDivide)
485WRAP_BINARY(proxy_true_div, PyNumber_TrueDivide)
Fred Drake8844d522001-10-05 21:52:26 +0000486WRAP_BINARY(proxy_mod, PyNumber_Remainder)
487WRAP_BINARY(proxy_divmod, PyNumber_Divmod)
488WRAP_TERNARY(proxy_pow, PyNumber_Power)
489WRAP_UNARY(proxy_neg, PyNumber_Negative)
490WRAP_UNARY(proxy_pos, PyNumber_Positive)
491WRAP_UNARY(proxy_abs, PyNumber_Absolute)
492WRAP_UNARY(proxy_invert, PyNumber_Invert)
493WRAP_BINARY(proxy_lshift, PyNumber_Lshift)
494WRAP_BINARY(proxy_rshift, PyNumber_Rshift)
495WRAP_BINARY(proxy_and, PyNumber_And)
496WRAP_BINARY(proxy_xor, PyNumber_Xor)
497WRAP_BINARY(proxy_or, PyNumber_Or)
Mark Dickinson17c7cd82009-01-17 21:57:11 +0000498WRAP_UNARY(proxy_int, PyNumber_Long)
Fred Drake8844d522001-10-05 21:52:26 +0000499WRAP_UNARY(proxy_float, PyNumber_Float)
500WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd)
501WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract)
502WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply)
Georg Brandlb533e262008-05-25 18:19:30 +0000503WRAP_BINARY(proxy_ifloor_div, PyNumber_InPlaceFloorDivide)
504WRAP_BINARY(proxy_itrue_div, PyNumber_InPlaceTrueDivide)
Fred Drake8844d522001-10-05 21:52:26 +0000505WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder)
506WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower)
507WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift)
508WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift)
509WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd)
510WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)
511WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
Georg Brandlb533e262008-05-25 18:19:30 +0000512WRAP_UNARY(proxy_index, PyNumber_Index)
Fred Drake8844d522001-10-05 21:52:26 +0000513
Tim Peters403a2032003-11-20 21:21:46 +0000514static int
Jack Diederich4dafcc42006-11-28 19:15:13 +0000515proxy_bool(PyWeakReference *proxy)
Fred Drake8844d522001-10-05 21:52:26 +0000516{
517 PyObject *o = PyWeakref_GET_OBJECT(proxy);
518 if (!proxy_checkref(proxy))
Neal Norwitzbdcb9412004-07-08 01:22:31 +0000519 return -1;
Raymond Hettingere6c470f2005-03-27 03:04:54 +0000520 return PyObject_IsTrue(o);
Fred Drake8844d522001-10-05 21:52:26 +0000521}
522
Fred Drake0a4dd392004-07-02 18:57:45 +0000523static void
524proxy_dealloc(PyWeakReference *self)
525{
526 if (self->wr_callback != NULL)
527 PyObject_GC_UnTrack((PyObject *)self);
528 clear_weakref(self);
529 PyObject_GC_Del(self);
530}
531
Fred Drake8844d522001-10-05 21:52:26 +0000532/* sequence slots */
533
Fred Drake8844d522001-10-05 21:52:26 +0000534static int
535proxy_contains(PyWeakReference *proxy, PyObject *value)
536{
537 if (!proxy_checkref(proxy))
538 return -1;
539 return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value);
540}
541
542
543/* mapping slots */
544
Martin v. Löwis18e16552006-02-15 17:27:45 +0000545static Py_ssize_t
Fred Drake8844d522001-10-05 21:52:26 +0000546proxy_length(PyWeakReference *proxy)
547{
548 if (!proxy_checkref(proxy))
549 return -1;
550 return PyObject_Length(PyWeakref_GET_OBJECT(proxy));
551}
552
553WRAP_BINARY(proxy_getitem, PyObject_GetItem)
554
555static int
556proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value)
557{
558 if (!proxy_checkref(proxy))
559 return -1;
Raymond Hettingerd693a812003-06-30 04:18:48 +0000560
561 if (value == NULL)
562 return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key);
563 else
564 return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value);
Fred Drake8844d522001-10-05 21:52:26 +0000565}
566
Fred Drakef16c3dc2002-08-09 18:34:16 +0000567/* iterator slots */
568
569static PyObject *
570proxy_iter(PyWeakReference *proxy)
571{
572 if (!proxy_checkref(proxy))
573 return NULL;
574 return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy));
575}
576
577static PyObject *
578proxy_iternext(PyWeakReference *proxy)
579{
580 if (!proxy_checkref(proxy))
581 return NULL;
582 return PyIter_Next(PyWeakref_GET_OBJECT(proxy));
583}
584
Fred Drake8844d522001-10-05 21:52:26 +0000585
Benjamin Petersona1f9c042009-11-19 03:10:36 +0000586WRAP_METHOD(proxy_bytes, "__bytes__");
587
588
589static PyMethodDef proxy_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000590 {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS},
591 {NULL, NULL}
Benjamin Petersona1f9c042009-11-19 03:10:36 +0000592};
593
594
Fred Drake8844d522001-10-05 21:52:26 +0000595static PyNumberMethods proxy_as_number = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000596 proxy_add, /*nb_add*/
597 proxy_sub, /*nb_subtract*/
598 proxy_mul, /*nb_multiply*/
599 proxy_mod, /*nb_remainder*/
600 proxy_divmod, /*nb_divmod*/
601 proxy_pow, /*nb_power*/
602 proxy_neg, /*nb_negative*/
603 proxy_pos, /*nb_positive*/
604 proxy_abs, /*nb_absolute*/
Jack Diederich4dafcc42006-11-28 19:15:13 +0000605 (inquiry)proxy_bool, /*nb_bool*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000606 proxy_invert, /*nb_invert*/
607 proxy_lshift, /*nb_lshift*/
608 proxy_rshift, /*nb_rshift*/
609 proxy_and, /*nb_and*/
610 proxy_xor, /*nb_xor*/
611 proxy_or, /*nb_or*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000612 proxy_int, /*nb_int*/
Mark Dickinson8055afd2009-01-17 10:04:45 +0000613 0, /*nb_reserved*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000614 proxy_float, /*nb_float*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000615 proxy_iadd, /*nb_inplace_add*/
616 proxy_isub, /*nb_inplace_subtract*/
617 proxy_imul, /*nb_inplace_multiply*/
618 proxy_imod, /*nb_inplace_remainder*/
619 proxy_ipow, /*nb_inplace_power*/
620 proxy_ilshift, /*nb_inplace_lshift*/
621 proxy_irshift, /*nb_inplace_rshift*/
622 proxy_iand, /*nb_inplace_and*/
623 proxy_ixor, /*nb_inplace_xor*/
624 proxy_ior, /*nb_inplace_or*/
Georg Brandlb533e262008-05-25 18:19:30 +0000625 proxy_floor_div, /*nb_floor_divide*/
626 proxy_true_div, /*nb_true_divide*/
627 proxy_ifloor_div, /*nb_inplace_floor_divide*/
628 proxy_itrue_div, /*nb_inplace_true_divide*/
629 proxy_index, /*nb_index*/
Fred Drake8844d522001-10-05 21:52:26 +0000630};
631
632static PySequenceMethods proxy_as_sequence = {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000633 (lenfunc)proxy_length, /*sq_length*/
Fred Drake8844d522001-10-05 21:52:26 +0000634 0, /*sq_concat*/
635 0, /*sq_repeat*/
636 0, /*sq_item*/
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000637 0, /*sq_slice*/
Fred Drake8844d522001-10-05 21:52:26 +0000638 0, /*sq_ass_item*/
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000639 0, /*sq_ass_slice*/
Fred Drake8844d522001-10-05 21:52:26 +0000640 (objobjproc)proxy_contains, /* sq_contains */
641};
642
643static PyMappingMethods proxy_as_mapping = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000644 (lenfunc)proxy_length, /*mp_length*/
645 proxy_getitem, /*mp_subscript*/
Fred Drake8844d522001-10-05 21:52:26 +0000646 (objobjargproc)proxy_setitem, /*mp_ass_subscript*/
647};
648
649
650PyTypeObject
651_PyWeakref_ProxyType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000652 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Fred Drake8844d522001-10-05 21:52:26 +0000653 "weakproxy",
654 sizeof(PyWeakReference),
655 0,
656 /* methods */
Fred Drake0a4dd392004-07-02 18:57:45 +0000657 (destructor)proxy_dealloc, /* tp_dealloc */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000658 0, /* tp_print */
659 0, /* tp_getattr */
660 0, /* tp_setattr */
661 0, /* tp_reserved */
662 (reprfunc)proxy_repr, /* tp_repr */
663 &proxy_as_number, /* tp_as_number */
664 &proxy_as_sequence, /* tp_as_sequence */
665 &proxy_as_mapping, /* tp_as_mapping */
666 0, /* tp_hash */
667 0, /* tp_call */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000668 proxy_str, /* tp_str */
669 proxy_getattr, /* tp_getattro */
Fred Drakef16c3dc2002-08-09 18:34:16 +0000670 (setattrofunc)proxy_setattr, /* tp_setattro */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000671 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Fred Drakef16c3dc2002-08-09 18:34:16 +0000673 0, /* tp_doc */
674 (traverseproc)gc_traverse, /* tp_traverse */
675 (inquiry)gc_clear, /* tp_clear */
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000676 proxy_richcompare, /* tp_richcompare */
Fred Drakef16c3dc2002-08-09 18:34:16 +0000677 0, /* tp_weaklistoffset */
678 (getiterfunc)proxy_iter, /* tp_iter */
679 (iternextfunc)proxy_iternext, /* tp_iternext */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000680 proxy_methods, /* tp_methods */
Fred Drake8844d522001-10-05 21:52:26 +0000681};
682
683
684PyTypeObject
685_PyWeakref_CallableProxyType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000686 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Fred Drake8844d522001-10-05 21:52:26 +0000687 "weakcallableproxy",
688 sizeof(PyWeakReference),
689 0,
690 /* methods */
Fred Drake0a4dd392004-07-02 18:57:45 +0000691 (destructor)proxy_dealloc, /* tp_dealloc */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000692 0, /* tp_print */
693 0, /* tp_getattr */
694 0, /* tp_setattr */
695 0, /* tp_reserved */
696 (unaryfunc)proxy_repr, /* tp_repr */
697 &proxy_as_number, /* tp_as_number */
698 &proxy_as_sequence, /* tp_as_sequence */
699 &proxy_as_mapping, /* tp_as_mapping */
700 0, /* tp_hash */
701 proxy_call, /* tp_call */
702 proxy_str, /* tp_str */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000703 proxy_getattr, /* tp_getattro */
Fred Drakef16c3dc2002-08-09 18:34:16 +0000704 (setattrofunc)proxy_setattr, /* tp_setattro */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000705 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000706 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Fred Drakef16c3dc2002-08-09 18:34:16 +0000707 0, /* tp_doc */
708 (traverseproc)gc_traverse, /* tp_traverse */
709 (inquiry)gc_clear, /* tp_clear */
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000710 proxy_richcompare, /* tp_richcompare */
Fred Drakef16c3dc2002-08-09 18:34:16 +0000711 0, /* tp_weaklistoffset */
712 (getiterfunc)proxy_iter, /* tp_iter */
713 (iternextfunc)proxy_iternext, /* tp_iternext */
Fred Drake8844d522001-10-05 21:52:26 +0000714};
715
716
Fred Drake8844d522001-10-05 21:52:26 +0000717
718PyObject *
719PyWeakref_NewRef(PyObject *ob, PyObject *callback)
720{
721 PyWeakReference *result = NULL;
722 PyWeakReference **list;
723 PyWeakReference *ref, *proxy;
724
Christian Heimes90aa7642007-12-19 02:45:37 +0000725 if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
Fred Drake8844d522001-10-05 21:52:26 +0000726 PyErr_Format(PyExc_TypeError,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000727 "cannot create weak reference to '%s' object",
Christian Heimes90aa7642007-12-19 02:45:37 +0000728 Py_TYPE(ob)->tp_name);
Fred Drake8844d522001-10-05 21:52:26 +0000729 return NULL;
730 }
731 list = GET_WEAKREFS_LISTPTR(ob);
732 get_basic_refs(*list, &ref, &proxy);
Fred Drake6a2852c2004-02-03 19:52:56 +0000733 if (callback == Py_None)
734 callback = NULL;
735 if (callback == NULL)
Fred Drake8844d522001-10-05 21:52:26 +0000736 /* return existing weak reference if it exists */
737 result = ref;
738 if (result != NULL)
Fred Drakebc875f52004-02-04 23:14:14 +0000739 Py_INCREF(result);
Fred Drake8844d522001-10-05 21:52:26 +0000740 else {
Fred Drakebc875f52004-02-04 23:14:14 +0000741 /* Note: new_weakref() can trigger cyclic GC, so the weakref
742 list on ob can be mutated. This means that the ref and
743 proxy pointers we got back earlier may have been collected,
744 so we need to compute these values again before we use
745 them. */
Neil Schemenauer38a89162002-03-27 15:18:21 +0000746 result = new_weakref(ob, callback);
Fred Drake8844d522001-10-05 21:52:26 +0000747 if (result != NULL) {
Fred Drake6d3265d2004-08-03 14:47:25 +0000748 get_basic_refs(*list, &ref, &proxy);
Fred Drake8844d522001-10-05 21:52:26 +0000749 if (callback == NULL) {
Fred Drake6d3265d2004-08-03 14:47:25 +0000750 if (ref == NULL)
751 insert_head(result, list);
752 else {
753 /* Someone else added a ref without a callback
754 during GC. Return that one instead of this one
755 to avoid violating the invariants of the list
756 of weakrefs for ob. */
757 Py_DECREF(result);
758 Py_INCREF(ref);
759 result = ref;
760 }
Fred Drake8844d522001-10-05 21:52:26 +0000761 }
762 else {
Fred Drakebc875f52004-02-04 23:14:14 +0000763 PyWeakReference *prev;
Fred Drake8844d522001-10-05 21:52:26 +0000764
Fred Drakebc875f52004-02-04 23:14:14 +0000765 prev = (proxy == NULL) ? ref : proxy;
Fred Drake8844d522001-10-05 21:52:26 +0000766 if (prev == NULL)
767 insert_head(result, list);
768 else
769 insert_after(result, prev);
770 }
Fred Drake8844d522001-10-05 21:52:26 +0000771 }
772 }
773 return (PyObject *) result;
774}
775
776
777PyObject *
778PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
779{
780 PyWeakReference *result = NULL;
781 PyWeakReference **list;
782 PyWeakReference *ref, *proxy;
783
Christian Heimes90aa7642007-12-19 02:45:37 +0000784 if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
Fred Drake8844d522001-10-05 21:52:26 +0000785 PyErr_Format(PyExc_TypeError,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000786 "cannot create weak reference to '%s' object",
Christian Heimes90aa7642007-12-19 02:45:37 +0000787 Py_TYPE(ob)->tp_name);
Fred Drake8844d522001-10-05 21:52:26 +0000788 return NULL;
789 }
790 list = GET_WEAKREFS_LISTPTR(ob);
791 get_basic_refs(*list, &ref, &proxy);
Fred Drake6a2852c2004-02-03 19:52:56 +0000792 if (callback == Py_None)
793 callback = NULL;
Fred Drake8844d522001-10-05 21:52:26 +0000794 if (callback == NULL)
795 /* attempt to return an existing weak reference if it exists */
796 result = proxy;
797 if (result != NULL)
Fred Drakebc875f52004-02-04 23:14:14 +0000798 Py_INCREF(result);
Fred Drake8844d522001-10-05 21:52:26 +0000799 else {
Fred Drakebc875f52004-02-04 23:14:14 +0000800 /* Note: new_weakref() can trigger cyclic GC, so the weakref
801 list on ob can be mutated. This means that the ref and
802 proxy pointers we got back earlier may have been collected,
803 so we need to compute these values again before we use
804 them. */
Neil Schemenauer38a89162002-03-27 15:18:21 +0000805 result = new_weakref(ob, callback);
Fred Drake8844d522001-10-05 21:52:26 +0000806 if (result != NULL) {
807 PyWeakReference *prev;
808
809 if (PyCallable_Check(ob))
Christian Heimes90aa7642007-12-19 02:45:37 +0000810 Py_TYPE(result) = &_PyWeakref_CallableProxyType;
Fred Drake8844d522001-10-05 21:52:26 +0000811 else
Christian Heimes90aa7642007-12-19 02:45:37 +0000812 Py_TYPE(result) = &_PyWeakref_ProxyType;
Fred Drakebc875f52004-02-04 23:14:14 +0000813 get_basic_refs(*list, &ref, &proxy);
Fred Drake6d3265d2004-08-03 14:47:25 +0000814 if (callback == NULL) {
815 if (proxy != NULL) {
816 /* Someone else added a proxy without a callback
817 during GC. Return that one instead of this one
818 to avoid violating the invariants of the list
819 of weakrefs for ob. */
820 Py_DECREF(result);
821 Py_INCREF(result = proxy);
822 goto skip_insert;
823 }
Fred Drake8844d522001-10-05 21:52:26 +0000824 prev = ref;
Fred Drake6d3265d2004-08-03 14:47:25 +0000825 }
Fred Drake8844d522001-10-05 21:52:26 +0000826 else
827 prev = (proxy == NULL) ? ref : proxy;
828
829 if (prev == NULL)
830 insert_head(result, list);
831 else
832 insert_after(result, prev);
Fred Drake6d3265d2004-08-03 14:47:25 +0000833 skip_insert:
834 ;
Fred Drake8844d522001-10-05 21:52:26 +0000835 }
836 }
837 return (PyObject *) result;
838}
839
840
841PyObject *
842PyWeakref_GetObject(PyObject *ref)
843{
844 if (ref == NULL || !PyWeakref_Check(ref)) {
845 PyErr_BadInternalCall();
846 return NULL;
847 }
848 return PyWeakref_GET_OBJECT(ref);
849}
850
Tim Petersead8b7a2004-10-30 23:09:22 +0000851/* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's
852 * handle_weakrefs().
853 */
Fred Drakeef8ebd12001-12-10 23:44:54 +0000854static void
855handle_callback(PyWeakReference *ref, PyObject *callback)
856{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000857 PyObject *cbresult = PyObject_CallFunctionObjArgs(callback, ref, NULL);
Fred Drakeef8ebd12001-12-10 23:44:54 +0000858
859 if (cbresult == NULL)
860 PyErr_WriteUnraisable(callback);
861 else
862 Py_DECREF(cbresult);
863}
864
865/* This function is called by the tp_dealloc handler to clear weak references.
Fred Drake8844d522001-10-05 21:52:26 +0000866 *
867 * This iterates through the weak references for 'object' and calls callbacks
868 * for those references which have one. It returns when all callbacks have
869 * been attempted.
870 */
871void
872PyObject_ClearWeakRefs(PyObject *object)
873{
874 PyWeakReference **list;
875
876 if (object == NULL
Christian Heimes90aa7642007-12-19 02:45:37 +0000877 || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
Fred Drake8844d522001-10-05 21:52:26 +0000878 || object->ob_refcnt != 0) {
879 PyErr_BadInternalCall();
880 return;
881 }
882 list = GET_WEAKREFS_LISTPTR(object);
883 /* Remove the callback-less basic and proxy references */
884 if (*list != NULL && (*list)->wr_callback == NULL) {
885 clear_weakref(*list);
886 if (*list != NULL && (*list)->wr_callback == NULL)
887 clear_weakref(*list);
888 }
889 if (*list != NULL) {
Fred Drakeef8ebd12001-12-10 23:44:54 +0000890 PyWeakReference *current = *list;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000891 Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
Fred Drakeef8ebd12001-12-10 23:44:54 +0000892 int restore_error = PyErr_Occurred() ? 1 : 0;
893 PyObject *err_type, *err_value, *err_tb;
Fred Drake8844d522001-10-05 21:52:26 +0000894
Fred Drakeef8ebd12001-12-10 23:44:54 +0000895 if (restore_error)
896 PyErr_Fetch(&err_type, &err_value, &err_tb);
Fred Drake8844d522001-10-05 21:52:26 +0000897 if (count == 1) {
Fred Drake8844d522001-10-05 21:52:26 +0000898 PyObject *callback = current->wr_callback;
Fred Drake8844d522001-10-05 21:52:26 +0000899
Fred Drakeef8ebd12001-12-10 23:44:54 +0000900 current->wr_callback = NULL;
Fred Drake8844d522001-10-05 21:52:26 +0000901 clear_weakref(current);
Fred Drake0a4dd392004-07-02 18:57:45 +0000902 if (callback != NULL) {
Benjamin Petersona38d1562008-06-16 20:47:12 +0000903 if (((PyObject *)current)->ob_refcnt > 0)
Amaury Forgeot d'Arcc856c7a2008-06-16 19:50:09 +0000904 handle_callback(current, callback);
Fred Drake0a4dd392004-07-02 18:57:45 +0000905 Py_DECREF(callback);
906 }
Fred Drake8844d522001-10-05 21:52:26 +0000907 }
908 else {
Hye-Shik Chang4af5c8c2006-03-07 15:39:21 +0000909 PyObject *tuple;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000910 Py_ssize_t i = 0;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000911
Hye-Shik Chang4af5c8c2006-03-07 15:39:21 +0000912 tuple = PyTuple_New(count * 2);
913 if (tuple == NULL) {
914 if (restore_error)
915 PyErr_Fetch(&err_type, &err_value, &err_tb);
916 return;
917 }
Fred Drake8844d522001-10-05 21:52:26 +0000918
919 for (i = 0; i < count; ++i) {
920 PyWeakReference *next = current->wr_next;
921
Benjamin Petersona38d1562008-06-16 20:47:12 +0000922 if (((PyObject *)current)->ob_refcnt > 0)
Amaury Forgeot d'Arcc856c7a2008-06-16 19:50:09 +0000923 {
924 Py_INCREF(current);
925 PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
926 PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
927 }
928 else {
929 Py_DECREF(current->wr_callback);
930 }
Fred Drake8844d522001-10-05 21:52:26 +0000931 current->wr_callback = NULL;
Fred Drake8844d522001-10-05 21:52:26 +0000932 clear_weakref(current);
933 current = next;
934 }
935 for (i = 0; i < count; ++i) {
Fred Drake8844d522001-10-05 21:52:26 +0000936 PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
Fred Drakeef8ebd12001-12-10 23:44:54 +0000937
Amaury Forgeot d'Arcc856c7a2008-06-16 19:50:09 +0000938 /* The tuple may have slots left to NULL */
Fred Drake0a4dd392004-07-02 18:57:45 +0000939 if (callback != NULL) {
Neal Norwitz0c6e2f12006-01-08 06:13:44 +0000940 PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
941 handle_callback((PyWeakReference *)item, callback);
Fred Drake0a4dd392004-07-02 18:57:45 +0000942 }
Fred Drake8844d522001-10-05 21:52:26 +0000943 }
944 Py_DECREF(tuple);
945 }
Fred Drakeef8ebd12001-12-10 23:44:54 +0000946 if (restore_error)
947 PyErr_Restore(err_type, err_value, err_tb);
Fred Drake8844d522001-10-05 21:52:26 +0000948 }
949}