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.

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 to do distributed computation over cores. 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.

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

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.8.0.tar.gz (355.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.8.0-cp314-cp314-win_amd64.whl (180.7 kB view details)

Uploaded CPython 3.14Windows x86-64

bocpy-0.8.0-cp314-cp314-win32.whl (173.7 kB view details)

Uploaded CPython 3.14Windows x86

bocpy-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl (443.2 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

bocpy-0.8.0-cp314-cp314-manylinux_2_28_x86_64.whl (448.8 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

bocpy-0.8.0-cp314-cp314-macosx_14_0_x86_64.whl (183.7 kB view details)

Uploaded CPython 3.14macOS 14.0+ x86-64

bocpy-0.8.0-cp314-cp314-macosx_11_0_arm64.whl (177.4 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

bocpy-0.8.0-cp313-cp313-win_amd64.whl (178.0 kB view details)

Uploaded CPython 3.13Windows x86-64

bocpy-0.8.0-cp313-cp313-win32.whl (171.4 kB view details)

Uploaded CPython 3.13Windows x86

bocpy-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl (442.6 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

bocpy-0.8.0-cp313-cp313-manylinux_2_28_x86_64.whl (448.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bocpy-0.8.0-cp313-cp313-macosx_14_0_x86_64.whl (183.7 kB view details)

Uploaded CPython 3.13macOS 14.0+ x86-64

bocpy-0.8.0-cp313-cp313-macosx_11_0_arm64.whl (177.4 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

bocpy-0.8.0-cp312-cp312-win_amd64.whl (178.1 kB view details)

Uploaded CPython 3.12Windows x86-64

bocpy-0.8.0-cp312-cp312-win32.whl (171.5 kB view details)

Uploaded CPython 3.12Windows x86

bocpy-0.8.0-cp312-cp312-musllinux_1_2_x86_64.whl (444.7 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

bocpy-0.8.0-cp312-cp312-manylinux_2_28_x86_64.whl (450.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bocpy-0.8.0-cp312-cp312-macosx_14_0_x86_64.whl (183.9 kB view details)

Uploaded CPython 3.12macOS 14.0+ x86-64

bocpy-0.8.0-cp312-cp312-macosx_11_0_arm64.whl (177.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

bocpy-0.8.0-cp311-cp311-win_amd64.whl (178.4 kB view details)

Uploaded CPython 3.11Windows x86-64

bocpy-0.8.0-cp311-cp311-win32.whl (171.4 kB view details)

Uploaded CPython 3.11Windows x86

bocpy-0.8.0-cp311-cp311-musllinux_1_2_x86_64.whl (439.5 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

bocpy-0.8.0-cp311-cp311-manylinux_2_28_x86_64.whl (444.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

bocpy-0.8.0-cp311-cp311-macosx_14_0_x86_64.whl (183.6 kB view details)

Uploaded CPython 3.11macOS 14.0+ x86-64

bocpy-0.8.0-cp311-cp311-macosx_11_0_arm64.whl (177.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

bocpy-0.8.0-cp310-cp310-win_amd64.whl (178.5 kB view details)

Uploaded CPython 3.10Windows x86-64

bocpy-0.8.0-cp310-cp310-win32.whl (171.4 kB view details)

Uploaded CPython 3.10Windows x86

bocpy-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl (431.9 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

bocpy-0.8.0-cp310-cp310-manylinux_2_28_x86_64.whl (436.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

bocpy-0.8.0-cp310-cp310-macosx_14_0_x86_64.whl (183.8 kB view details)

Uploaded CPython 3.10macOS 14.0+ x86-64

bocpy-0.8.0-cp310-cp310-macosx_11_0_arm64.whl (177.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: bocpy-0.8.0.tar.gz
  • Upload date:
  • Size: 355.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.8.0.tar.gz
Algorithm Hash digest
SHA256 f5c722a076f0900aaa31b0a9dd4be69b77dd8070ac8b59d327a88e772bbe3721
MD5 52c6d1984a5f842a991260fadf9f217f
BLAKE2b-256 54bff9de0af7bf49410bea23ba55428c4a2aee68d113b9dbe8c9abe14355e493

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 180.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.8.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 a2b24136b8a42382bbd37a5c5fa8ae22416426a5e4cfff77a1f6b5e4fb11b276
MD5 d03fa20518f56b30635bed5a0561a200
BLAKE2b-256 85c22eb8106540b3b72fa7901d4f3faca9e60cfc50b9e31826258557da4b77b7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp314-cp314-win32.whl
  • Upload date:
  • Size: 173.7 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.8.0-cp314-cp314-win32.whl
Algorithm Hash digest
SHA256 01d03e657f9fe3974b980c899e52c7c29913cc8c34a468a0d0f4904afae9046f
MD5 297552864a6584861adcf661dd778758
BLAKE2b-256 eac5098154ffef1c56e51a756efb45ee34ca4ec0bbae9d6694bb761a2b1dafa1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0d3a2d31cd81ae970d7244b4def4425f8f70eb002ee1fdb0aa9a8dab7e4ebaa4
MD5 98f05bebb7c43a820af9ae1f656f9582
BLAKE2b-256 fab0140772c815098d735843a039df75f7c779bc394fa25ef6b7f8261e1dac5b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 dd16a70cbcf993d766c5f6dc51e8928c9ce7ac1adf1bb550f2fd9908bb099413
MD5 1779c715804fbf5b09fb514ecf421147
BLAKE2b-256 bd06a72f4a07235bb890ef3a91f861230920afca32f5228070746dd3248679be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp314-cp314-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 fa70854d2fc896430485fa923a7cbaaf2e486a843ce2d2e86e426110493ac549
MD5 f52bb48b875c8ad22746bc906d1c5082
BLAKE2b-256 9cdcf01812a14b4928242c64a58daa72b84e98d37dcbc3406caf0f1fe77558ea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6ce0fd68a7933e870d2b2d6d625e0b119be48947d4ce1c9d118440d5bdc00895
MD5 5014cacd96713dbbd55223a89410f638
BLAKE2b-256 681d248f3508cff312133d4c634e02db1cc634edc6cfe28af52887f21facfc49

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 178.0 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.8.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 56362a4e6ad90866c1eee35c211c98552dd9f0c6d4c10ded90d8d980efc6e697
MD5 726ac978d62c5e7ae4c91147bca5d7d3
BLAKE2b-256 4b3acc5db3208c856e45f3cca3356e614513b445528af667a64fdc683616b995

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp313-cp313-win32.whl
  • Upload date:
  • Size: 171.4 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.8.0-cp313-cp313-win32.whl
Algorithm Hash digest
SHA256 01fee5f138c74bac0f85924367d8876c6d52ceb46b63a0bd666af1ea817fdf36
MD5 360d2fb277896f6a8c7e424d02ce5162
BLAKE2b-256 4983c580b8156beca61c38be69b92f040e6cd87cc98d403cfe955b654f8e18fa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 54a43b317e418112977da7bac6ce1b7b22c53434d22fed64907b17bf4aea67d0
MD5 3399c3bd544edefae35757e22e5fa609
BLAKE2b-256 80f66537fbcd814dbeaf8a20fd79726aeb6937748a8e365572dd0afa25007200

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ebc52d2990c392bff6c31c3f3c5227006bcd2703739b1047a2b85d824bc1b3b1
MD5 cb42055a731d1ac01d894a3cb9482959
BLAKE2b-256 817f2521fd5ba799c7b41de0e73153fd50961c500dd7694e4057b3a311ed3f8b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp313-cp313-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 74d500976c40f4f4e22d69261740f9f89f090eee6edb50623d7362e162f378fa
MD5 d77475aec6b1ab3a234ec2c7b98bc0e7
BLAKE2b-256 af5d8fbccf52b20f27d30f49a82501aa7836a5ecf66fc60cbea787627a7621aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b6a7c7e7f5521cb9cf5fd70196a21727016fcaca8e90c6fa2da646f4e19ad672
MD5 12fd57abb091ff3f121616d501bb9b65
BLAKE2b-256 30e24e1343fe96c218dbccbacdf1f3dcc6feabb17843252c8236ec5c43c19d3f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 178.1 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.8.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 a8b9508457464ce503dc321d8fd106c84eee01075c3be27423ff4a68a3486a6b
MD5 cc276ecfac7707bc32345c7beba78046
BLAKE2b-256 6cc2d0f6293697e8954da40d45016739476d1f82c982ccca230a2a2b6f8334f8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp312-cp312-win32.whl
  • Upload date:
  • Size: 171.5 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.8.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 4d72d104f9ca2a089f7286039b5666f5de47fbe800bda893a5775e6cc6ea315f
MD5 e34aaf405e3d794cb766e21dd5094582
BLAKE2b-256 32c54c51e8855d1c5de1ea47fc454a2c0bc596dbc550317afe27ec42bb7d79cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 550089f8fb735882397d0d0ae0f9eda408a28ce853a9eb7c85cf919c04f472ec
MD5 3425f7fbd42fced297887e1c0ee8ccd6
BLAKE2b-256 ffd1d55617a5d359067fc0aa7977ad0fc848f8b26de30309da352301a13cdb07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 35710a305d7616a17d87c3aedef23418bf5fcab6c79f618be60de04898cf3d1c
MD5 d59c71bcf9597de2bbbcb8ab1dffb033
BLAKE2b-256 71346f5f218e375a75e7d3db2b219689bcd338d45b579a6343e07a83725a7467

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp312-cp312-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 dfbaaf1faf3be06343957656ce2330bcc468d25c556bca041b8517c31608ba23
MD5 38d06ad51b6fa7b07992c6ef7a8a26ca
BLAKE2b-256 65b24f1177dcfbd05bead359cff5bcb1703dbd3bf4f5855ffc85f32b2ff3f3fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 030baf6372b82880a7326096c876bcc3edd2e7e1ec78bd358c253017daaebc7c
MD5 f891ed5651dd15ef6f03a2f3bfd055d6
BLAKE2b-256 52e0f0bf863c471ad9e8ef824f68a5e657a3284495bd3a3169772a9c995ac5ea

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 178.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.8.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 adf00f5d9973ef28b6209623674f0d94a4d87c91ff20692e455888890387773b
MD5 1d8adf655a4f965a57a25ead68fbdd7f
BLAKE2b-256 fcec463018675e3d7e056e27d118239340019f859824513a6935082e00311154

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp311-cp311-win32.whl
  • Upload date:
  • Size: 171.4 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.8.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 41381e740dd5bb88d51264a31a4317c71b4d571a1b6f6fbbc179bab0a0a6c525
MD5 2161e7f329a54dabd9be5fd7bf5ad20f
BLAKE2b-256 e7a0f795d272766afd6f5cc1748786842a5533728b73f0da6f21bbd007266936

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 95bd8d535634b30040099e41926d6ce56d4eb03e0b57dbfd239dc35e1fc81483
MD5 bc74dcf4f76aa5310e7a010baf17d4cd
BLAKE2b-256 9cf664aaa8261a972411ee4c5c16d9e69578582f389ebafa3a2246fdd57d6a92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e06958c9358d8c55cedc4a6984d636e578302c26ecf34ad3aa864e1cca66c41c
MD5 dcfbbd725ca88aea1f6b6e5f9365f202
BLAKE2b-256 e424aecca319aa26f8600ff5602f980a87ee5f3c8f0ad9ecc8cc6581d6a1ba98

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp311-cp311-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 e9a239c4c0e3ab59ad59b1ba69e781e0206d8d7bcd656cefebceea309bc2641f
MD5 ad49da72ae7ad1da2f444adf2ae0fb18
BLAKE2b-256 e7b85088d67fa30b4013710d38b523d0345619a0828cdcb6944035404294a774

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2d59bf4327109133a04965ad7989821a237ea88eeb0389c18a9d727ad6fb1a98
MD5 d856a30cd75596077548f3b5928bc488
BLAKE2b-256 6e1b4fb7052f0a974da3972af1aeae50b1eeb34aeb9d9395af10ce75844800c4

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 178.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.8.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 809df4abac6ea48721353094865814363e4301fcefdcc6ea1632bc756a6e27d0
MD5 6df851af32b2e1edfb8e30030012f36c
BLAKE2b-256 7a3cbd226daeefe3aa1c0e9c622317d52f85432f8be738cffa9bbbfc910c0d86

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bocpy-0.8.0-cp310-cp310-win32.whl
  • Upload date:
  • Size: 171.4 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.8.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 77de41d8aadb7a31c6b4012283a97df94f52b37aaf3e01ab5a302191d93be22b
MD5 787c3758ad15fe08ea0570a8a3841672
BLAKE2b-256 d32cb67fb408fe4a6bce29c4f165db946326a5f6d03b1e33f0a7bd2a0029ef6a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2c5a2f86751bc41e1dd138054b86a1b29bb4baf75829bf157bab6a123622ca31
MD5 95f53c5424d0cf2bacbb1c34511a68bb
BLAKE2b-256 7597e73f47662d7d3b9c1c2725c54103a1941e24c975238f0852ba0ad41b6adb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a770dce4da755d9ae07e925559252d0d1dd267e4ea6646c17dfe568050ada17d
MD5 b04255d25cb6431fcd7dd6a18e470022
BLAKE2b-256 57de86e48570252f3eb44ed9cbc8e953a4c19cb392339b0f7284a65861e59103

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp310-cp310-macosx_14_0_x86_64.whl
Algorithm Hash digest
SHA256 ffddc8b0ac08ea5a0d975ac164225b084c1bb8e45624cba646db47293e7a2b39
MD5 0eb88858c9aeaac6e8928a83b4dd4a5f
BLAKE2b-256 81e5b22b1e948bc7b47b3bdfa33e7ef67e439eb0dfb08e965643625092b9f6d8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bocpy-0.8.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d56cf244fd44187dddb2661119023d35f02ccec110b7d34de2473cc892a811de
MD5 387a075f9c97d37b05a8bb1b27ec840a
BLAKE2b-256 cba768fb0e9704447d886458034a60cf8cc45603178fd30ab0409470bfa75ef6

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