1
1
#include "Python.h"
2
2
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR()
3
+ #include "pycore_weakref.h" // _PyWeakref_GET_REF()
3
4
#include "structmember.h" // PyMemberDef
4
5
5
6
@@ -147,12 +148,11 @@ weakref_hash(PyWeakReference *self)
147
148
{
148
149
if (self -> hash != -1 )
149
150
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 ) {
152
153
PyErr_SetString (PyExc_TypeError , "weak object has gone away" );
153
154
return -1 ;
154
155
}
155
- Py_INCREF (obj );
156
156
self -> hash = PyObject_Hash (obj );
157
157
Py_DECREF (obj );
158
158
return self -> hash ;
@@ -162,15 +162,13 @@ weakref_hash(PyWeakReference *self)
162
162
static PyObject *
163
163
weakref_repr (PyObject * self )
164
164
{
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 ) {
169
167
return PyUnicode_FromFormat ("<weakref at %p; dead>" , self );
170
168
}
171
169
172
- Py_INCREF (obj );
173
- name = _PyObject_LookupSpecial ( obj , & _Py_ID ( __name__ )) ;
170
+ PyObject * name = _PyObject_LookupSpecial (obj , & _Py_ID ( __name__ ) );
171
+ PyObject * repr ;
174
172
if (name == NULL || !PyUnicode_Check (name )) {
175
173
repr = PyUnicode_FromFormat (
176
174
"<weakref at %p; to '%s' at %p>" ,
@@ -191,16 +189,18 @@ weakref_repr(PyObject *self)
191
189
gone away, they are equal if they are identical. */
192
190
193
191
static PyObject *
194
- weakref_richcompare (PyWeakReference * self , PyWeakReference * other , int op )
192
+ weakref_richcompare (PyObject * self , PyObject * other , int op )
195
193
{
196
194
if ((op != Py_EQ && op != Py_NE ) ||
197
195
!PyWeakref_Check (self ) ||
198
196
!PyWeakref_Check (other )) {
199
197
Py_RETURN_NOTIMPLEMENTED ;
200
198
}
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 );
204
204
int res = (self == other );
205
205
if (op == Py_NE )
206
206
res = !res ;
@@ -209,8 +209,6 @@ weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
209
209
else
210
210
Py_RETURN_FALSE ;
211
211
}
212
- Py_INCREF (obj );
213
- Py_INCREF (other_obj );
214
212
PyObject * res = PyObject_RichCompare (obj , other_obj , op );
215
213
Py_DECREF (obj );
216
214
Py_DECREF (other_obj );
@@ -372,7 +370,7 @@ _PyWeakref_RefType = {
372
370
Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_BASETYPE ,
373
371
.tp_traverse = (traverseproc )gc_traverse ,
374
372
.tp_clear = (inquiry )gc_clear ,
375
- .tp_richcompare = ( richcmpfunc ) weakref_richcompare ,
373
+ .tp_richcompare = weakref_richcompare ,
376
374
.tp_methods = weakref_methods ,
377
375
.tp_members = weakref_members ,
378
376
.tp_init = weakref___init__ ,
@@ -385,7 +383,7 @@ _PyWeakref_RefType = {
385
383
static bool
386
384
proxy_check_ref (PyObject * obj )
387
385
{
388
- if (obj == Py_None ) {
386
+ if (obj == NULL ) {
389
387
PyErr_SetString (PyExc_ReferenceError ,
390
388
"weakly-referenced object no longer exists" );
391
389
return false;
@@ -400,16 +398,19 @@ proxy_check_ref(PyObject *obj)
400
398
*/
401
399
#define UNWRAP (o ) \
402
400
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)) { \
405
403
return NULL; \
404
+ } \
405
+ } \
406
+ else { \
407
+ Py_INCREF(o); \
406
408
}
407
409
408
410
#define WRAP_UNARY (method , generic ) \
409
411
static PyObject * \
410
412
method(PyObject *proxy) { \
411
413
UNWRAP(proxy); \
412
- Py_INCREF(proxy); \
413
414
PyObject* res = generic(proxy); \
414
415
Py_DECREF(proxy); \
415
416
return res; \
@@ -420,8 +421,6 @@ proxy_check_ref(PyObject *obj)
420
421
method(PyObject *x, PyObject *y) { \
421
422
UNWRAP(x); \
422
423
UNWRAP(y); \
423
- Py_INCREF(x); \
424
- Py_INCREF(y); \
425
424
PyObject* res = generic(x, y); \
426
425
Py_DECREF(x); \
427
426
Py_DECREF(y); \
@@ -436,11 +435,9 @@ proxy_check_ref(PyObject *obj)
436
435
method(PyObject *proxy, PyObject *v, PyObject *w) { \
437
436
UNWRAP(proxy); \
438
437
UNWRAP(v); \
439
- if (w != NULL) \
438
+ if (w != NULL) { \
440
439
UNWRAP(w); \
441
- Py_INCREF(proxy); \
442
- Py_INCREF(v); \
443
- Py_XINCREF(w); \
440
+ } \
444
441
PyObject* res = generic(proxy, v, w); \
445
442
Py_DECREF(proxy); \
446
443
Py_DECREF(v); \
@@ -452,7 +449,6 @@ proxy_check_ref(PyObject *obj)
452
449
static PyObject * \
453
450
method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \
454
451
UNWRAP(proxy); \
455
- Py_INCREF(proxy); \
456
452
PyObject* res = PyObject_CallMethodNoArgs(proxy, &_Py_ID(SPECIAL)); \
457
453
Py_DECREF(proxy); \
458
454
return res; \
@@ -466,24 +462,24 @@ WRAP_UNARY(proxy_str, PyObject_Str)
466
462
WRAP_TERNARY (proxy_call , PyObject_Call )
467
463
468
464
static PyObject *
469
- proxy_repr (PyWeakReference * proxy )
465
+ proxy_repr (PyObject * proxy )
470
466
{
471
- return PyUnicode_FromFormat (
467
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
468
+ PyObject * repr = PyUnicode_FromFormat (
472
469
"<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 ;
476
473
}
477
474
478
475
479
476
static int
480
477
proxy_setattr (PyObject * proxy , PyObject * name , PyObject * value )
481
478
{
482
- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
479
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
483
480
if (!proxy_check_ref (obj )) {
484
481
return -1 ;
485
482
}
486
- Py_INCREF (obj );
487
483
int res = PyObject_SetAttr (obj , name , value );
488
484
Py_DECREF (obj );
489
485
return res ;
@@ -494,7 +490,10 @@ proxy_richcompare(PyObject *proxy, PyObject *v, int op)
494
490
{
495
491
UNWRAP (proxy );
496
492
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 ;
498
497
}
499
498
500
499
/* number slots */
@@ -536,11 +535,10 @@ WRAP_BINARY(proxy_imatmul, PyNumber_InPlaceMatrixMultiply)
536
535
static int
537
536
proxy_bool (PyObject * proxy )
538
537
{
539
- PyObject * o = PyWeakref_GET_OBJECT (proxy );
538
+ PyObject * o = _PyWeakref_GET_REF (proxy );
540
539
if (!proxy_check_ref (o )) {
541
540
return -1 ;
542
541
}
543
- Py_INCREF (o );
544
542
int res = PyObject_IsTrue (o );
545
543
Py_DECREF (o );
546
544
return res ;
@@ -561,11 +559,10 @@ proxy_dealloc(PyWeakReference *self)
561
559
static int
562
560
proxy_contains (PyObject * proxy , PyObject * value )
563
561
{
564
- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
562
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
565
563
if (!proxy_check_ref (obj )) {
566
564
return -1 ;
567
565
}
568
- Py_INCREF (obj );
569
566
int res = PySequence_Contains (obj , value );
570
567
Py_DECREF (obj );
571
568
return res ;
@@ -576,11 +573,10 @@ proxy_contains(PyObject *proxy, PyObject *value)
576
573
static Py_ssize_t
577
574
proxy_length (PyObject * proxy )
578
575
{
579
- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
576
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
580
577
if (!proxy_check_ref (obj )) {
581
578
return -1 ;
582
579
}
583
- Py_INCREF (obj );
584
580
Py_ssize_t res = PyObject_Length (obj );
585
581
Py_DECREF (obj );
586
582
return res ;
@@ -591,11 +587,10 @@ WRAP_BINARY(proxy_getitem, PyObject_GetItem)
591
587
static int
592
588
proxy_setitem (PyObject * proxy , PyObject * key , PyObject * value )
593
589
{
594
- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
590
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
595
591
if (!proxy_check_ref (obj )) {
596
592
return -1 ;
597
593
}
598
- Py_INCREF (obj );
599
594
int res ;
600
595
if (value == NULL ) {
601
596
res = PyObject_DelItem (obj , key );
@@ -611,11 +606,10 @@ proxy_setitem(PyObject *proxy, PyObject *key, PyObject *value)
611
606
static PyObject *
612
607
proxy_iter (PyObject * proxy )
613
608
{
614
- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
609
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
615
610
if (!proxy_check_ref (obj )) {
616
611
return NULL ;
617
612
}
618
- Py_INCREF (obj );
619
613
PyObject * res = PyObject_GetIter (obj );
620
614
Py_DECREF (obj );
621
615
return res ;
@@ -624,17 +618,17 @@ proxy_iter(PyObject *proxy)
624
618
static PyObject *
625
619
proxy_iternext (PyObject * proxy )
626
620
{
627
- PyObject * obj = PyWeakref_GET_OBJECT (proxy );
621
+ PyObject * obj = _PyWeakref_GET_REF (proxy );
628
622
if (!proxy_check_ref (obj )) {
629
623
return NULL ;
630
624
}
631
625
if (!PyIter_Check (obj )) {
632
626
PyErr_Format (PyExc_TypeError ,
633
627
"Weakref proxy referenced a non-iterator '%.200s' object" ,
634
628
Py_TYPE (obj )-> tp_name );
629
+ Py_DECREF (obj );
635
630
return NULL ;
636
631
}
637
- Py_INCREF (obj );
638
632
PyObject * res = PyIter_Next (obj );
639
633
Py_DECREF (obj );
640
634
return res ;
@@ -721,7 +715,7 @@ _PyWeakref_ProxyType = {
721
715
0 , /* tp_getattr */
722
716
0 , /* tp_setattr */
723
717
0 , /* tp_as_async */
724
- ( reprfunc ) proxy_repr , /* tp_repr */
718
+ proxy_repr , /* tp_repr */
725
719
& proxy_as_number , /* tp_as_number */
726
720
& proxy_as_sequence , /* tp_as_sequence */
727
721
& proxy_as_mapping , /* tp_as_mapping */
@@ -756,7 +750,7 @@ _PyWeakref_CallableProxyType = {
756
750
0 , /* tp_getattr */
757
751
0 , /* tp_setattr */
758
752
0 , /* tp_as_async */
759
- ( unaryfunc ) proxy_repr , /* tp_repr */
753
+ proxy_repr , /* tp_repr */
760
754
& proxy_as_number , /* tp_as_number */
761
755
& proxy_as_sequence , /* tp_as_sequence */
762
756
& proxy_as_mapping , /* tp_as_mapping */
0 commit comments