@@ -86,50 +86,32 @@ _weakref_getweakrefs(PyObject *module, PyObject *object)
86
86
return PyList_New (0 );
87
87
}
88
88
89
- PyWeakReference * * list = GET_WEAKREFS_LISTPTR (object );
90
- Py_ssize_t count = _PyWeakref_GetWeakrefCount (object );
91
-
92
- PyObject * result = PyList_New (count );
89
+ PyObject * result = PyList_New (0 );
93
90
if (result == NULL ) {
94
91
return NULL ;
95
92
}
96
93
97
- #ifdef Py_GIL_DISABLED
98
- Py_ssize_t num_added = 0 ;
99
94
LOCK_WEAKREFS (object );
100
- PyWeakReference * current = * list ;
101
- // Weakrefs may be added or removed since the count was computed.
102
- while (num_added < count && current != NULL ) {
103
- if (_Py_TryIncref ((PyObject * ) current )) {
104
- PyList_SET_ITEM (result , num_added , current );
105
- num_added ++ ;
95
+ PyWeakReference * current = * GET_WEAKREFS_LISTPTR (object );
96
+ while (current != NULL ) {
97
+ PyObject * curobj = (PyObject * ) current ;
98
+ if (_Py_TryIncref (curobj )) {
99
+ if (PyList_Append (result , curobj )) {
100
+ UNLOCK_WEAKREFS (object );
101
+ Py_DECREF (curobj );
102
+ Py_DECREF (result );
103
+ return NULL ;
104
+ }
105
+ else {
106
+ // Undo our _Py_TryIncref. This is safe to do with the lock
107
+ // held in free-threaded builds; the list holds a reference to
108
+ // curobj so we're guaranteed not to invoke the destructor.
109
+ Py_DECREF (curobj );
110
+ }
106
111
}
107
112
current = current -> wr_next ;
108
113
}
109
114
UNLOCK_WEAKREFS (object );
110
-
111
- // Don't return an incomplete list
112
- if (num_added != count ) {
113
- PyObject * new_list = PyList_New (num_added );
114
- if (new_list == NULL ) {
115
- Py_DECREF (result );
116
- return NULL ;
117
- }
118
- for (Py_ssize_t i = 0 ; i < num_added ; i ++ ) {
119
- PyObject * obj = PyList_GET_ITEM (result , i );
120
- PyList_SET_ITEM (new_list , i , obj );
121
- PyList_SET_ITEM (result , i , NULL );
122
- }
123
- Py_DECREF (result );
124
- result = new_list ;
125
- }
126
- #else
127
- PyWeakReference * current = * list ;
128
- for (Py_ssize_t i = 0 ; i < count ; ++ i ) {
129
- PyList_SET_ITEM (result , i , Py_NewRef (current ));
130
- current = current -> wr_next ;
131
- }
132
- #endif
133
115
return result ;
134
116
}
135
117
0 commit comments