-
-
Notifications
You must be signed in to change notification settings - Fork 52
c api next level changes
This document presents further details on the changes envisioned in Taking the C API to the Next Level.
A function returns a borrowed reference to a Python object obj if instead of returning a new reference to obj, it loans the caller an existing reference.
This saves the caller from having to call Py_DECREF(obj) but at the cost of exposing the lifetime of the reference as part of the API and preventing the Python implementation from knowing when the caller has finished using the borrowed reference.
As a simple example, imagine that a Python module contained t = (1, 2, 3) and that a Python implementation wished to efficiently store that tuple as int t[] = {1, 2, 3}. PyTuple_GetItem returns a borrowed reference, so calling PyTuple_GetItem(obj_t, 0) would require creating a new reference that could never be freed even though the caller would likely only require it for a short time.
A function steals a reference to a Python object obj when it takes over the responsibility of freeing the reference from the caller.
This exposes the lifetime of the stolen reference as part of the API.
For example, PyList_SetItem steals the reference to the item passed to it. The caller might then continue to use the reference (even though they shouldn't) and rely on the reference continuing to be valid for as long as the list exists.
Stolen references also make it harder to write correct code. Instead of being able to easily check where references are freed by reading the C code, one must also remember the long list of API functions that steal a reference. For example, PyList_SetItem steals a reference, but PyList_Insert and PyList_Append do not.
The current API exposes reference counting via Py_INCREF and Py_DECREF. Implementing the semantics of this API requires maintaining a counter for each object -- i.e. emulating reference counting.
It also requires references to be long-lived -- a reference must be valid for as long as the reference count is non-zero (i.e. for the object's entire lifetime).
It would be better to use an interface that allowed the caller of the API to explicitly communicate its own requirements via obj = Py_I_Need_A_New_Reference(...) and Py_I_Am_Done_With_This_Reference(obj) API functions. These would allow for shorter lived references that can be freed as soon as an individual caller is done with them.
- 5 September 2024
- 4 April 2024
- 7 March 2024
- 1 February 2024
- 11 January 2024
- 7 December 2023
- 9 November 2023
- 5 October 2023
- 14 September 2023
- 3 August 2023
- 6 July 2023
- 1 June 2023
- 4 May 2023
- 13 April 2023
- 2 March 2023
- 2 February 2023
- 12 January 2023
- 1 December 2022
- 3 November 2022
- 6 October 2022
- 8 September 2022
- 4 August 2022
- 7 July 2022
- 2 June 2022
- 5 May 2022
- 7 April 2022
- 3 March 2022
- 3 February 2022
- 13 January 2022
- 2 December 2021
- 4 November 2021
- 7 October 2021
- 2 September 2021
- 12 August 2021
- 8 July 2021
- 6 May 2021
- 4 March 2021
- 7 January 2021
- 3 December 2020
- 5 November 2020