title: C API Essentials icon: dot
Include pocketpy.h and initialize the runtime before calling the API.
The quick start has a complete host program.
Public declarations live in
pocketpy.h;
the function reference is generated from that header.
Read execution and exceptions for calls and error handling, module loading for imports, and C bindings for native functions.
A py_Ref points to a slot containing a Python value. Copying the C pointer
does not copy the value or keep its object alive. Use py_assign(dst, src)
to copy a value into another valid slot. pocketpy uses garbage collection, so
there is no public Py_INCREF/Py_DECREF protocol.
The reference typedefs have the same C representation but document different lifetimes:
| Type | Meaning and lifetime |
|---|---|
py_Ref |
Generic reference; the function returning it determines its lifetime. |
py_GlobalRef |
VM-owned reference; invalid after VM reset or finalization. |
py_StackRef |
Value-stack slot; valid while that slot remains on the stack. |
py_ObjectRef |
Slot owned by an object; the owner must remain alive. |
py_ItemRef |
Container item; reacquire it after modifying the container. |
py_OutRef |
A caller-provided destination slot for an output value. |
A local C variable containing a reference is not a garbage-collector root. Keep values in a VM register, on the value stack, or in a reachable Python container or module for as long as they are needed.
| Storage | Use |
|---|---|
py_r0() ... py_r7() |
Eight application registers. Shared with other native code using the same VM. |
py_tmpr0() ... py_tmpr3() |
Scratch registers also used internally; do not keep values here across API calls. |
py_retval() |
Return slot, overwritten by operations producing a result. |
py_sysr0(), py_sysr1() |
Reserved for the debugger and C++ binding layer. |
py_push(), py_pushtmp() |
Stack storage for values that must survive nested calls. |
py_peek(-1) addresses the top value. py_peek(0) is the stack boundary,
useful as a saved position for error recovery; it is not an initialized value.
This fragment runs after initialization and creates a rooted list:
py_StackRef values = py_pushtmp();
py_newlistn(values, 3);
py_newint(py_list_getitem(values, 0), 10);
py_newint(py_list_getitem(values, 1), 20);
py_newint(py_list_getitem(values, 2), 30);
py_setglobal(py_name("scores"), values);
py_pop(); /* The __main__.scores global now keeps the list alive. */
Initialize a slot returned by py_pushtmp() immediately. On successful return
from a native function, pop every temporary you pushed. On failure, propagate
the exception to the caller; the host's recovery boundary restores the stack.
See exception handling.
| Python value | Create from C | Read in C |
|---|---|---|
int (signed 64-bit) |
py_newint(out, value) |
py_toint(ref) returning py_i64 |
float (double) |
py_newfloat(out, value) |
py_tofloat(ref) |
bool |
py_newbool(out, value) |
py_tobool(ref) |
UTF-8 str |
py_newstr(out, text), py_newstrv(out, view) |
py_tostr(ref), py_tosv(ref) |
bytes |
py_newbytes(out, size), then fill the returned buffer |
py_tobytes(ref, &size) |
None |
py_newnone(out) |
py_isnone(ref) |
The py_to* functions are low-level accessors, not general Python conversions.
Check types first with py_checktype() or the PY_CHECK_ARG_TYPE macro.
For a numeric input accepting either int or float, use
py_castfloat(ref, &value) and check its boolean result. Range-check before
narrowing a py_i64 to a smaller C integer.
String and byte pointers refer to interpreter-owned memory. Copy the data if it
must outlive the owning object. Use c11_sv or an explicit byte length for data
that may contain embedded NUL characters.
PY_RAISE macroMarks an operation that can set a Python exception. A boolean return of false
indicates failure; for integer-returning operations, -1 indicates failure.
Other integer values have function-specific meanings: for example,
py_import() returns 0 for "not found" and 1 for success.
PY_RETURN macroMarks an operation whose successful result is written to py_retval().
Read or copy it before another operation overwrites it.
PY_MAYBENULL macroMarks a pointer or callback that may be NULL. Check the function's contract
before dereferencing it.
These macros document contracts; they do not perform checks themselves.
py_initialize() creates VM 0. Up to 16 VM slots exist, selected with
py_switchvm(index). A value belongs to its VM and must not be passed to
another VM. Each VM can be used by only one thread at a time; see
compute threads.
py_resetvm() discards the current VM's state, invalidating its references.
py_finalize() destroys all VMs and is terminal for the process: the API must
not be used afterward.