@@ -145,11 +145,14 @@ weakref_hash(PyWeakReference *self)
145145{
146146 if (self -> hash != -1 )
147147 return self -> hash ;
148- if (PyWeakref_GET_OBJECT (self ) == Py_None ) {
148+ PyObject * obj = PyWeakref_GET_OBJECT (self );
149+ if (obj == Py_None ) {
149150 PyErr_SetString (PyExc_TypeError , "weak object has gone away" );
150151 return -1 ;
151152 }
152- self -> hash = PyObject_Hash (PyWeakref_GET_OBJECT (self ));
153+ Py_INCREF (obj );
154+ self -> hash = PyObject_Hash (obj );
155+ Py_DECREF (obj );
153156 return self -> hash ;
154157}
155158
@@ -159,28 +162,36 @@ weakref_repr(PyWeakReference *self)
159162{
160163 PyObject * name , * repr ;
161164 _Py_IDENTIFIER (__name__ );
165+ PyObject * obj = PyWeakref_GET_OBJECT (self );
162166
163- if (PyWeakref_GET_OBJECT ( self ) == Py_None )
167+ if (obj == Py_None ) {
164168 return PyUnicode_FromFormat ("<weakref at %p; dead>" , self );
169+ }
170+
171+ Py_INCREF (obj );
172+ if (_PyObject_LookupAttrId (obj , & PyId___name__ , & name ) < 0 ) {
173+ Py_DECREF (obj );
174+ return NULL ;
175+ }
165176
166- name = _PyObject_GetAttrId (PyWeakref_GET_OBJECT (self ), & PyId___name__ );
167177 if (name == NULL || !PyUnicode_Check (name )) {
168178 if (name == NULL )
169179 PyErr_Clear ();
170180 repr = PyUnicode_FromFormat (
171181 "<weakref at %p; to '%s' at %p>" ,
172182 self ,
173183 Py_TYPE (PyWeakref_GET_OBJECT (self ))-> tp_name ,
174- PyWeakref_GET_OBJECT ( self ) );
184+ obj );
175185 }
176186 else {
177187 repr = PyUnicode_FromFormat (
178188 "<weakref at %p; to '%s' at %p (%U)>" ,
179189 self ,
180190 Py_TYPE (PyWeakref_GET_OBJECT (self ))-> tp_name ,
181- PyWeakref_GET_OBJECT ( self ) ,
191+ obj ,
182192 name );
183193 }
194+ Py_DECREF (obj );
184195 Py_XDECREF (name );
185196 return repr ;
186197}
@@ -207,8 +218,14 @@ weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
207218 else
208219 Py_RETURN_FALSE ;
209220 }
210- return PyObject_RichCompare (PyWeakref_GET_OBJECT (self ),
211- PyWeakref_GET_OBJECT (other ), op );
221+ PyObject * obj = PyWeakref_GET_OBJECT (self );
222+ PyObject * other_obj = PyWeakref_GET_OBJECT (other );
223+ Py_INCREF (obj );
224+ Py_INCREF (other_obj );
225+ PyObject * res = PyObject_RichCompare (obj , other_obj , op );
226+ Py_DECREF (obj );
227+ Py_DECREF (other_obj );
228+ return res ;
212229}
213230
214231/* Given the head of an object's list of weak references, extract the
@@ -415,26 +432,27 @@ proxy_checkref(PyWeakReference *proxy)
415432 o = PyWeakref_GET_OBJECT(o); \
416433 }
417434
418- #define UNWRAP_I (o ) \
419- if (PyWeakref_CheckProxy(o)) { \
420- if (!proxy_checkref((PyWeakReference *)o)) \
421- return -1; \
422- o = PyWeakref_GET_OBJECT(o); \
423- }
424-
425435#define WRAP_UNARY (method , generic ) \
426436 static PyObject * \
427437 method(PyObject *proxy) { \
428438 UNWRAP(proxy); \
429- return generic(proxy); \
439+ Py_INCREF(proxy); \
440+ PyObject* res = generic(proxy); \
441+ Py_DECREF(proxy); \
442+ return res; \
430443 }
431444
432445#define WRAP_BINARY (method , generic ) \
433446 static PyObject * \
434447 method(PyObject *x, PyObject *y) { \
435448 UNWRAP(x); \
436449 UNWRAP(y); \
437- return generic(x, y); \
450+ Py_INCREF(x); \
451+ Py_INCREF(y); \
452+ PyObject* res = generic(x, y); \
453+ Py_DECREF(x); \
454+ Py_DECREF(y); \
455+ return res; \
438456 }
439457
440458/* Note that the third arg needs to be checked for NULL since the tp_call
@@ -447,15 +465,25 @@ proxy_checkref(PyWeakReference *proxy)
447465 UNWRAP(v); \
448466 if (w != NULL) \
449467 UNWRAP(w); \
450- return generic(proxy, v, w); \
468+ Py_INCREF(proxy); \
469+ Py_INCREF(v); \
470+ Py_XINCREF(w); \
471+ PyObject* res = generic(proxy, v, w); \
472+ Py_DECREF(proxy); \
473+ Py_DECREF(v); \
474+ Py_XDECREF(w); \
475+ return res; \
451476 }
452477
453478#define WRAP_METHOD (method , special ) \
454479 static PyObject * \
455480 method(PyObject *proxy) { \
456481 _Py_IDENTIFIER(special); \
457482 UNWRAP(proxy); \
458- return _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \
483+ Py_INCREF(proxy); \
484+ PyObject* res = _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \
485+ Py_DECREF(proxy); \
486+ return res; \
459487 }
460488
461489
@@ -481,7 +509,11 @@ proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value)
481509{
482510 if (!proxy_checkref (proxy ))
483511 return -1 ;
484- return PyObject_SetAttr (PyWeakref_GET_OBJECT (proxy ), name , value );
512+ PyObject * obj = PyWeakref_GET_OBJECT (proxy );
513+ Py_INCREF (obj );
514+ int res = PyObject_SetAttr (obj , name , value );
515+ Py_DECREF (obj );
516+ return res ;
485517}
486518
487519static PyObject *
@@ -530,9 +562,13 @@ static int
530562proxy_bool (PyWeakReference * proxy )
531563{
532564 PyObject * o = PyWeakref_GET_OBJECT (proxy );
533- if (!proxy_checkref (proxy ))
565+ if (!proxy_checkref (proxy )) {
534566 return -1 ;
535- return PyObject_IsTrue (o );
567+ }
568+ Py_INCREF (o );
569+ int res = PyObject_IsTrue (o );
570+ Py_DECREF (o );
571+ return res ;
536572}
537573
538574static void
@@ -551,9 +587,13 @@ proxy_contains(PyWeakReference *proxy, PyObject *value)
551587{
552588 if (!proxy_checkref (proxy ))
553589 return -1 ;
554- return PySequence_Contains (PyWeakref_GET_OBJECT (proxy ), value );
555- }
556590
591+ PyObject * obj = PyWeakref_GET_OBJECT (proxy );
592+ Py_INCREF (obj );
593+ int res = PySequence_Contains (obj , value );
594+ Py_DECREF (obj );
595+ return res ;
596+ }
557597
558598/* mapping slots */
559599
@@ -562,7 +602,12 @@ proxy_length(PyWeakReference *proxy)
562602{
563603 if (!proxy_checkref (proxy ))
564604 return -1 ;
565- return PyObject_Length (PyWeakref_GET_OBJECT (proxy ));
605+
606+ PyObject * obj = PyWeakref_GET_OBJECT (proxy );
607+ Py_INCREF (obj );
608+ Py_ssize_t res = PyObject_Length (obj );
609+ Py_DECREF (obj );
610+ return res ;
566611}
567612
568613WRAP_BINARY (proxy_getitem , PyObject_GetItem )
@@ -573,10 +618,16 @@ proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value)
573618 if (!proxy_checkref (proxy ))
574619 return -1 ;
575620
576- if (value == NULL )
577- return PyObject_DelItem (PyWeakref_GET_OBJECT (proxy ), key );
578- else
579- return PyObject_SetItem (PyWeakref_GET_OBJECT (proxy ), key , value );
621+ PyObject * obj = PyWeakref_GET_OBJECT (proxy );
622+ Py_INCREF (obj );
623+ int res ;
624+ if (value == NULL ) {
625+ res = PyObject_DelItem (obj , key );
626+ } else {
627+ res = PyObject_SetItem (obj , key , value );
628+ }
629+ Py_DECREF (obj );
630+ return res ;
580631}
581632
582633/* iterator slots */
@@ -586,15 +637,24 @@ proxy_iter(PyWeakReference *proxy)
586637{
587638 if (!proxy_checkref (proxy ))
588639 return NULL ;
589- return PyObject_GetIter (PyWeakref_GET_OBJECT (proxy ));
640+ PyObject * obj = PyWeakref_GET_OBJECT (proxy );
641+ Py_INCREF (obj );
642+ PyObject * res = PyObject_GetIter (obj );
643+ Py_DECREF (obj );
644+ return res ;
590645}
591646
592647static PyObject *
593648proxy_iternext (PyWeakReference * proxy )
594649{
595650 if (!proxy_checkref (proxy ))
596651 return NULL ;
597- return PyIter_Next (PyWeakref_GET_OBJECT (proxy ));
652+
653+ PyObject * obj = PyWeakref_GET_OBJECT (proxy );
654+ Py_INCREF (obj );
655+ PyObject * res = PyIter_Next (obj );
656+ Py_DECREF (obj );
657+ return res ;
598658}
599659
600660
0 commit comments