@@ -747,13 +747,23 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback)
747747 them. */
748748 result = new_weakref (ob , callback );
749749 if (result != NULL ) {
750+ get_basic_refs (* list , & ref , & proxy );
750751 if (callback == NULL ) {
751- insert_head (result , list );
752+ if (ref == NULL )
753+ insert_head (result , list );
754+ else {
755+ /* Someone else added a ref without a callback
756+ during GC. Return that one instead of this one
757+ to avoid violating the invariants of the list
758+ of weakrefs for ob. */
759+ Py_DECREF (result );
760+ Py_INCREF (ref );
761+ result = ref ;
762+ }
752763 }
753764 else {
754765 PyWeakReference * prev ;
755766
756- get_basic_refs (* list , & ref , & proxy );
757767 prev = (proxy == NULL ) ? ref : proxy ;
758768 if (prev == NULL )
759769 insert_head (result , list );
@@ -803,15 +813,27 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
803813 else
804814 result -> ob_type = & _PyWeakref_ProxyType ;
805815 get_basic_refs (* list , & ref , & proxy );
806- if (callback == NULL )
816+ if (callback == NULL ) {
817+ if (proxy != NULL ) {
818+ /* Someone else added a proxy without a callback
819+ during GC. Return that one instead of this one
820+ to avoid violating the invariants of the list
821+ of weakrefs for ob. */
822+ Py_DECREF (result );
823+ Py_INCREF (result = proxy );
824+ goto skip_insert ;
825+ }
807826 prev = ref ;
827+ }
808828 else
809829 prev = (proxy == NULL ) ? ref : proxy ;
810830
811831 if (prev == NULL )
812832 insert_head (result , list );
813833 else
814834 insert_after (result , prev );
835+ skip_insert :
836+ ;
815837 }
816838 }
817839 return (PyObject * ) result ;
0 commit comments