11#include "Python.h"
22#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR()
3+ #include "pycore_weakref.h" // _PyWeakref_GET_REF()
34#include "structmember.h" // PyMemberDef
45
56
@@ -147,12 +148,11 @@ weakref_hash(PyWeakReference *self)
147148{
148149 if (self -> hash != -1 )
149150 return self -> hash ;
150- PyObject * obj = PyWeakref_GET_OBJECT ( self );
151- if (obj == Py_None ) {
151+ PyObject * obj = _PyWeakref_GET_REF (( PyObject * ) self );
152+ if (obj == NULL ) {
152153 PyErr_SetString (PyExc_TypeError , "weak object has gone away" );
153154 return -1 ;
154155 }
155- Py_INCREF (obj );
156156 self -> hash = PyObject_Hash (obj );
157157 Py_DECREF (obj );
158158 return self -> hash ;
@@ -162,15 +162,13 @@ weakref_hash(PyWeakReference *self)
162162static PyObject *
163163weakref_repr (PyObject * self )
164164{
165- PyObject * name , * repr ;
166- PyObject * obj = PyWeakref_GET_OBJECT (self );
167-
168- if (obj == Py_None ) {
165+ PyObject * obj = _PyWeakref_GET_REF (self );
166+ if (obj == NULL ) {
169167 return PyUnicode_FromFormat ("<weakref at %p; dead>" , self );
170168 }
171169
172- Py_INCREF (obj );
173- name = _PyObject_LookupSpecial ( obj , & _Py_ID ( __name__ )) ;
170+ PyObject * name = _PyObject_LookupSpecial (obj , & _Py_ID ( __name__ ) );
171+ PyObject * repr ;
174172 if (name == NULL || !PyUnicode_Check (name )) {
175173 repr = PyUnicode_FromFormat (
176174 "<weakref at %p; to '%s' at %p>" ,
@@ -191,16 +189,18 @@ weakref_repr(PyObject *self)
191189 gone away, they are equal if they are identical. */
192190
193191static PyObject *
194- weakref_richcompare (PyWeakReference * self , PyWeakReference * other , int op )
192+ weakref_richcompare (PyObject * self , PyObject * other , int op )
195193{
196194 if ((op != Py_EQ && op != Py_NE ) ||
197195 !PyWeakref_Check (self ) ||
198196 !PyWeakref_Check (other )) {
199197 Py_RETURN_NOTIMPLEMENTED ;
200198 }
201- PyObject * obj = PyWeakref_GET_OBJECT (self );
202- PyObject * other_obj = PyWeakref_GET_OBJECT (other );
203- if (obj == Py_None || other_obj == Py_None ) {
199+ PyObject * obj = _PyWeakref_GET_REF (self );
200+ PyObject * other_obj = _PyWeakref_GET_REF (other );
201+ if (obj == NULL || other_obj == NULL ) {
202+ Py_XDECREF (obj );
203+ Py_XDECREF (other_obj );
204204 int res = (self == other );
205205 if (op == Py_NE )
206206 res = !res ;
@@ -209,8 +209,6 @@ weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
209209 else
210210 Py_RETURN_FALSE ;
211211 }
212- Py_INCREF (obj );
213- Py_INCREF (other_obj );
214212 PyObject * res = PyObject_RichCompare (obj , other_obj , op );
215213 Py_DECREF (obj );
216214 Py_DECREF (other_obj );
@@ -372,7 +370,7 @@ _PyWeakref_RefType = {
372370 Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_BASETYPE ,
373371 .tp_traverse = (traverseproc )gc_traverse ,
374372 .tp_clear = (inquiry )gc_clear ,
375- .tp_richcompare = ( richcmpfunc ) weakref_richcompare ,
373+ .tp_richcompare = weakref_richcompare ,
376374 .tp_methods = weakref_methods ,
377375 .tp_members = weakref_members ,
378376 .tp_init = weakref___init__ ,
@@ -385,7 +383,7 @@ _PyWeakref_RefType = {
385383static bool
386384proxy_check_ref (PyObject * obj )
387385{
388- if (obj == Py_None ) {
386+ if (obj == NULL ) {
389387 PyErr_SetString (PyExc_ReferenceError ,
390388 "weakly-referenced object no longer exists" );
391389 return false;
@@ -400,16 +398,19 @@ proxy_check_ref(PyObject *obj)
400398 */
401399#define UNWRAP (o ) \
402400 if (PyWeakref_CheckProxy(o)) { \
403- o = PyWeakref_GET_OBJECT (o); \
404- if (!proxy_check_ref(o)) \
401+ o = _PyWeakref_GET_REF (o); \
402+ if (!proxy_check_ref(o)) { \
405403 return NULL; \
404+ } \
405+ } \
406+ else { \
407+ Py_INCREF(o); \
406408 }
407409
408410#define WRAP_UNARY (method , generic ) \
409411 static PyObject * \
410412 method(PyObject *proxy) { \
411413 UNWRAP(proxy); \
412- Py_INCREF(proxy); \
413414 PyObject* res = generic(proxy); \
414415 Py_DECREF(proxy); \
415416 return res; \
@@ -420,8 +421,6 @@ proxy_check_ref(PyObject *obj)
420421 method(PyObject *x, PyObject *y) { \
421422 UNWRAP(x); \
422423 UNWRAP(y); \
423- Py_INCREF(x); \
424- Py_INCREF(y); \
425424 PyObject* res = generic(x, y); \
426425 Py_DECREF(x); \
427426 Py_DECREF(y); \
@@ -436,11 +435,9 @@ proxy_check_ref(PyObject *obj)
436435 method(PyObject *proxy, PyObject *v, PyObject *w) { \
437436 UNWRAP(proxy); \
438437 UNWRAP(v); \
439- if (w != NULL) \
438+ if (w != NULL) { \
440439 UNWRAP(w); \
441- Py_INCREF(proxy); \
442- Py_INCREF(v); \
443- Py_XINCREF(w); \
440+ } \
444441 PyObject* res = generic(proxy, v, w); \
445442 Py_DECREF(proxy); \
446443 Py_DECREF(v); \
@@ -452,7 +449,6 @@ proxy_check_ref(PyObject *obj)
452449 static PyObject * \
453450 method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \
454451 UNWRAP(proxy); \
455- Py_INCREF(proxy); \
456452 PyObject* res = PyObject_CallMethodNoArgs(proxy, &_Py_ID(SPECIAL)); \
457453 Py_DECREF(proxy); \
458454 return res; \
@@ -466,24 +462,24 @@ WRAP_UNARY(proxy_str, PyObject_Str)
466462WRAP_TERNARY (proxy_call , PyObject_Call )
467463
468464static PyObject *
469- proxy_repr (PyWeakReference * proxy )
465+ proxy_repr (PyObject * proxy )
470466{
471- return PyUnicode_FromFormat (
467+ PyObject * obj = _PyWeakref_GET_REF (proxy );
468+ PyObject * repr = PyUnicode_FromFormat (
472469 "<weakproxy at %p to %s at %p>" ,
473- proxy ,
474- Py_TYPE ( PyWeakref_GET_OBJECT ( proxy )) -> tp_name ,
475- PyWeakref_GET_OBJECT ( proxy )) ;
470+ proxy , Py_TYPE ( obj ) -> tp_name , obj );
471+ Py_DECREF ( obj );
472+ return repr ;
476473}
477474
478475
479476static int
480477proxy_setattr (PyObject * proxy , PyObject * name , PyObject * value )
481478{
482- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
479+ PyObject * obj = _PyWeakref_GET_REF (proxy );
483480 if (!proxy_check_ref (obj )) {
484481 return -1 ;
485482 }
486- Py_INCREF (obj );
487483 int res = PyObject_SetAttr (obj , name , value );
488484 Py_DECREF (obj );
489485 return res ;
@@ -494,7 +490,10 @@ proxy_richcompare(PyObject *proxy, PyObject *v, int op)
494490{
495491 UNWRAP (proxy );
496492 UNWRAP (v );
497- return PyObject_RichCompare (proxy , v , op );
493+ PyObject * res = PyObject_RichCompare (proxy , v , op );
494+ Py_DECREF (proxy );
495+ Py_DECREF (v );
496+ return res ;
498497}
499498
500499/* number slots */
@@ -536,11 +535,10 @@ WRAP_BINARY(proxy_imatmul, PyNumber_InPlaceMatrixMultiply)
536535static int
537536proxy_bool (PyObject * proxy )
538537{
539- PyObject * o = PyWeakref_GET_OBJECT (proxy );
538+ PyObject * o = _PyWeakref_GET_REF (proxy );
540539 if (!proxy_check_ref (o )) {
541540 return -1 ;
542541 }
543- Py_INCREF (o );
544542 int res = PyObject_IsTrue (o );
545543 Py_DECREF (o );
546544 return res ;
@@ -561,11 +559,10 @@ proxy_dealloc(PyWeakReference *self)
561559static int
562560proxy_contains (PyObject * proxy , PyObject * value )
563561{
564- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
562+ PyObject * obj = _PyWeakref_GET_REF (proxy );
565563 if (!proxy_check_ref (obj )) {
566564 return -1 ;
567565 }
568- Py_INCREF (obj );
569566 int res = PySequence_Contains (obj , value );
570567 Py_DECREF (obj );
571568 return res ;
@@ -576,11 +573,10 @@ proxy_contains(PyObject *proxy, PyObject *value)
576573static Py_ssize_t
577574proxy_length (PyObject * proxy )
578575{
579- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
576+ PyObject * obj = _PyWeakref_GET_REF (proxy );
580577 if (!proxy_check_ref (obj )) {
581578 return -1 ;
582579 }
583- Py_INCREF (obj );
584580 Py_ssize_t res = PyObject_Length (obj );
585581 Py_DECREF (obj );
586582 return res ;
@@ -591,11 +587,10 @@ WRAP_BINARY(proxy_getitem, PyObject_GetItem)
591587static int
592588proxy_setitem (PyObject * proxy , PyObject * key , PyObject * value )
593589{
594- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
590+ PyObject * obj = _PyWeakref_GET_REF (proxy );
595591 if (!proxy_check_ref (obj )) {
596592 return -1 ;
597593 }
598- Py_INCREF (obj );
599594 int res ;
600595 if (value == NULL ) {
601596 res = PyObject_DelItem (obj , key );
@@ -611,11 +606,10 @@ proxy_setitem(PyObject *proxy, PyObject *key, PyObject *value)
611606static PyObject *
612607proxy_iter (PyObject * proxy )
613608{
614- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
609+ PyObject * obj = _PyWeakref_GET_REF (proxy );
615610 if (!proxy_check_ref (obj )) {
616611 return NULL ;
617612 }
618- Py_INCREF (obj );
619613 PyObject * res = PyObject_GetIter (obj );
620614 Py_DECREF (obj );
621615 return res ;
@@ -624,17 +618,17 @@ proxy_iter(PyObject *proxy)
624618static PyObject *
625619proxy_iternext (PyObject * proxy )
626620{
627- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
621+ PyObject * obj = _PyWeakref_GET_REF (proxy );
628622 if (!proxy_check_ref (obj )) {
629623 return NULL ;
630624 }
631625 if (!PyIter_Check (obj )) {
632626 PyErr_Format (PyExc_TypeError ,
633627 "Weakref proxy referenced a non-iterator '%.200s' object" ,
634628 Py_TYPE (obj )-> tp_name );
629+ Py_DECREF (obj );
635630 return NULL ;
636631 }
637- Py_INCREF (obj );
638632 PyObject * res = PyIter_Next (obj );
639633 Py_DECREF (obj );
640634 return res ;
@@ -721,7 +715,7 @@ _PyWeakref_ProxyType = {
721715 0 , /* tp_getattr */
722716 0 , /* tp_setattr */
723717 0 , /* tp_as_async */
724- ( reprfunc ) proxy_repr , /* tp_repr */
718+ proxy_repr , /* tp_repr */
725719 & proxy_as_number , /* tp_as_number */
726720 & proxy_as_sequence , /* tp_as_sequence */
727721 & proxy_as_mapping , /* tp_as_mapping */
@@ -756,7 +750,7 @@ _PyWeakref_CallableProxyType = {
756750 0 , /* tp_getattr */
757751 0 , /* tp_setattr */
758752 0 , /* tp_as_async */
759- ( unaryfunc ) proxy_repr , /* tp_repr */
753+ proxy_repr , /* tp_repr */
760754 & proxy_as_number , /* tp_as_number */
761755 & proxy_as_sequence , /* tp_as_sequence */
762756 & proxy_as_mapping , /* tp_as_mapping */
0 commit comments