You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add PyUnstable_Object_ClearWeakRefsNoCallbacks() function #25
Clear weakrefs again, but don't call callbacks (i.e., the proposed PyObject_ClearWeakRefsNoCallbacks)
The third-step is performed internally via _PyWeakref_ClearWeakRefsExceptCallbacks, but that's not a public API. This is performed internally by subtype_dealloc, but extensions cannot always delegate to that function.
Previously, C API extensions used the following pattern, but it's not thread-safe without the GIL and relies on an undocumented private API _PyWeakref_ClearRef:
PyWeakReference**list=PyObject_GET_WEAKREFS_LISTPTR(self);
while (*list) {
_PyWeakref_ClearRef(*list);
}
Proposed API
// Clears the weakrefs for object `obj`, but does not call their callbacks.PyAPI_FUNC(void) PyObject_ClearWeakRefsNoCallbacks(PyObject*obj);
Implementation
The implementation already exists as the internal-only _PyWeakref_ClearWeakRefsExceptCallbacks function. Per @vstinner's suggestion, I'd propose that the PyObject_ClearWeakRefsNoCallbacks returns immediately if obj does not support weakrefs.
See also
PyObject_ClearWeakRefs: a similar function, which clears weakrefs and calls their callbacks
EDIT: Updated name based on @iritkatriel's suggestion
While the semantics of PyObject_ClearWeakRefsNoCallbacks function itself are clear, it seems that anyone calling it is quite deep in implementation details.
I worry that by exposing the function, we're implicitly saying that it's OK to re-implementing subtype_dealloc, or at least the “clear/call del/clear again” dance.
It seems better to expose this as PyUnstable_Object_ClearWeakRefsNoCallbacks: if you use this function, you better be checking What's News and you better be prepared to adjust code for each new release.
(Perhaps one of those releases will add a PyObject_Finalize() that abstracts away a well-defined chunk of subtype_dealloc. But even if we add something like that in 3.14, a transitional PyUnstable_Object_ClearWeakRefsNoCallbacks would be nice to have.)
I worry that by exposing the function, we're implicitly saying that it's OK to re-implementing subtype_dealloc, or at least the “clear/call del/clear again” dance.
IMO it's ok to reimplement something like subtype_dealloc, since 3rd party extensions do it, and that's why Sam wants to make the function public. I'm not sure that the function needs to be tagged as "unstable". The documentation can be clear about where and when it should be used or not.
It seems like we are ok with the feature, but not in which API it should be added: how the function should be named. I'm not sure how to resolve this disagreement, so I propose a poll/vote below.
IMO it's ok to reimplement something like subtype_dealloc, since 3rd party extensions do it[...] The documentation can be clear about where and when it should be used or not.
I'd need to see that documentation to be convinced.
I lean towards the "unstable" marking, just so we can remove it within a release. I wouldn't expect the API to change in any other meaningful way apart from the function no longer doing what the caller thinks it is doing.
Activity
gvanrossum commentedon May 10, 2024
No objection from me.
iritkatriel commentedon May 10, 2024
I don't think the name
PyObject_ClearWeakRefsExceptCallbacksis clear.Exceptin particular.Something like
PyObject_ClearWeakRefsNoCallbacksmaybe.[-]Add `PyObject_ClearWeakRefsExceptCallbacks`[/-][+]Add `PyObject_ClearWeakRefsNoCallbacks`[/+]colesbury commentedon May 10, 2024
I've updated the proposed name
vstinner commentedon May 12, 2024
LGTM.
gvanrossum commentedon May 12, 2024
encukou commentedon May 13, 2024
While the semantics of
PyObject_ClearWeakRefsNoCallbacksfunction itself are clear, it seems that anyone calling it is quite deep in implementation details.I worry that by exposing the function, we're implicitly saying that it's OK to re-implementing
subtype_dealloc, or at least the “clear/call del/clear again” dance.It seems better to expose this as
PyUnstable_Object_ClearWeakRefsNoCallbacks: if you use this function, you better be checking What's News and you better be prepared to adjust code for each new release.(Perhaps one of those releases will add a
PyObject_Finalize()that abstracts away a well-defined chunk ofsubtype_dealloc. But even if we add something like that in 3.14, a transitionalPyUnstable_Object_ClearWeakRefsNoCallbackswould be nice to have.)colesbury commentedon May 13, 2024
PyUnstable_Object_ClearWeakRefsNoCallbacksis fine with me too.colesbury commentedon May 22, 2024
@vstinner - is
PyUnstable_Object_ClearWeakRefsNoCallbacksokay with you?vstinner commentedon May 22, 2024
IMO it's ok to reimplement something like subtype_dealloc, since 3rd party extensions do it, and that's why Sam wants to make the function public. I'm not sure that the function needs to be tagged as "unstable". The documentation can be clear about where and when it should be used or not.
vstinner commentedon May 31, 2024
It seems like we are ok with the feature, but not in which API it should be added: how the function should be named. I'm not sure how to resolve this disagreement, so I propose a poll/vote below.
Function name: please pick only name :-)
PyUnstable_Object_ClearWeakRefsNoCallbacks()- unstable API, rationale: #25 (comment)PyObject_ClearWeakRefsNoCallbacks()- public API, rationale: #25 (comment)encukou commentedon May 31, 2024
I'd need to see that documentation to be convinced.
zooba commentedon May 31, 2024
I lean towards the "unstable" marking, just so we can remove it within a release. I wouldn't expect the API to change in any other meaningful way apart from the function no longer doing what the caller thinks it is doing.
erlend-aasland commentedon May 31, 2024
I chose
PyObject_ClearWeakRefsNoCallbacks, but I won't oppose the unstable variant (though I think it is a weak candidate for the unstable tier).encukou commentedon Jun 6, 2024
We discussed this on a meeting, and decided that it should be unstable API. Please go with
PyUnstable_Object_ClearWeakRefsNoCallbacks.[-]Add `PyObject_ClearWeakRefsNoCallbacks`[/-][+]Add `PyUnstable_Object_ClearWeakRefsNoCallbacks()` function[/+]