summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/weakrefobject.c
diff options
context:
space:
mode:
authorAlexSm <[email protected]>2024-02-16 11:51:30 +0100
committerGitHub <[email protected]>2024-02-16 11:51:30 +0100
commit506ecaee93b52cc12c2e2f97c3d42e3ca2a7f59e (patch)
treed096fb9eb988fbb0ca1ba970041773207ce3aa70 /contrib/tools/python3/src/Objects/weakrefobject.c
parent4749b9e5d260714490997e6f5ee1ee8c1c8fc46c (diff)
parentf200f72c9d7a89c1018e3dc6b46c49fe2ecf84fb (diff)
Merge pull request #1940 from dcherednik/importlib
Library import 14
Diffstat (limited to 'contrib/tools/python3/src/Objects/weakrefobject.c')
-rw-r--r--contrib/tools/python3/src/Objects/weakrefobject.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/contrib/tools/python3/src/Objects/weakrefobject.c b/contrib/tools/python3/src/Objects/weakrefobject.c
index c76c92843cb..aee79fc1410 100644
--- a/contrib/tools/python3/src/Objects/weakrefobject.c
+++ b/contrib/tools/python3/src/Objects/weakrefobject.c
@@ -308,8 +308,7 @@ weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
if (callback == NULL && type == &_PyWeakref_RefType) {
if (ref != NULL) {
/* We can re-use an existing reference. */
- Py_INCREF(ref);
- return (PyObject *)ref;
+ return Py_NewRef(ref);
}
}
/* We have to create a new reference. */
@@ -822,9 +821,7 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback)
during GC. Return that one instead of this one
to avoid violating the invariants of the list
of weakrefs for ob. */
- Py_DECREF(result);
- Py_INCREF(ref);
- result = ref;
+ Py_SETREF(result, (PyWeakReference*)Py_NewRef(ref));
}
}
else {
@@ -887,9 +884,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
during GC. Return that one instead of this one
to avoid violating the invariants of the list
of weakrefs for ob. */
- Py_DECREF(result);
- result = proxy;
- Py_INCREF(result);
+ Py_SETREF(result, (PyWeakReference*)Py_NewRef(proxy));
goto skip_insert;
}
prev = ref;
@@ -961,9 +956,8 @@ PyObject_ClearWeakRefs(PyObject *object)
if (*list != NULL) {
PyWeakReference *current = *list;
Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
- PyObject *err_type, *err_value, *err_tb;
+ PyObject *exc = PyErr_GetRaisedException();
- PyErr_Fetch(&err_type, &err_value, &err_tb);
if (count == 1) {
PyObject *callback = current->wr_callback;
@@ -982,7 +976,7 @@ PyObject_ClearWeakRefs(PyObject *object)
tuple = PyTuple_New(count * 2);
if (tuple == NULL) {
- _PyErr_ChainExceptions(err_type, err_value, err_tb);
+ _PyErr_ChainExceptions1(exc);
return;
}
@@ -990,8 +984,7 @@ PyObject_ClearWeakRefs(PyObject *object)
PyWeakReference *next = current->wr_next;
if (Py_REFCNT((PyObject *)current) > 0) {
- Py_INCREF(current);
- PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
+ PyTuple_SET_ITEM(tuple, i * 2, Py_NewRef(current));
PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
}
else {
@@ -1013,6 +1006,25 @@ PyObject_ClearWeakRefs(PyObject *object)
Py_DECREF(tuple);
}
assert(!PyErr_Occurred());
- PyErr_Restore(err_type, err_value, err_tb);
+ PyErr_SetRaisedException(exc);
+ }
+}
+
+/* This function is called by _PyStaticType_Dealloc() to clear weak references.
+ *
+ * This is called at the end of runtime finalization, so we can just
+ * wipe out the type's weaklist. We don't bother with callbacks
+ * or anything else.
+ */
+void
+_PyStaticType_ClearWeakRefs(PyInterpreterState *interp, PyTypeObject *type)
+{
+ static_builtin_state *state = _PyStaticType_GetState(interp, type);
+ PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state);
+ while (*list != NULL) {
+ /* Note that clear_weakref() pops the first ref off the type's
+ weaklist before clearing its wr_object and wr_callback.
+ That is how we're able to loop over the list. */
+ clear_weakref((PyWeakReference *)*list);
}
}