Skip to main content

bocpy

BOC Logo

Behavior-Oriented Concurrency (BOC) is a new paradigm for parallel and concurrent programming which is particularly well-suited to Python. In a BOC program, data is shared such that each behavior has unique temporal ownership of the data, removing the need for locks to coordinate access. For Python programmers, this brings a lot of benefits. Behaviors are implemented as decorated functions, and from the programmer's perspective, those functions work like normal. Importantly, the programmer's task shifts from solving concurrent data access problems to organizing data flow through functions. The resulting programs are easier to understand, easier to support, easier to extend, and unlock multi-core performance due to the ability to schedule behaviors to run efficiently across multiple sub-interpreters.

BOC has been implemented in several languages, including as a foundational aspect of the research language Verona, and now has been implemented in Python.

Getting Started

You can install bocpy via PyPi:

pip install bocpy

We provide pre-compiled wheels for Python 3.10 onwards on most platforms, but if you have problems with your particular platform/version combination, please file an issue on this repository.

[!NOTE] We provide wheels for Python 3.10 and newer, but bocpy only achieves true parallelism on Python 3.12+, where each sub-interpreter has its own GIL. On 3.10 and 3.11 behaviors still run, but they are serialised by the global GIL. The library may not work on Python versions older than 3.10.

Python version support

The mainline (main) branch in the diagram is the standard CPython build:

  • 3.10 / 3.11 — wheels are published and @when works, but every sub-interpreter still shares one process-wide GIL, so behaviors execute one at a time. Use these versions for portability rather than performance.
  • 3.12+ — each sub-interpreter gets its own GIL (PEP 684), so worker behaviors run in parallel across cores. This is where bocpy delivers on its concurrency story.
  • 3.14 is the current default development and CI target; 3.15 is validated as it stabilises.

The free-threaded branch tracks the no-GIL CPython builds (informally "3.13t", "3.14t", "3.15t" — see PEP 703). bocpy runs unmodified on these interpreters today: we don't re-enable the GIL, and the cown / 2PL protocol gives the same data-race-free guarantees you get on the GIL build. The catch is overhead — on free-threaded Python, the sub-interpreter and XIData machinery is pure ceremony, since plain threads in the main interpreter would already run in parallel.

Issue #5 tracks adding an alternative direct-threading backend that detects a free-threaded interpreter at runtime and skips the sub-interpreter / transpiler / XIData path entirely, while keeping the public Cown / @when API unchanged. We're holding off on that work until the free-threaded build and the relevant CPython APIs stabilise.

Scaling with cores

The chart below shows BOC runtime throughput as the worker count grows from 1 to 8, plotted as speedup relative to a single worker. Numbers come from examples/benchmark.py — a chain-ring workload that exercises the scheduler, two-phase locking, sub-interpreter crossings and the message queue together — run on CPython 3.14 (mean of 3 repeats, 8 s each).

Up to 8 workers, BOC delivers roughly linear scaling on this microbenchmark (≈7.5× at 8 workers). Real applications carry serial costs that this benchmark deliberately strips out — see the docstring at the top of examples/benchmark.py for the load-bearing caveats. To reproduce:

python examples/benchmark.py \
    --sweep-axis workers --sweep-values 1,2,3,4,5,6,7,8 \
    --duration 8 --warmup 2 --repeats 3 \
    --output scaling.json

A behavior can be thought of as a function which depends on zero or more concurrently-owned data objects (which we call cowns). As a programmer, you indicate that you want the function to be called once all of those resources are available. For example, let's say that you had two complex and time-consuming operations, and you needed to act on the basis of both of their outcomes:

def buy_cheese():
    logger = logging.getLogger("cheese_shop")
    for name in all_known_cheeses():
        if is_available(logger, name):
            return name
    
    cleanup_shop(logger)
    return None


def order_meal(exclude: str):
    logger = logging.getLogger("greasy_spoon")
    for dish in menu():
        logger.info(dish)
        if exclude.lower() not in dish.lower():
            logger.info(f"That doesn't have much {exclude} in it")
            return dish

        vikings(logger)
        if random.random() < 0.3:
            logger.info("<bloody vikings>")

    return None


cheese = buy_cheese()
meal = order_meal(exclude="spam")

if meal is not None:
    eat(meal)
elif cheese is not None:
    eat(cheese)

if meal is not None:
    print("I really wanted some cheese...")
elif cheese is not None:
    print("Cheesy comestibles")

return_to_library()

The code above will work, but requires the purveying of cheese and the navigation of the menu for non-spam options to happen sequentially. If we wanted to do these tasks in parallel, we will end up with some version of nested waiting, which can result in deadlock. With BOC, we would write the above like this:

from bocpy import wait, when, Cown

# ...

def buy_cheese():
    cheese = Cown(None)

    @when(cheese)
    def _(cheese):
        logger = logging.getLogger("cheese_shop")
        for name in all_known_cheeses():
            if is_available(logger, name):
                cheese.value = name
                return

        cleanup_shop(logger)

    return cheese


def order_meal(exclude: str):
    order = Cown(None)

    @when(order)
    def _(order, exclude=exclude):
        logger = logging.getLogger("greasy_spoon")
        logger.info("We have...")
        for dish in menu():
            logger.info(dish)
            if exclude.lower() not in dish.lower():
                logger.info(f"That doesn't have much {exclude} in it")
                order.value = dish
                return

            vikings(logger)
            if random.random() < 0.3:
                logger.info("<bloody vikings>")

    return order


cheese = buy_cheese()
meal = order_meal(exclude="spam")


@when(cheese, meal)
def _(cheese, meal):
    if meal.value is not None:
        eat(meal.value)
    elif cheese.value is not None:
        eat(cheese.value)
    else:
        print("<stomach rumbles>")


@when(cheese, meal)
def _(cheese, meal):
    if meal.value is not None:
        print("I really wanted cheese...")
    elif cheese.value is not None:
        print("Cheesy comestibles!")

    return_to_library()


wait()

You can view the full example here

The BOC runtime ensures that this operates without deadlock, by construction.

Talking to main-thread objects

Some values can't survive an XIData round-trip — pyglet shapes, Tk widgets, open file handles, ctypes pointers into a library loaded by __main__, a GPU context. Wrap those in a PinnedCown. Behaviors whose request set contains any pinned cown run on the main thread, drained by pump() from your event loop (or implicitly by wait()).

Keep dispatch coarse — one pinned @when per frame, not per item — so the single-consumer main thread doesn't serialise your worker parallelism. The pump() call drains whatever pinned behaviors are queued and returns immediately when the queue is empty (it never blocks), so it is safe to call from a tight render-loop tick. Hosts that want a starvation warning when the queue stays non-empty can enable it explicitly with set_pump_watchdog(); with no call, the runtime stays silent.

from bocpy import Cown, PinnedCown, pump, start, when

start()
canvas = PinnedCown(MyCanvas())  # main-thread-only handle

def update(dt):
    pump()                                     # drains prior frame's write-back; returns immediately if nothing is queued
    results = [worker_compute(i) for i in range(n)]  # per-item worker @whens

    @when(*results, canvas)                    # one pinned behavior per frame
    def _writeback(*args):
        *cells, canvas = args
        for cell in cells:
            canvas.value.draw(cell.value)

See the Pinned Cowns guide for the coarse-grained dispatch pattern, event-loop integration recipes (pyglet, Tk, asyncio), and the starvation watchdog.

Examples

We provide a few examples to show different ways of using BOC in a program:

  1. bocpy-bank: Shows an example where two objects (in this case, bank accounts), interact in an atomic way.
  2. bocpy-dining-philosophers: The classic Dining Philosphers problem implemented using BOC.
  3. bocpy-fibonacci: A parallel implementation of Fibonacci calculation.
  4. bocpy-cooking-boc: The example from the BOC tutorial.
  5. bocpy-boids: An agent-based bird flocking example demonstrating the Matrix class for parallel per-cell physics on workers, with one PinnedCown-driven @when per frame batching the pyglet-visible write-back (the coarse-grained pinned-dispatch pattern). Note: you'll need to install pyglet first in order to run the bocpy-boids example.
  6. bocpy-primes and bocpy-prime-factor: parallel prime sieve and Pollard's rho factorisation, the latter coordinating early termination via the noticeboard.
  7. bocpy-calculator: a small Erlang-style calculator service driven by send/receive.
  8. bocpy-cooking-threads: the cooking example written with plain threads, for comparison with bocpy-cooking-boc.
  9. bocpy-sketches: the cheese-and-spam sketch shown above as a runnable script.

Why BOC for Python?

Python has always had data races — compound operations like x += 1 are not atomic, even under the GIL — and with the arrival of free-threaded builds (Python 3.13t+) the surface area for concurrency bugs is only growing. BOC eliminates these problems by construction: because behaviors interact with shared data exclusively through cowns, each behavior operates over its data as if it were single-threaded. There is no lock ordering to get right, no forgotten acquire()/release(), and no possibility of deadlock. This holds whether your program runs under the GIL, on per-interpreter GIL (3.12+), or on a free-threaded interpreter.

This library

Our implementation is built on top of the sub-interpreters mechanism and the Cross-Interpreter Data (XIData) API. As of Python 3.12 each sub-interpreter has its own GIL, so behaviors scheduled by bocpy run truly in parallel.

The core scheduling engine is written in C — it is not a wrapper around locks, message queues, or asyncio. Each Cown is backed by a C-level capsule that embeds an MCS-style queue of pending behaviors. When you call @when(a, b), the runtime performs two-phase locking (2PL) over the sorted cown IDs entirely in C (releasing the GIL across the lock-free link loops). Once all cowns in a behavior's request set are acquired, the behavior is dispatched directly to a worker — there is no central scheduler thread and no OS-level lock acquisition on the fast path. Releasing a cown unlinks the MCS node and hands ownership to the next waiting behavior in O(1), which is then dispatched without touching any shared queue. This gives bocpy the same deadlock-freedom-by-construction guarantee as the original Verona runtime.

For cross-behavior data sharing that does not warrant a Cown, the library also provides a small noticeboard — a global key-value store of up to 64 entries. Behaviors can notice_write, notice_update (atomic read-modify-write) and notice_delete keys without acquiring any cowns, and read a frozen snapshot via noticeboard() / notice_read(). The bocpy-prime-factor example uses it to coordinate early termination across worker behaviors.

For values that can't survive an XIData round-trip — UI handles, GPU contexts, file descriptors — the library provides PinnedCown, a cown whose value lives permanently in the main interpreter. Behaviors against a pinned cown run on the main thread, drained by pump() from your event loop or implicitly by wait(). The full surface is PinnedCown, pump, PumpResult, set_pump_watchdog, and set_wait_pump_poll; the bocpy-boids example drives a pyglet window through one pinned @when per frame. See the Pinned Cowns guide for the coarse-grained dispatch pattern, watchdog, and free-threaded support trajectory.

The library also includes lower-level Erlang-style messaging primitives (send / receive) for channel-based communication patterns; see the API documentation for details.

Waiting for completion

Call wait() after scheduling all your behaviors. It blocks the calling thread until every scheduled behavior has finished, then tears down the runtime (joins workers, closes the noticeboard). The next @when call will spin up a fresh runtime automatically.

wait()          # block indefinitely
wait(timeout=5) # raise TimeoutError if not done in 5 s

For a synchronization checkpoint that does not tear the runtime down — e.g. a parallel search that inspects a best-so-far cown between rounds and then continues — use quiesce() instead. It blocks until every in-flight behavior completes, optionally returns a per-worker stats or noticeboard snapshot, and leaves the worker pool and the noticeboard thread running so the next @when call dispatches immediately.

from bocpy import quiesce

snap = quiesce(noticeboard=True)  # dict[str, Any]
print("best so far:", snap.get("best"))
# ... schedule the next round of @when calls ...

Additional Info

BOC is built on a solid foundation of serious scholarship and engineering. For further reading, please see:

  1. When Concurrency Matters: Behaviour-Oriented Concurrency
  2. Reference implementation in C#
  3. OOPSLA23 Talk

C API stability

bocpy is implemented as a CPython C extension that links against the private cross-interpreter data API — _PyXIData_* on 3.14+, _PyCrossInterpreterData_* on 3.12 / 3.13, and on 3.13+ the internal header internal/pycore_crossinterp.h (which requires Py_BUILD_CORE). Under PEP 689 these symbols are explicitly unstable: they may change shape, semantics, or disappear entirely between CPython minor releases, and there is no PyPI / setuptools metadata field that advertises this kind of dependency. The practical consequences are:

  • Per-minor wheels. Because we do not target the limited API (Py_LIMITED_API / abi3), every wheel carries a version-specific ABI tag (cp310, cp311, …, cp315). pip will only install a wheel that matches the running interpreter's minor version. The Programming Language :: Python :: 3.x classifiers in pyproject.toml mirror this set.
  • Source builds may lag CPython. Alpha / beta / RC builds of a new CPython minor frequently rename or reshape these private symbols. When that happens, bocpy's xidata.h shim needs an update before it will compile against the new headers; until then, install on a released minor version.
  • No CPython implementation other than CPython itself. The internal cross-interpreter machinery is CPython-specific, which is why the only implementation classifier we set is Programming Language :: Python :: Implementation :: CPython. PyPy, GraalPy, and other alternatives are not supported.

The compatibility ladder lives in src/bocpy/include/bocpy/xidata.h; the Py_BUILD_CORE #define / #undef save-and-restore there is scoped narrowly to the one #include that needs it, so downstream C extensions that pull in bocpy.h do not inherit it.

Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bocpy-0.11.0.tar.gz (360.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

bocpy-0.11.0-cp314-cp314-win_amd64.whl (193.7 kB view details)

Uploaded CPython 3.14Windows x86-64

bocpy-0.11.0-cp314-cp314-win32.whl (189.4 kB view details)

Uploaded CPython 3.14Windows x86

bocpy-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl (499.1 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

bocpy-0.11.0-cp314-cp314-manylinux_2_28_x86_64.whl (505.5 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

bocpy-0.11.0-cp314-cp314-macosx_14_0_x86_64.whl (203.0 kB view details)

Uploaded CPython 3.14macOS 14.0+ x86-64

bocpy-0.11.0-cp314-cp314-macosx_11_0_arm64.whl (196.4 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

bocpy-0.11.0-cp313-cp313-win_amd64.whl (191.2 kB view details)

Uploaded CPython 3.13Windows x86-64

bocpy-0.11.0-cp313-cp313-win32.whl (187.1 kB view details)

Uploaded CPython 3.13Windows x86

bocpy-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl (498.4 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

bocpy-0.11.0-cp313-cp313-manylinux_2_28_x86_64.whl (504.8 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bocpy-0.11.0-cp313-cp313-macosx_14_0_x86_64.whl (202.9 kB view details)

Uploaded CPython 3.13macOS 14.0+ x86-64

bocpy-0.11.0-cp313-cp313-macosx_11_0_arm64.whl (196.2 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

bocpy-0.11.0-cp312-cp312-win_amd64.whl (191.3 kB view details)

Uploaded CPython 3.12Windows x86-64

bocpy-0.11.0-cp312-cp312-win32.whl (187.2 kB view details)

Uploaded CPython 3.12Windows x86

bocpy-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl (500.5 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

bocpy-0.11.0-cp312-cp312-manylinux_2_28_x86_64.whl (507.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bocpy-0.11.0-cp312-cp312-macosx_14_0_x86_64.whl (203.1 kB view details)

Uploaded CPython 3.12macOS 14.0+ x86-64

bocpy-0.11.0-cp312-cp312-macosx_11_0_arm64.whl (196.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

bocpy-0.11.0-cp311-cp311-win_amd64.whl (191.3 kB view details)

Uploaded CPython 3.11Windows x86-64

bocpy-0.11.0-cp311-cp311-win32.whl (187.0 kB view details)

Uploaded CPython 3.11Windows x86

bocpy-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl (494.3 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

bocpy-0.11.0-cp311-cp311-manylinux_2_28_x86_64.whl (499.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

bocpy-0.11.0-cp311-cp311-macosx_14_0_x86_64.whl (203.0 kB view details)

Uploaded CPython 3.11macOS 14.0+ x86-64

bocpy-0.11.0-cp311-cp311-macosx_11_0_arm64.whl (196.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

bocpy-0.11.0-cp310-cp310-win_amd64.whl (191.5 kB view details)

Uploaded CPython 3.10Windows x86-64

bocpy-0.11.0-cp310-cp310-win32.whl (186.9 kB view details)

Uploaded CPython 3.10Windows x86

bocpy-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl (485.6 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

bocpy-0.11.0-cp310-cp310-manylinux_2_28_x86_64.whl (490.4 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

bocpy-0.11.0-cp310-cp310-macosx_14_0_x86_64.whl (203.2 kB view details)

Uploaded CPython 3.10macOS 14.0+ x86-64

bocpy-0.11.0-cp310-cp310-macosx_11_0_arm64.whl (196.9 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file bocpy-0.11.0.tar.gz.

File metadata

  • Download URL: bocpy-0.11.0.tar.gz
  • Upload date:
  • Size: 360.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0.tar.gz
Algorithm Hash digest
SHA256 949eda1aeeb47b25414fe7ac5fa198a9975a09ca7d680700b0ac4200a1cf52f7
MD5 c3786a44eac68b8932ea6fb1f4c6a78b
BLAKE2b-256 a5776d5d4a33d90e6b2ea1474696ff0efade76ede51b25f94632879b9a299992

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 193.7 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 df7769fd8e3d897b1fd85f4a6b2d99b3fe598a3bc6243ece0baba1cbfac03bc9
MD5 c07f6104da3b1d12641898466a137bbc
BLAKE2b-256 7a71c4fa9e566777be74482739b74b76167e6ff2e8e3613f8b3472eb421e100c

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp314-cp314-win32.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp314-cp314-win32.whl
  • Upload date:
  • Size: 189.4 kB
  • Tags: CPython 3.14, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp314-cp314-win32.whl
Algorithm Hash digest
SHA256 c54f8d827eebef07afd45c7ac5fa5690f7d6e975b8b92bd2e7469cbc7feea2f1
MD5 5f654039600ad77b3c878c4aab4a9435
BLAKE2b-256 3316e4d70403bed59b5ea932c1bb9b205607a165e7edf7e94b28c72eb16ccbff

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9a5788357d64e458c00f34e7ea3b1669c1b5fbf7617879fb91343eee6075c89e
MD5 0284a0be2d28528623df1f58379e892f
BLAKE2b-256 7ea4ea8680273e8e72333ba33ba12ea8de9eecf3c05a6ce73aa386b64057fdb6

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 11f2dbf6f758643e1135ef91ac95442770ff997b1aab938efb22909ff97b42bc
MD5 2e95c39a427f34d85bd496d3a1f444fa
BLAKE2b-256 ce0b59bc3d589f186e846d985c74409e43ff9cc4d1f13cc9850765951e2705e9

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp314-cp314-macosx_14_0_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp314-cp314-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 9c88b635bbaaba846651a6325a084e55707b5a43708fd1d0f387fb9b18433cb5
MD5 e8b67fdd8a6eeba5b1b2eeca31fa3d4f
BLAKE2b-256 ad1a9da7b94a4689c785de27b124d2e35f4340cebdd524967e75b6921e496575

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b561298bc8140b89b34ab98e3c22cc3cfca93e71a481df9b77b2a8d707d82f83
MD5 b4766e5667dc465aae8fba694e9a6c6d
BLAKE2b-256 f056a5c34291e96fce3c1c7ae8599a13f786ccc161ef8f280eb7616560334f48

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 191.2 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 a81b1bd716c0757f64ac9c250ee5ea2c6db76771df9f8529bef49981970fb2ba
MD5 26a923741befbafa9a141e11131914f5
BLAKE2b-256 13e931c2547cb5518348eb27f64d0e3990efd74d4cc13301fad67abdfdd02fac

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp313-cp313-win32.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp313-cp313-win32.whl
  • Upload date:
  • Size: 187.1 kB
  • Tags: CPython 3.13, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp313-cp313-win32.whl
Algorithm Hash digest
SHA256 17e6c3f6b7c307e322de835fd646853898bd8e8c62139603037237545ec7f397
MD5 1bb0aff52da89167872756e58c2fc336
BLAKE2b-256 3812510db423b3be3915a7a7b39cf6dcbb4ef356348a0e5431e7d2ecd40cbb00

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9524f9aa3372b9e27abd6d7731d6ff81596bf3810ee217a6353dcf1cf31511c7
MD5 b3c66daa8588dfcfb67f9af85a2ef454
BLAKE2b-256 9777195d23e0a3498ac6d5a9ebd6d87b42ed34bc6223cacf82391d3d11efa62b

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fbbfd18841b24b1db92ef77ca726b2c43fd09d48157759c1bed603ce01c26923
MD5 2b4ccb661504b4bfa7eecda4ac3b4930
BLAKE2b-256 e03e7a94f7dff9073dcf6f64d32eb137769172cfac9011009a778d35afe3e51f

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp313-cp313-macosx_14_0_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp313-cp313-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 bf89151693cecc28249933b721bf377c46aee43ee18e45ef431da9ba33493117
MD5 afb5221bf84d412247330ea871a3bf77
BLAKE2b-256 0596c7c980be6cdb2e24954ebfd6fd75332e9d022d3079fecc7d352ebe4f8caf

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 08f2ec992f0fd0d6ab5174f1de6bc80988dc0dd4169d2b6d2daa240667eb938e
MD5 4cf9a605921f21fe054ca39014825ebe
BLAKE2b-256 ff2d80304b0c3b9d5eca41412bc7e899a27442ee602bbd51ceabb3651b757597

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 191.3 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e12b08eb0f16d2a76dee32d8081503409dfd43d3336d5c2c7494b6b062ed88f4
MD5 a45547a4f1596f5165d96afdf36a61c6
BLAKE2b-256 3c9f68005470b8a6528464ca191caf676d669e286f98956ead4872f1e022477f

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp312-cp312-win32.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp312-cp312-win32.whl
  • Upload date:
  • Size: 187.2 kB
  • Tags: CPython 3.12, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 012f3cff1b3f12404992b33492c65e38a97b492a0fc2e4af418e680b57e1850f
MD5 b4f676462738d02d6da4a7c0dfcf9719
BLAKE2b-256 e79e480a9536d43b89a6d01a7e03765ff3f31e526180af23ac662f784364d2d8

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ace5f22a77785a15b1d7937400dbfc8d9ed2949f419f13dd56df6f03ab0fa5e8
MD5 281a0f6d7106b9ace0161a30e94fa428
BLAKE2b-256 3e5971ef8b67021d8e913bf38b964ea0160dcd6f970970618afe14cc73e873fa

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 256d59b60e42f00742f45afa94aa06c2c308c99225e6109a08f1668582012b87
MD5 78d225511e9fe0c8527eaa71fa8a6e17
BLAKE2b-256 9545f75a08133a039c1938fad2a368c591a2c4b728a29ebadcb3c33b7a00023d

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp312-cp312-macosx_14_0_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp312-cp312-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 9afb084da80e5c878bf2450e414e09715f7cf96a475e4b391f71c0c225e8c52c
MD5 3c477743d099aa14024dd8157efaf72b
BLAKE2b-256 71c93b1997fa0922fd1429bd7149e47f11a23d67ac49972f4bf94f4edbb87e9c

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ad9fe0b9fa3aee24ef7b6cd03d670fbeb6cd4e6fc5301a7f985d6b47e6f61d6e
MD5 f986ad22513a10dea6f89e34dbfaae55
BLAKE2b-256 9be923375e26921344d6268dc04e157c8cde7ed45ee6c30be1c8810480cd11bd

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 191.3 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 527b28c680fb347d6b210ef002cbcf142b23bcd431395af0f265d7e4d5495acd
MD5 77f1c80361eeb4bcad81a229d019822a
BLAKE2b-256 e191b8bd65988f72a0b35303e780651e76815a7d33e7e4bc7957ba9f504abb04

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp311-cp311-win32.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp311-cp311-win32.whl
  • Upload date:
  • Size: 187.0 kB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 b84683ce01dea5d21313e20f4fe78b0f756f149a945e8f3609b1796daf4c6619
MD5 dac012460e7bcf814ee8143fdb5e273e
BLAKE2b-256 13853df1a187a70ade4fea364c438276d5babe95495a587823253467e6ac4b97

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6358789987e3c6188d41fe9edec693fbb0078dd9c7102c2069a0ae90f192037e
MD5 a0c71c1a3ea6501d5e0ecc3b1f3a2425
BLAKE2b-256 4fc2d6ef96639d85a2e95be4755458af4fe9ff0f475819f662b663b33638185d

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f4813055fe96a50cf3a4457666f5cb00694e40e8b9a955ad5b2bb3a550d465b9
MD5 679f30f2357b333eccfb05a7c7e348ab
BLAKE2b-256 9ed8986d6827956966af2e5e1c45243a660f753ab459e8e0c5c6d72574cbee22

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp311-cp311-macosx_14_0_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp311-cp311-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 30857fc33f5af7d21e47407a5aee32acac2026f92c4b55f8b33d2cccbe52fc95
MD5 4b209cf61d23fe7a96938f658810a25c
BLAKE2b-256 455acdb82e0a825b9ef834fcb196f18a1751ef5b573570c78d57800e88d3bce2

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c3aac9bb4c8a680e97e4b6bb110bb727e679994eedae3ca22203dcfb9f322e8d
MD5 8a5e4993d13417ef942945b87884e9af
BLAKE2b-256 e38a51e3374483addc0d497aad6c37c5705fe962dbb5d0757f54a6ec6663f3bf

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 191.5 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 fb7c41b5fa1dfc1b9d266e0d0b2a2048c92839204d9a38346e59406c23a33259
MD5 8ee364814eb54d622c257118c4fdd909
BLAKE2b-256 1936ab7829bfb146cce835af9b38de4d161e03520de857f8b6ce2068d090a9cf

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp310-cp310-win32.whl.

File metadata

  • Download URL: bocpy-0.11.0-cp310-cp310-win32.whl
  • Upload date:
  • Size: 186.9 kB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for bocpy-0.11.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 b19572c77293b3dafd98af51635c50b9079c25a5627aae6ee6c0ca2c8fa15e7d
MD5 39ae4bf43b45fdf959328c5d23ee4ce5
BLAKE2b-256 f97062ab8022d23982278909b13e399f6b895160d8c69334d73c2afb94989b94

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 15131f7a9329d5e9daaf0f01b2a70ba4c0c4b69a7a1fa6424e4befbfca9a3ba5
MD5 d677c49ca88387b697e50651718297e9
BLAKE2b-256 a57e71213a25a6b7b129eb92a509856500d5295cf5a742b0cf9bbd686824646d

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9a4ce061eaf7b8eee5f2def4e0e4607fc4b15c98eeea0c36932db162c5ab751b
MD5 6e43a8cca1c70c36af79cdb0008842eb
BLAKE2b-256 b1dc639e0c8fcd09ade0b10e9c1624fbfef7db27761e8dd4d3e11e03a431b8de

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp310-cp310-macosx_14_0_x86_64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp310-cp310-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 8806055eb75060a8056cdbb1ca64ecfd7558dfd3b5db17d3cc670e06e38f1e56
MD5 13d612f3011fdad5ca9fdbe2dba1c6bd
BLAKE2b-256 8ee79eb66a748ec532a65c723473099321095c6e9e2b990f55e288fb7b6bc38c

See more details on using hashes here.

File details

Details for the file bocpy-0.11.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bocpy-0.11.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 851558bb53716c9c2c1124392981183e7d26221c6f1578288c10fbcb54f2c257
MD5 c53a98c72d711efed39f65e952d2a723
BLAKE2b-256 fa18af62ba301ede75bb993bbb5f4efd917f459f8a575a6466b55c9accc7e79b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page