File tree Expand file tree Collapse file tree 2 files changed +78
-3
lines changed
Expand file tree Collapse file tree 2 files changed +78
-3
lines changed Original file line number Diff line number Diff line change @@ -538,6 +538,58 @@ class MyObj:
538538 with self .assertRaises (TypeError ):
539539 hash (weakref .proxy (obj ))
540540
541+ def test_proxy_unref_add_refcount (self ):
542+ class C :
543+ def __add__ (self , o ):
544+ return NotImplemented
545+
546+ # create dead proxy
547+ o = C ()
548+ dead = weakref .proxy (o )
549+ del o
550+ gc .collect ()
551+
552+ # create live proxy
553+ obj = C ()
554+ ref = weakref .ref (obj )
555+ proxy = weakref .proxy (obj )
556+
557+ try :
558+ operator .add (proxy , dead )
559+ except ReferenceError :
560+ pass
561+
562+ del proxy , obj , dead
563+ gc .collect ()
564+
565+ self .assertIsNone (ref (), "Leaked object in add operation" )
566+
567+ def test_proxy_unref_pow_refcount (self ):
568+ class C :
569+ def __pow__ (self , o , m = None ):
570+ return NotImplemented
571+
572+ # create dead proxy
573+ o = C ()
574+ dead = weakref .proxy (o )
575+ del o
576+ gc .collect ()
577+
578+ # create live proxy
579+ obj = C ()
580+ ref = weakref .ref (obj )
581+ proxy = weakref .proxy (obj )
582+
583+ try :
584+ pow (proxy , dead , None )
585+ except ReferenceError :
586+ pass
587+
588+ del proxy , obj , dead
589+ gc .collect ()
590+
591+ self .assertIsNone (ref (), "Leaked object in pow operation" )
592+
541593 def test_getweakrefcount (self ):
542594 o = C ()
543595 ref1 = weakref .ref (o )
Original file line number Diff line number Diff line change @@ -538,9 +538,7 @@ proxy_check_ref(PyObject *obj)
538538#define UNWRAP (o ) \
539539 if (PyWeakref_CheckProxy(o)) { \
540540 o = _PyWeakref_GET_REF(o); \
541- if (!proxy_check_ref(o)) { \
542- return NULL; \
543- } \
541+ proxy_check_ref(o); \
544542 } \
545543 else { \
546544 Py_INCREF(o); \
@@ -559,7 +557,13 @@ proxy_check_ref(PyObject *obj)
559557 static PyObject * \
560558 method(PyObject *x, PyObject *y) { \
561559 UNWRAP(x); \
560+ if (x == NULL) \
561+ return NULL; \
562562 UNWRAP(y); \
563+ if (y == NULL) { \
564+ Py_XDECREF(x); \
565+ return NULL; \
566+ } \
563567 PyObject* res = generic(x, y); \
564568 Py_DECREF(x); \
565569 Py_DECREF(y); \
@@ -573,9 +577,20 @@ proxy_check_ref(PyObject *obj)
573577 static PyObject * \
574578 method(PyObject *proxy, PyObject *v, PyObject *w) { \
575579 UNWRAP(proxy); \
580+ if (proxy == NULL) \
581+ return NULL; \
576582 UNWRAP(v); \
583+ if (v == NULL) { \
584+ Py_XDECREF(proxy); \
585+ return NULL; \
586+ } \
577587 if (w != NULL) { \
578588 UNWRAP(w); \
589+ if (w == NULL) { \
590+ Py_XDECREF(proxy); \
591+ Py_XDECREF(v); \
592+ return NULL; \
593+ } \
579594 } \
580595 PyObject* res = generic(proxy, v, w); \
581596 Py_DECREF(proxy); \
@@ -588,6 +603,8 @@ proxy_check_ref(PyObject *obj)
588603 static PyObject * \
589604 method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \
590605 UNWRAP(proxy); \
606+ if (proxy == NULL) \
607+ return NULL; \
591608 PyObject* res = PyObject_CallMethodNoArgs(proxy, &_Py_ID(SPECIAL)); \
592609 Py_DECREF(proxy); \
593610 return res; \
@@ -636,7 +653,13 @@ static PyObject *
636653proxy_richcompare (PyObject * proxy , PyObject * v , int op )
637654{
638655 UNWRAP (proxy );
656+ if (proxy == NULL )
657+ return NULL ;
639658 UNWRAP (v );
659+ if (v == NULL ) {
660+ Py_XDECREF (proxy );
661+ return NULL ;
662+ }
640663 PyObject * res = PyObject_RichCompare (proxy , v , op );
641664 Py_DECREF (proxy );
642665 Py_DECREF (v );
You can’t perform that action at this time.
0 commit comments