Setu 2026.11.9
static
YoSTEALTH/Setu
Edit

6. Buffers and ownership#

Type (locked; released by): use.

/// What `own` keeps.
var owned: struct {
    buf: ?py.OwnedWritableBuffer = null,
    data: ?py.OwnedBuffer = null,
} = .{};

/// Releases what the last call kept, then keeps `buf` and `data` as they come (`py.OwnedWritableBuffer` /
/// `py.OwnedBuffer`, no second view): locked until the next call. `own()` only releases; with
/// `drop=True` the function releases them itself before returning.
pub fn own(buf: ?py.OwnedWritableBuffer, data: ?py.OwnedBuffer, drop: ?bool) void {
    if (owned.buf) |b| b.deinit();
    if (owned.data) |d| d.deinit();
    owned = .{};
    if (drop orelse false) {
        if (buf) |b| b.deinit();
        if (data) |d| d.deinit();
        return;
    }
    owned = .{ .buf = buf, .data = data };
}

In Python, a kept bytearray is locked (it can not be resized) until the extension releases it:

>>> from pkg import own
>>> b = bytearray(3)
>>> own(b)  # kept
>>> b.append(1)
Traceback (most recent call last):
  ...
BufferError: Existing exports of data: object cannot be re-sized
>>> b[0] = 7  # writing is fine
>>> own()  # released
>>> b.append(1)
>>> b
bytearray(b'\x07\x00\x00\x01')

Rules: when a later argument fails to convert, the function is not called and Setu releases everything, owned buffers included; once the function runs, an owned buffer is its own, on error paths too. A Sequence of an owned buffer type is a compile error (use Sequence(Buffer) and take), take of an owned buffer too. take asks the argument itself for the second view, so an object with a Python __buffer__ can be kept too. A buffer whose view has no object (PyBuffer_FillInfo(NULL)) raises BufferError on take. On 3.14t / 3.15t a bytearray argument costs 10-15 ns more: CPython's own critical section.

Generated by tool/setu_doc.py from the docstrings of Setu 2026.11.9.