8000 Refactor `weakref._getweakrefs` to have one implementation · python/cpython@fb9eee5 · GitHub
[go: up one dir, main page]

Skip to content

Commit fb9eee5

Browse files
committed
Refactor weakref._getweakrefs to have one implementation
1 parent 37f9ceb commit fb9eee5

File tree

1 file changed

+17
-35
lines changed

1 file changed

+17
-35
lines changed

Modules/_weakref.c

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -86,50 +86,32 @@ _weakref_getweakrefs(PyObject *module, PyObject *object)
8686
return PyList_New(0);
8787
}
8888

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);
9390
if (result == NULL) {
9491
return NULL;
9592
}
9693

97-
#ifdef Py_GIL_DISABLED
98-
Py_ssize_t num_added = 0;
9994
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+
}
106111
}
107112
current = current->wr_next;
108113
}
109114
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
133115
return result;
134116
}
135117

0 commit comments

Comments
 (0)
0