New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C API: Add PyWeakref_GetRef() function #105927
Comments
With an error set? If no, would you need to call |
proxy_checkref() now checks the object, not the proxy.
* proxy_checkref() now checks the object, not the proxy. * Most functions take PyObject* instead of PyWeakReference*. * Remove redundant calls to PyWeakref_GET_OBJECT().
* proxy_checkref() now checks the object, not the proxy. * Most functions take PyObject* instead of PyWeakReference*. * Remove redundant calls to PyWeakref_GET_OBJECT().
* Rename proxy_checkref() to proxy_check_ref(). * proxy_check_ref() now checks the object, not the proxy. * Most functions take PyObject* instead of PyWeakReference*. * Remove redundant calls to PyWeakref_GET_OBJECT().
* Rename proxy_checkref() to proxy_check_ref(). * proxy_check_ref() now checks the object, not the proxy. * Most functions take PyObject* instead of PyWeakReference*. * Remove redundant calls to PyWeakref_GET_OBJECT().
* Rename proxy_checkref() to proxy_check_ref(). * proxy_check_ref() now checks the object, not the proxy. * Most functions take PyObject* instead of PyWeakReference*. * Remove redundant calls to PyWeakref_GET_OBJECT().
Add new pycore_weakref.h internal header file.
No error is set. See PR #105929 for the first part of the implementation. |
Add new pycore_weakref.h internal header file.
Would it be better to return None if the object has been finalized? The idiom is that APIs returning a |
It's possible to return a strong reference to None if the reference is dead. But it makes the API harder to handle since you have to handle Py_None reference count in the "dead reference" code path. In Python 3.12, Py_None is immortal. But I plan to add PyWeakref_GetRef() to https://pythoncapi-compat.readthedocs.io/ and on Python 3.11 and older, you have to carefully Py_DECREF(Py_None). |
|
Consider making this |
|
The proposed function cannot fail. If you use it on the wrong type, it does crash instead. |
|
I see. Different reasoning then. |
|
I agree with Petr; if the internals of the API changes in the future, it would be unfortunate if we also had to add a |
|
See also capi-workgroup/problems#20 |
|
I'm trying to fix race conditions by avoiding borrow references. If the API is modified so it can raise an exeption, it means that all callers must be updated to handle exceptions? That sounds like a lot of work. I don't see the point of making the API so it can raise an exeption, if there is no known case where it can happen. I would prefer to not modify PyWeakref_GetRef() to emit a cute exception if the argument is not a weak reference. I prefer to move this responsibility to the caller. The Modules/_abc.c code is an interesting example: it handles the rare case if an object which is not a weakref landed in the container. I would prefer to have an API simple to use when the caller controls the argument object type. |
Yes.
Please don't add it to the stable ABI. Maintaining that for decades is also a lot of work, and avoiding the work now means we'll pay in the future.
That's not necessary. |
* Add tests on PyWeakref_NewRef(), PyWeakref_GetObject(), PyWeakref_GET_OBJECT() and PyWeakref_GetRef(). * PyWeakref_GetObject() now raises a TypeError if the argument is not a weak reference, instead of SystemError.
|
Ok, Erlend and Petr convinced me, I updated my PR to use the API: |
* Replace PyWeakref_GET_OBJECT() with _PyWeakref_GET_REF(). * _sqlite/blob.c now holds a strong reference to the blob object while calling close_blob(). * _xidregistry_find_type() now holds a strong reference to registered while using it.
* Add _PyWeakref_IS_DEAD() internal function. * Modify is_dead_weakref() of Modules/_weakref.c and _pysqlite_drop_unused_cursor_references() to replace PyWeakref_GET_OBJECT() with _PyWeakref_IS_DEAD(). * Replace "int i" with "Py_ssize_t i" to iterate on cursors in _pysqlite_drop_unused_cursor_references().
* Replace PyWeakref_GET_OBJECT() with _PyWeakref_GET_REF(). * _sqlite/blob.c now holds a strong reference to the blob object while calling close_blob(). * _xidregistry_find_type() now holds a strong reference to registered while using it.
It now raises an exception if sys.modules doesn't hold a strong reference to the module. Elaborate the comment explaining why a weak reference is used to create a borrowed reference.
It now raises an exception if sys.modules doesn't hold a strong reference to the module. Elaborate the comment explaining why a weak reference is used to create a borrowed reference.
It now raises an exception if sys.modules doesn't hold a strong reference to the module. Elaborate the comment explaining why a weak reference is used to create a borrowed reference.
It now raises an exception if sys.modules doesn't hold a strong reference to the module. Elaborate the comment explaining why a weak reference is used to create a borrowed reference.
Deprecate PyWeakref_GetObject() and PyWeakref_GET_OBJECT() functions.
Deprecate PyWeakref_GetObject() and PyWeakref_GET_OBJECT() functions.
Remove _PyWeakref_GetWeakrefCount() and _PyWeakref_ClearRef() from the public C API: move them to the internal C API. Refactor also _weakref_getweakrefs() code to make it more readable.
Remove _PyWeakref_GetWeakrefCount() and _PyWeakref_ClearRef() from the public C API: move them to the internal C API. Refactor also _weakref_getweakrefs() code to make it more readable.
Deprecate PyWeakref_GetObject() and PyWeakref_GET_OBJECT() functions.
…T_REF() (python#105971) finalize_modules_clear_weaklist() now holds a strong reference to the module longer than before: replace PyWeakref_GET_OBJECT() with _PyWeakref_GET_REF().
Deprecate PyWeakref_GetObject() and PyWeakref_GET_OBJECT() functions.
The sqlite3 extension module should be built using the public API, so we're removing the Py_BUILD_CORE_MODULE define that was introduced as part of the pythongh-105927 changes.
|
Oh, PEP 703 – Making the Global Interpreter Lock Optional in CPython proposes PyWeakref_FetchObject() which is more or less the PyWeakref_GetRef() function that was just added to Python 3.13. |
|
I added |
PyWeakref_GetRef() now returns 1 on success, and return 0 if the reference is dead.
PyWeakref_GetRef() now returns 1 on success, and return 0 if the reference is dead. Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
PyWeakref_GET_OBJECT() and PyWeakref_GetObject() return a borrowed reference to the object, or a borrowed reference to None if the object has been finalized. This API is error-prone and not easy to use.
This API was discussed in 2016: https://mail.python.org/archives/list/python-dev@python.org/thread/6BIPI4MCMAZFLJNIZB4JLTBW2COCACQQ/
I propose adding a new PyWeakref_GetRef() C API function which returns a new strong reference to the object, or NULL if the object has been finalized.
Linked PRs
The text was updated successfully, but these errors were encountered: