Per capi-workgroup/problems#11, we need terms for managing ownership.
IMO, it would be useful to use similar terms both for references and to non-refcounted resources -- typically, allocated memory.
Arguments
By default, ownership of arguments is not transferred. After a call:
- the caller is still responsible for decrefing/freeing any arguments it passed in.
- the callee must not assume the argument stays valid.
The caller must guarantee that the arguments stay valid for the duration of the call.
“Output” arguments (where the callee gets a *result pointer and fills it) follow rules for return values.
We should use shorter, context-specific terms for transferring ownership (the non-default-behaviour):
- Steal: take ownership of
PyObject* or other refcounted/GCd data (i.e. other references might exist). Used for performance optimizations or ergonomics.
- Consume: used for non-refcounted data (e.g. array of
PyObject*), e.g. string builder finalization API would consume the scratch data and return a new object
- Clear: Destroy a reference and mark it invalid (i.e. set the
PyObject* to NULL)
- conflicts with the term for emptying a container
- Decref, Close, Free, Dealloc: specific API that only destroys the reference/data
I'm aware that Steal is pejorative; but IMO it's better than the alternative (Take, Give, Move)
Another useful exception is:
- Static: The argument is static and immutable; it does not need to be freed and is always valid.
Return values
By default, ownership of the return value is transferred. After a call:
- the caller is responsible for decrefing/freeing the return value.
- the callee must not assume the return value stays valid
The opposite is:
-
Borrow: the caller must not decref/free the return value, but is responsible for ensuring that it is not accessed after its lifetime ends. Docs for the called function need to indicate what that lifetime is.
-
Static is, conceptually, borrowing from the interpreter itself.
Per capi-workgroup/problems#11, we need terms for managing ownership.
IMO, it would be useful to use similar terms both for references and to non-refcounted resources -- typically, allocated memory.
Arguments
By default, ownership of arguments is not transferred. After a call:
The caller must guarantee that the arguments stay valid for the duration of the call.
“Output” arguments (where the callee gets a
*resultpointer and fills it) follow rules for return values.We should use shorter, context-specific terms for transferring ownership (the non-default-behaviour):
PyObject*or other refcounted/GCd data (i.e. other references might exist). Used for performance optimizations or ergonomics.PyObject*), e.g. string builder finalization API would consume the scratch data and return a new objectPyObject*toNULL)I'm aware that Steal is pejorative; but IMO it's better than the alternative (Take, Give, Move)
Another useful exception is:
Return values
By default, ownership of the return value is transferred. After a call:
The opposite is:
Borrow: the caller must not decref/free the return value, but is responsible for ensuring that it is not accessed after its lifetime ends. Docs for the called function need to indicate what that lifetime is.
Static is, conceptually, borrowing from the interpreter itself.