API¶
This part of the documentation covers all the interfaces of bocpy.
Behaviors¶
- class bocpy.Cown(value)¶
Lightweight wrapper around the underlying cown capsule.
- acquire()¶
Acquires the cown (required for reading and writing).
- property acquired: bool¶
Whether the cown is currently acquired.
- property exception: bool¶
Whether the held value is the result of an unhandled exception.
- release()¶
Releases the cown.
- property value: T¶
Return the current stored value.
- @bocpy.when¶
Decorator to schedule a function as a behavior using given cowns.
This decorator takes a list of zero or more cown objects, which will be passed in the order in which they were provided to the decorated function. The function itself is extracted and run as a behavior once all the cowns are available (i.e., not acquired by other behaviors). Behaviors are scheduled such that deadlock will not occur.
The function itself will be replaced by a Cown which will hold the result of executing the behavior. This Cown can be used for further coordination.
Note: the transpiler matches
@whenby literal name. Aliasing the import (from bocpy import when as boc_when) is not supported – the rewrite will not fire and the worker will fail.
- bocpy.wait(timeout=None, *, stats=False)¶
Block until all behaviors complete, with optional timeout.
When
stats=True, returns the per-worker_core.scheduler_stats()snapshot captured at shutdown (after all behaviors have run, before the per-worker array is freed). Whenstats=False(the default), returnsNone. Returns[]if the runtime was never started or the snapshot could not be captured.
- bocpy.start(worker_count=None, module=None)¶
Start the behavior runtime: worker pool plus noticeboard thread.
The runtime distributes scheduling (2PL link/release) across caller and worker threads; there is no central scheduler thread.
- Parameters:
worker_count (
Optional[int]) – The number of worker interpreters to start. If None, defaults to the number of available cores minus one.module (
Optional[tuple[str,str]]) – A tuple of the target module name and file path to export for worker import. If None, the caller’s module will be used.
Cown Groups¶
In addition to passing individual cowns to @when, you can pass a
list of cowns to acquire an entire group atomically. The list is
delivered to the behavior parameter as a list[Cown]:
from bocpy import Cown, when, wait
items = [Cown(i) for i in range(5)]
@when(items)
def _(items):
# `items` is a list[Cown] — all five acquired together
total = sum(c.value for c in items)
print("Sum:", total)
wait()
You can mix individual cowns and groups freely:
summary = Cown(0)
items = [Cown(i) for i in range(5)]
@when(summary, items)
def _(summary, items):
summary.value = sum(c.value for c in items)
Each argument to @when becomes one parameter of the decorated function:
a single Cown is passed directly, while a list is delivered as a
list[Cown].
Runtime Lifecycle¶
The bocpy runtime follows a simple lifecycle:
Start — the first
@whencall (or an explicitstart()) spawns the worker sub-interpreters and the noticeboard thread.Schedule —
@when/whencall()schedules behaviors against cowns. Scheduling and release run on the caller and worker threads; there is no central scheduler thread.Wait —
wait()blocks until all scheduled behaviors complete, then tears down the runtime (joins workers, closes the noticeboard).Re-start — after
wait()returns, the next@whencall spins up a fresh runtime. The noticeboard is cleared and worker statistics are reset; existingCownobjects survive and can be scheduled against the new runtime.
- bocpy.WORKER_COUNT = 3¶
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
Advanced¶
Noticeboard¶
See the Noticeboard guide for a conceptual overview, consistency model, and worked examples.
- bocpy.notice_write(key, value)¶
Write a value to the noticeboard.
The write is fire-and-forget: the value is serialized immediately and handed to a dedicated noticeboard thread, which applies it under mutex.
notice_writereturns as soon as the message is enqueued.No ordering guarantee. A subsequent behavior — even one that chains directly off the writer through a shared cown — is not guaranteed to observe this write. The noticeboard mutator runs on its own thread and may not have processed the message by the time the next behavior reads. Treat the noticeboard as eventually consistent shared state, never as a synchronization channel between behaviors. Use cowns or
send/receivefor that.The noticeboard supports up to 64 distinct keys. Writes beyond the limit are not applied; the noticeboard thread catches the resulting error and logs a warning. No exception propagates to the caller.
- Parameters:
key (
str) – The noticeboard key (max 63 UTF-8 bytes).value (
Any) – The value to store.
- Return type:
None
- bocpy.notice_update(key, fn, default=None)¶
Atomically update a noticeboard entry.
Reads the current value for key (or default if absent), applies fn to it, and writes the result back. The read-modify-write is atomic because the single-threaded noticeboard mutator performs all three steps without interleaving.
Like
notice_write(), the call is fire-and-forget and carries no ordering guarantee with respect to other behaviors. The update is processed on the noticeboard thread; subsequent behaviors may or may not observe the result.Both fn and default must be picklable — they are serialized and sent to the noticeboard thread via the message queue. Lambdas and closures are not picklable; use
functools.partialwith a module-level function or anoperatorfunction instead:import operator from functools import partial notice_update("total", partial(operator.add, 5), default=0) notice_update("best", partial(max, 42), default=float("-inf"))
If fn raises, the key retains its previous value and a warning is logged by the noticeboard thread.
Important: fn runs synchronously on the single-threaded noticeboard mutator. It must be fast, pure (no side effects), and must not call any bocpy API (
notice_write,send,when, etc.). A blocking or expensive fn will stall every other noticeboard mutation.If fn returns the
REMOVEDsentinel, the entry is deleted from the noticeboard instead of being updated.Warning
fn and default are pickled and sent to the noticeboard thread for execution. Anyone with permission to call this function can therefore cause arbitrary Python code to run on the noticeboard thread, which holds the privileged noticeboard-mutator role. In the current threat model bocpy treats all code running in the runtime (primary and sub-interpreters) as equally trusted, so this is no worse than any other cross-interpreter message. If you need to run untrusted behavior code, restrict what can reach
boc_noticeboardand audit callers ofnotice_update().- Parameters:
key (
str) – The noticeboard key (max 63 UTF-8 bytes).fn (
Callable[[Any],Any]) – A picklable callable taking the current value, returning the new.default (
Any) – Value used when key does not yet exist.
- Return type:
None
- bocpy.notice_delete(key)¶
Delete a single noticeboard entry.
The deletion is fire-and-forget: the request is sent to the noticeboard thread, which removes the entry under mutex. If the key does not exist, the operation is a no-op. Like
notice_write(), this carries no ordering guarantee with respect to other behaviors.Alternatively, use
notice_updatewith a function that returnsREMOVEDto conditionally delete an entry based on its current value.- Parameters:
key (
str) – The noticeboard key to delete (max 63 UTF-8 bytes).- Return type:
None
- bocpy.noticeboard()¶
Return a cached snapshot of the noticeboard.
Must be called from within a
@whenbehavior. The first call within a behavior captures all entries under mutex and caches the data. Subsequent calls in the same behavior return a view of the same cached data.The returned mapping is read-only.
Calling from outside a behavior (e.g. the main thread) will return a snapshot that is never refreshed for that thread.
- Returns:
A read-only mapping of keys to their stored values.
- Return type:
Mapping[str,Any]
- bocpy.notice_read(key, default=None)¶
Read a single key from the noticeboard.
Must be called from within a
@whenbehavior. Convenience wrapper that takes a snapshot and returns one value.Calling from outside a behavior (e.g. the main thread) will return a snapshot that is never refreshed for that thread.
- Parameters:
key (
str) – The noticeboard key to read.default (
Any) – Value returned when key is absent.
- Returns:
The stored value, or default if the key does not exist.
- Return type:
Any
- bocpy.notice_sync(timeout=30.0)¶
Block until the caller’s prior noticeboard mutations are committed.
Because
notice_write(),notice_update(), andnotice_delete()are fire-and-forget, a behavior that wants read-your-writes ordering against a subsequent behavior must callnotice_sync()after its writes. The call posts a sentinel onto theboc_noticeboardtag (which is FIFO per producer) and blocks until the noticeboard thread has drained that sentinel. By the time this returns, every write/update/delete posted from the calling thread before the sentinel has been applied to the noticeboard.The barrier carries no ordering guarantee with respect to writes posted from other threads or behaviors interleaved with the caller’s; it only flushes the caller’s own queued mutations.
- Parameters:
timeout (
Optional[float]) – Maximum seconds to wait.Nonewaits forever. Defaults to 30 seconds.- Raises:
TimeoutError – If the noticeboard thread does not drain the caller’s sentinel within timeout seconds.
RuntimeError – If the runtime is not started.
- Return type:
None
- bocpy.REMOVED = REMOVED¶
Sentinel returned by notice_update fn to delete the entry.
Math¶
- class bocpy.Matrix(rows, columns, values=None)¶
A dense 2-D matrix of double-precision floats.
- T¶
Return a new matrix that is the transpose of this one.
- __init__(*args, **kwargs)¶
Create a new rows x columns matrix.
- Parameters:
rows – Number of rows (must be ≥ 1).
columns – Number of columns (must be ≥ 1).
values – Initial values. May be
None(zero-filled), a scalar (broadcast to every element), or a flat sequence of rows x columns numbers in row-major order.
- abs()¶
Element-wise absolute value.
- Return type:
Matrix
- acquired¶
Whether the matrix is currently acquired.
- classmethod allclose(lhs, rhs, /, rtol=1e-05, atol=1e-08, equal_nan=False)¶
Check element-wise equality within tolerance.
- ceil()¶
Element-wise ceiling.
- Return type:
Matrix
- clip(min_or_maxval, /, maxval=None)¶
Clip elements to a range.
- Return type:
Matrix
- columns¶
The number of columns in the matrix.
- classmethod concat(values, /, axis=0)¶
Concatenate matrices along an axis.
- Return type:
Matrix
- copy()¶
Return a deep copy.
- Return type:
Matrix
- floor()¶
Element-wise floor.
- Return type:
Matrix
- magnitude(axis=None)¶
Euclidean magnitude.
- Return type:
Union[float, Matrix]
- max(axis=None)¶
Maximum of elements.
- Return type:
Union[float, Matrix]
- mean(axis=None)¶
Mean of elements.
- Return type:
Union[float, Matrix]
- min(axis=None)¶
Minimum of elements.
- Return type:
Union[float, Matrix]
- negate()¶
Element-wise negation.
- Return type:
Matrix
- classmethod normal(mean=0.0, stddev=1.0, /, size=None)¶
Sample from a normal distribution.
- Return type:
Union[float, Matrix]
- classmethod ones(size, /)¶
Create a matrix of ones.
- round()¶
Element-wise rounding.
- Return type:
Matrix
- rows¶
The number of rows in the matrix.
- select(indices, /, axis=0)¶
Select rows or columns by index.
- shape¶
The
(rows, columns)shape of the matrix.
- sum(axis=None)¶
Sum of elements.
- Return type:
Union[float, Matrix]
- transpose()¶
Return a transposed copy.
- Return type:
Matrix
- transpose_in_place()¶
Transpose in place.
- classmethod uniform(minval=0.0, maxval=1.0, /, size=None)¶
Sample from a uniform distribution.
- Return type:
Union[float, Matrix]
- classmethod vector(values, /, as_column=False)¶
Create a vector from a sequence.
- Return type:
Matrix
- w¶
Set the fourth vector component.
- x¶
Set the first vector component.
- y¶
Set the second vector component.
- z¶
Set the third vector component.
- classmethod zeros(size, /)¶
Create a zero-filled matrix.
Messaging¶
See the Messaging guide for a conceptual overview, the selective-receive pattern, timeouts, and a worked calculator example.
- bocpy.send(tag, contents, /)¶
Sends a message.
- bocpy.receive(tags, /, timeout=-1, after=None)¶
Receives a message.
- bocpy.set_tags(tags, /)¶
Assigns tags to message queues.
- bocpy.drain(tags, /)¶
Drains all messages for the given tags.
- bocpy.TIMEOUT = '__timeout__'¶
str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.
C ABI¶
See C ABI for the full usage contract for downstream C extensions that want to interoperate with bocpy at the C level.
- bocpy.get_include()¶
Return the absolute path to the bocpy public C header root.
Use the returned path as an additional
include_dirsentry on a downstreamsetuptools.Extensionso its translation units can#include <bocpy/bocpy.h>. The directory contains a singlebocpy/subdirectory holding the public ABI surface; bocpy’s private headers are not exposed.- Returns:
Absolute filesystem path to the include root (the parent of the
bocpy/subdirectory containingbocpy.handxidata.h).- Return type:
str
- bocpy.get_sources()¶
Return platform-specific extra C sources for downstream extensions.
On Windows the returned list contains the absolute path to
bocpy_msvc.c, which provides MSVC out-of-line bodies for the atomic ops declared in<bocpy/bocpy.h>. On non-Windows platforms the list is empty (<stdatomic.h>provides everything).- Returns:
A list of absolute paths to add to a downstream
setuptools.Extension’ssources=list.- Return type:
list[str]