@@ -536,19 +536,26 @@ proxy_check_ref(PyObject *obj)
536536}
537537
538538
539- /* If a parameter is a proxy, check that it is still "live" and wrap it,
540- * replacing the original value with the raw object. Raises ReferenceError
541- * if the param is a dead proxy.
539+ /* Return a new reference to a live proxy's referent, or to the object itself
540+ * if it is not a proxy. Raise ReferenceError for a dead proxy.
542541 */
542+ static PyObject *
543+ proxy_unwrap (PyObject * obj )
544+ {
545+ if (PyWeakref_CheckProxy (obj )) {
546+ PyObject * referent = _PyWeakref_GET_REF (obj );
547+ if (!proxy_check_ref (referent )) {
548+ return NULL ;
549+ }
550+ return referent ;
551+ }
552+ return Py_NewRef (obj );
553+ }
554+
543555#define UNWRAP (o ) \
544- if (PyWeakref_CheckProxy(o)) { \
545- o = _PyWeakref_GET_REF(o); \
546- if (!proxy_check_ref(o)) { \
547- return NULL; \
548- } \
549- } \
550- else { \
551- Py_INCREF(o); \
556+ o = proxy_unwrap(o); \
557+ if (o == NULL) { \
558+ return NULL; \
552559 }
553560
554561#define WRAP_UNARY (method , generic ) \
@@ -564,7 +571,11 @@ proxy_check_ref(PyObject *obj)
564571 static PyObject * \
565572 method(PyObject *x, PyObject *y) { \
566573 UNWRAP(x); \
567- UNWRAP(y); \
574+ y = proxy_unwrap(y); \
575+ if (y == NULL) { \
576+ Py_DECREF(x); \
577+ return NULL; \
578+ } \
568579 PyObject* res = generic(x, y); \
569580 Py_DECREF(x); \
570581 Py_DECREF(y); \
@@ -578,9 +589,18 @@ proxy_check_ref(PyObject *obj)
578589 static PyObject * \
579590 method(PyObject *proxy, PyObject *v, PyObject *w) { \
580591 UNWRAP(proxy); \
581- UNWRAP(v); \
592+ v = proxy_unwrap(v); \
593+ if (v == NULL) { \
594+ Py_DECREF(proxy); \
595+ return NULL; \
596+ } \
582597 if (w != NULL) { \
583- UNWRAP(w); \
598+ w = proxy_unwrap(w); \
599+ if (w == NULL) { \
600+ Py_DECREF(proxy); \
601+ Py_DECREF(v); \
602+ return NULL; \
603+ } \
584604 } \
585605 PyObject* res = generic(proxy, v, w); \
586606 Py_DECREF(proxy); \
@@ -641,7 +661,11 @@ static PyObject *
641661proxy_richcompare (PyObject * proxy , PyObject * v , int op )
642662{
643663 UNWRAP (proxy );
644- UNWRAP (v );
664+ v = proxy_unwrap (v );
665+ if (v == NULL ) {
666+ Py_DECREF (proxy );
667+ return NULL ;
668+ }
645669 PyObject * res = PyObject_RichCompare (proxy , v , op );
646670 Py_DECREF (proxy );
647671 Py_DECREF (v );
0 commit comments