Skip to main content

bocpy is a Python extension that adds Behavior-oriented concurrency built on top of cross-interpreter data.

Project description

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):
        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.

Project details


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.10.0.tar.gz (340.3 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.10.0-cp314-cp314-win_amd64.whl (194.0 kB view details)

Uploaded CPython 3.14Windows x86-64

bocpy-0.10.0-cp314-cp314-win32.whl (186.0 kB view details)

Uploaded CPython 3.14Windows x86

bocpy-0.10.0-cp314-cp314-musllinux_1_2_x86_64.whl (487.4 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

bocpy-0.10.0-cp314-cp314-manylinux_2_28_x86_64.whl (493.0 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

bocpy-0.10.0-cp314-cp314-macosx_14_0_x86_64.whl (197.1 kB view details)

Uploaded CPython 3.14macOS 14.0+ x86-64

bocpy-0.10.0-cp314-cp314-macosx_11_0_arm64.whl (190.6 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

bocpy-0.10.0-cp313-cp313-win_amd64.whl (191.1 kB view details)

Uploaded CPython 3.13Windows x86-64

bocpy-0.10.0-cp313-cp313-win32.whl (183.3 kB view details)

Uploaded CPython 3.13Windows x86

bocpy-0.10.0-cp313-cp313-musllinux_1_2_x86_64.whl (486.4 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

bocpy-0.10.0-cp313-cp313-manylinux_2_28_x86_64.whl (492.4 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bocpy-0.10.0-cp313-cp313-macosx_14_0_x86_64.whl (197.0 kB view details)

Uploaded CPython 3.13macOS 14.0+ x86-64

bocpy-0.10.0-cp313-cp313-macosx_11_0_arm64.whl (190.5 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.12Windows x86-64

bocpy-0.10.0-cp312-cp312-win32.whl (183.4 kB view details)

Uploaded CPython 3.12Windows x86

bocpy-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl (488.5 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

bocpy-0.10.0-cp312-cp312-manylinux_2_28_x86_64.whl (494.5 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bocpy-0.10.0-cp312-cp312-macosx_14_0_x86_64.whl (197.4 kB view details)

Uploaded CPython 3.12macOS 14.0+ x86-64

bocpy-0.10.0-cp312-cp312-macosx_11_0_arm64.whl (190.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

bocpy-0.10.0-cp311-cp311-win_amd64.whl (191.4 kB view details)

Uploaded CPython 3.11Windows x86-64

bocpy-0.10.0-cp311-cp311-win32.whl (183.3 kB view details)

Uploaded CPython 3.11Windows x86

bocpy-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl (482.8 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

bocpy-0.10.0-cp311-cp311-manylinux_2_28_x86_64.whl (487.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

bocpy-0.10.0-cp311-cp311-macosx_14_0_x86_64.whl (197.1 kB view details)

Uploaded CPython 3.11macOS 14.0+ x86-64

bocpy-0.10.0-cp311-cp311-macosx_11_0_arm64.whl (190.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

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

Uploaded CPython 3.10Windows x86-64

bocpy-0.10.0-cp310-cp310-win32.whl (183.2 kB view details)

Uploaded CPython 3.10Windows x86

bocpy-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl (473.6 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

bocpy-0.10.0-cp310-cp310-manylinux_2_28_x86_64.whl (478.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

bocpy-0.10.0-cp310-cp310-macosx_14_0_x86_64.whl (197.4 kB view details)

Uploaded CPython 3.10macOS 14.0+ x86-64

bocpy-0.10.0-cp310-cp310-macosx_11_0_arm64.whl (191.1 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

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

File metadata

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

File hashes

Hashes for bocpy-0.10.0.tar.gz
Algorithm Hash digest
SHA256 0638fb3351790f7a0614813f7f1eed5452fa54b89b31b2d5820eb232ca2c8339
MD5 1e3a556a9fb8afcf84f5e21815c93ecf
BLAKE2b-256 31f3dcbbcb3d11fa2b3be11554e0dbf4c865ae39ba77977f6ed36ceac2b93c67

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 194.0 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.10.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 ea4fecb6ff6deed9db525e77991257a062b8bf987eb118509c10e2f943016da1
MD5 e52a67ba6bb532ce400dcde1cc4bcc1a
BLAKE2b-256 f0728db1a3243b30a1db54b3f63a1036ad96497febc95a2a135de9c6e654cba1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp314-cp314-win32.whl
  • Upload date:
  • Size: 186.0 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.10.0-cp314-cp314-win32.whl
Algorithm Hash digest
SHA256 515b104fe526508e05ea8d61a114fca75cd10f4e9fb321da232b4a4662739d93
MD5 a5fb1b0fcde1e51e433ce04a8f51175e
BLAKE2b-256 6359b9433a2203a436d0a2ca52ae079698fb308473385e3129ab9713981da2b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 eeae2ca804944e6c59d91d7e3ca52560b35583ae6e4b95f8c4d26bde40e07805
MD5 1a76632fb70c25e0ef81ca5a440e06c7
BLAKE2b-256 53b5dc89cb476a2804fd89cdb9bfd37a0a5b68d0f7f3b2ffa0da86af7ca4c221

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 509af68a907a6219f845e067100129bfe09279a8e7f87478fe6ad1e15282c705
MD5 be65cd00b0a89a1105a61cdfbac99802
BLAKE2b-256 01c2e3a154da3ba675ee59a748c2971d0abff6f6361d1ab35d852e40a0bde7c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp314-cp314-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 5ee4aaa062b943e30e44170dc945ea77e44e996df79b00f2da188fd76bc4eeeb
MD5 1056591e71d6c77cbe8576f1723fda89
BLAKE2b-256 229c15eeeb98f565028bfb6cea1a598f087390f4925d91974d4a85d73b7c4506

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 995848ab23b793a107ef2ee06058beb29af17701fa83c8aa50fd17d4ff79c5d4
MD5 34505471b359cff8cc628fda92242e69
BLAKE2b-256 237781311e42e43b1caa4a041f2c993fef3871737fde510642bafaf7ebfddd1d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 191.1 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.10.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 5587a882892a31dfdef4f1941d0fa799d61349a1f9d974c130fac88ed55d23c6
MD5 f8e7b7ff2dc8c3896370d961727920f1
BLAKE2b-256 4a2f9abe4e25b415beee808999a1c02bb761a2fa4213ce102df1e6b5685f5006

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp313-cp313-win32.whl
  • Upload date:
  • Size: 183.3 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.10.0-cp313-cp313-win32.whl
Algorithm Hash digest
SHA256 a4c057f7244fd004a12415037c551b0138470e382976d1518ed1071871a416e6
MD5 ec10381c06b13516e373770249c3f253
BLAKE2b-256 26a21360a259e2bd7c47faf509fba3ad5312158511c2a10638fc054a7157d5c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f78b74b1db9b0935e866f20c87d8ce20870dece81d39a6a13b5664f97eafa24f
MD5 7dc5a4dea43d074ac2d757b34d3a57cc
BLAKE2b-256 1acd7ce3528cb04d029b4a69a3a82a34ff843b669602ca45248a0b7d66985b7b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 89220d6187c8b8b923eba2aa4a16df9bbaf5ad1f945680477a446d97c7bf0824
MD5 9c8c1cf5897bfaac10be746608bcfce3
BLAKE2b-256 db6310fa5fa4ca7eb722e82deaa4f0b11d0973998633851f4dca5dd4ba929681

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp313-cp313-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 4f01a3a9d44709358a92f8642940bf14f0b901e7c4cb51db98b314756f1fa864
MD5 6d0a0e02a5d1971d3c385843b62fbcfe
BLAKE2b-256 17c5d99aaaf4b5d13a623e866fcf191ab05c273c3ea88d570ce551a85cb39798

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 eb1ba04e193226f16eaccab358b19e5909019c48d0aac92bc7ca6f8cd3bb5947
MD5 31948266953b4c1bef2f4038cc88a118
BLAKE2b-256 2c1206ed25e6651c118eb16df7941adac6fb255770523b0db98beffb6638b3c8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.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.10.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0bbe8098d13e2e9ba2bbf08588d3be77d8cb4eeee5f779806f387c2337fab68a
MD5 48ed00f4484ef8ac7c5346b6ffae4f2e
BLAKE2b-256 ce73fa0557ec35efd5f6146b86f32179c7153644aeb62975069602c0cb8ce892

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp312-cp312-win32.whl
  • Upload date:
  • Size: 183.4 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.10.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 5dd9d523129b444e999edb0fd2152bb1b31e44c3b5c7a5a6faf1b9a264acf5b1
MD5 f8ace2a32bef59348f30b8b36be2e5b3
BLAKE2b-256 76cd44fef3509329d183db9c6232afca4dbfd29d48dbcd508d1097c7937f4482

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e0b9f385f32553dab0edb0687f8477f5235c54aa1c7f0ece9920a0a016946bcb
MD5 f06774d3b8cdecdfa520a36487a01e77
BLAKE2b-256 c640c4545826531c983578ccecb1447b4daefa31a9f09e075444f8cfb1d56e80

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0e91f99b773248ec1b97788f0e714313eb6618049814cc133dca37cc012381cf
MD5 22c77e161e89512944a8683eda826e3a
BLAKE2b-256 cd69ca265fb03db5b499a926da8b23f23cdc735e269d6395663dece66b2faabd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp312-cp312-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 d69c61e313f7e1f31c2c8b57c24cf2c59b797227b2609689760e5232415537fc
MD5 dfc4c2bb7c45c850a3af3cdee56b3a5c
BLAKE2b-256 d31fd3ebd2b96e058faf90839c0180e062b64afeccf6dce63f42793408a5d7cb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c05c7ea800bcbfc0bf00933d3741cb4a99ae36f561a67b14f4e1b3d62c6633b4
MD5 f40e876e13ed39bfa12436acc17ccb5f
BLAKE2b-256 e072b0bb0fccb74c84742fa0f288aa95af832eecea59268ea669f4ac440e5bdc

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 191.4 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.10.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c30961b331ed68f346ea5b5edcc301d9580b7e36046509fb43c66b665aec5731
MD5 8e36422aba23bad0ec684226b1a71735
BLAKE2b-256 3b443c1b6158ffb6ee81680c629a5349aa43ab2611b18331256a7af3c3c42161

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp311-cp311-win32.whl
  • Upload date:
  • Size: 183.3 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.10.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 4f3cd0aa32007ff04487af3738728df08e4ef817f8820b6b61e026b509e10553
MD5 548d39d6200da3b30cc620dca4bc9116
BLAKE2b-256 5596e462b1259b1d68ae5b1cbf85e58621895ac54b5a2ffca40e669c23b12472

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 1aae996641233fe4fb312dba74e4084ae0c6d1eab3590af00fad204b0bd7a9cf
MD5 0f16f239165cb1b6d5e2dd7842a78c80
BLAKE2b-256 fe10a9b57bf1f2a960bf7bb9d95428e8b4e9099a0d2ae577cc06130a6844910b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e83012e8e7c37d13aec7994ce49276735cf04a299c752dfe7ab78801dff52d03
MD5 f689c1ab454b5e268eb17740cb2fdd39
BLAKE2b-256 9a678a983d00b1d4500feda833446390a071e5646470be6fa43a726e85e6a370

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp311-cp311-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 86ccca4530147656bdf42c9b2a00ab890c2bee89190d9a9b4f4bb8c931360dd9
MD5 4601ba11f707c3bd5e35db33c2da6d45
BLAKE2b-256 82d28f5e8fe769f545f367dd6e1164681fb5859fe91f9f14f45d322f12fc01c1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 670975ac3fc6e943d32270a5bb43cfa7896488bc4cbb53c830bf7ce1515c7be7
MD5 55512e8db4d6592551202e22eeec539f
BLAKE2b-256 f20308c4e740e4d839421109891a2edec2d2924459ceee022d669e1a31692091

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.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.10.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 adece979365ab32ebdd7a8c2a326b84a68a382057290dc3f697cf7977dd2e69e
MD5 a094a8c525a0755a09e51a7952b08d71
BLAKE2b-256 6d33db47bd4ab8b47f4b34609db0aaf885e55ccad271a3a4f1409841f933dd32

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.10.0-cp310-cp310-win32.whl
  • Upload date:
  • Size: 183.2 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.10.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 74037999408468cc1b5cd4e6e92acf35393d40a4aed7bbc7247ea379af4c3145
MD5 c5c168bedf9be6c04105172a10eee9b4
BLAKE2b-256 48569339fb6fd86d8c93d11516359ccf693abbe37c69393048964b55dbfb962d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cfb36035adf14474081b75bacfa5fb986adc1fa84d14b8f42f01d2e84d59c213
MD5 ee936a201e3457acef7d20a1e4838bd8
BLAKE2b-256 de33e97a23bf4ee994fc1eedd45e6320d043ccb0fb5e27916b72f849a43e116d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0f60fabf6f2d93931cb701d2b80093c481c4b230ac394b04c1e618251983bb8c
MD5 9e283a8a3ba761e8d169de74c95f75a8
BLAKE2b-256 b0415a7bb2255f9d67090b62ef678e098ee716369c9a4ca51b397271a3ed82c1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp310-cp310-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 813f41a120e9b253233ab222116a88adff6431347bfb851759671731957a7e01
MD5 fe7c64f28a545b137440f6af5d5256e4
BLAKE2b-256 251b3dbc16c8007de7bbcfe2801450a7ed16d8f7a35853af87795349ffa21edf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.10.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bb2de95480ae28f4da98264e6305ae22db12ee8c15796d2ca167e38216694036
MD5 c7b4992806f904c19a4d7a7bb0154598
BLAKE2b-256 b29a3243ef6067bb96f823a9d779e585f7e497e5010b77c213b619a2981a10f7

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 Pingdom Monitoring Sentry Error logging StatusPage Status page