Skip to main content

Frontrun

A library for deterministic concurrency testing.

pip install frontrun

Overview

Frontrun is named after the insider trading crime where someone uses insider information to make a timed trade for maximum profit. The principle is the same here, except you use insider information about event ordering for maximum concurrency bugs.

The core problem: race conditions are hard to test because they depend on timing. A test that passes 95% of the time is worse than a test that always fails, because it breeds false confidence. Frontrun replaces timing-dependent thread interleaving with deterministic scheduling, so race conditions either always happen or never happen.

Four approaches, in order of decreasing interpretability:

  1. DPOR — Systematically explores every meaningfully different interleaving. When it finds a race, it tells you exactly which shared-memory accesses conflicted and in what order. Powered by a Rust engine using vector clocks to prune redundant orderings.

  2. Bytecode exploration — Generates random opcode-level schedules and checks an invariant under each one. Often finds races very efficiently (sometimes on the first attempt), and can catch races that are invisible to DPOR (e.g. shared state inside C extensions). The trade-off: error traces show what happened but not why — you get the interleaving that broke the invariant, not a causal explanation.

  3. Marker schedule exploration — Exhaustive exploration of all interleavings at the # frontrun: marker level. Much smaller search space than bytecode exploration, with completeness guarantees.

  4. Trace markers — Comment-based synchronization points (# frontrun: marker_name) that let you force a specific execution order. Useful when you already know the race window and want to reproduce it deterministically in a test.

All four have async variants. A C-level LD_PRELOAD library intercepts libc I/O for database drivers and other opaque extensions.

DPOR deadlock detection (dining philosophers)

DPOR explores thread interleavings and detects deadlocks via wait-for-graph cycle analysis. Here it finds the circular wait in the classic 3-philosopher dining problem:

Deadlock diagram showing DPOR exploration of the dining philosophers problem. Three threads each acquire one fork (lock) then block waiting for the next, forming a cycle.

The timeline shows each thread's lock acquisitions (green), context switches (pink arrows), and the point where the deadlock is detected. Run make screenshot to regenerate this image from examples/dpor_dining_philosophers.py.

Quick Start: Bank Account Race Condition

A pytest test that uses trace markers to trigger a lost-update race:

from frontrun.common import Schedule, Step
from frontrun.trace_markers import TraceExecutor

class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def transfer(self, amount):
        current = self.balance  # frontrun: read_balance
        new_balance = current + amount
        self.balance = new_balance  # frontrun: write_balance

def test_transfer_lost_update():
    account = BankAccount(balance=100)

    # Both threads read before either writes
    schedule = Schedule([
        Step("thread1", "read_balance"),    # T1 reads 100
        Step("thread2", "read_balance"),    # T2 reads 100 (both see same value!)
        Step("thread1", "write_balance"),   # T1 writes 150
        Step("thread2", "write_balance"),   # T2 writes 150 (overwrites T1's update!)
    ])

    executor = TraceExecutor(schedule)
    executor.run({
        "thread1": lambda: account.transfer(50),
        "thread2": lambda: account.transfer(50),
    }, timeout=5.0)

    # One update was lost: balance is 150, not 200
    assert account.balance == 150

Case Studies

46 concurrency bugs found across 12 libraries by running bytecode exploration directly against unmodified library code: TPool, threadpoolctl, cachetools, PyDispatcher, pydis, pybreaker, urllib3, SQLAlchemy, amqtt, pykka, and tenacity. See detailed case studies.

Usage Approaches

1. Trace Markers

Trace markers are special comments (# frontrun: <marker-name>) that mark synchronization points in multithreaded or async code. A sys.settrace callback pauses each thread at its markers and waits for a schedule to grant the next execution turn. This gives deterministic control over execution order without modifying code semantics — markers are just comments.

A marker gates the code that follows it: the thread pauses at the marker and only executes the gated code after the scheduler says so. Name markers after the operation they gate (e.g. read_value, write_balance) rather than with temporal prefixes like before_ or after_.

from frontrun.common import Schedule, Step
from frontrun.trace_markers import TraceExecutor

class Counter:
    def __init__(self):
        self.value = 0

    def increment(self):
        temp = self.value  # frontrun: read_value
        temp += 1
        self.value = temp  # frontrun: write_value

def test_counter_lost_update():
    counter = Counter()

    schedule = Schedule([
        Step("thread1", "read_value"),
        Step("thread2", "read_value"),
        Step("thread1", "write_value"),
        Step("thread2", "write_value"),
    ])

    executor = TraceExecutor(schedule)
    executor.run({
        "thread1": counter.increment,
        "thread2": counter.increment,
    }, timeout=5.0)

    assert counter.value == 1  # One increment lost

2. DPOR (Systematic Exploration)

DPOR (Dynamic Partial Order Reduction) systematically explores every meaningfully different thread interleaving. It automatically detects shared-memory accesses at the bytecode level — attribute reads/writes, subscript accesses, lock operations — and uses vector clocks to determine which orderings are equivalent. Two interleavings that differ only in the order of independent operations (two reads of different objects, say) produce the same outcome, so DPOR runs only one representative from each equivalence class.

When a race is found, the error trace shows the exact sequence of conflicting accesses and which threads were involved:

import frontrun

class Counter:
    def __init__(self):
        self.value = 0

    def increment(self):
        temp = self.value
        self.value = temp + 1

def test_counter_is_atomic():
    result = frontrun.explore(
        setup=Counter,
        workers=Counter.increment,
        count=2,
        invariant=lambda c: c.value == 2,
    )
    result.assert_holds()

This test fails because Counter.increment is not atomic. The result.explanation shows the conflict:

Race condition found after 2 interleavings.

  Write-write conflict: threads 0 and 1 both wrote to value.

  Thread 0 | counter.py:7             temp = self.value
           | [read Counter.value]
  Thread 0 | counter.py:8             self.value = temp + 1
           | [write Counter.value]
  Thread 1 | counter.py:7             temp = self.value
           | [read Counter.value]
  Thread 1 | counter.py:8             self.value = temp + 1
           | [write Counter.value]

  Reproduced 10/10 times (100%)

DPOR explored exactly 2 interleavings out of the 6 possible (the other 4 are equivalent to one of the first two). For a detailed walkthrough of how this works, see the DPOR algorithm documentation.

Search strategies: The default DFS strategy is optimal for exhaustive exploration (stop_on_first=False) — it produces the minimum number of executions. When the trace space is very large and you have a limited execution budget (stop_on_first=True or a low max_executions), use a non-DFS strategy like search="bit-reversal" to spread exploration across diverse conflict points early, finding bugs faster on average. See search strategy documentation for details.

Scope and limitations: DPOR tracks Python bytecode-level conflicts (attribute and subscript reads/writes, lock operations) plus I/O. Redis key-level conflicts are detected by intercepting redis-py's execute_command(); activate with detect_io=True (works in both sync and async from 0.5). SQL conflicts are detected by intercepting DBAPI cursor.execute(). These key/table-level detectors are important: raw socket detection uses host:port as the resource ID, so every send and recv to the same server appears to conflict — without key-level or SQL-level refinement this causes a combinatorial explosion of spurious interleavings. C-extension shared state (NumPy arrays, etc.) is not tracked at all. The frontrun CLI adds C-level socket interception via LD_PRELOAD for opaque drivers, also at the coarse host:port level.

3. Bytecode Exploration (Random Strategy)

Bytecode exploration generates random opcode-level schedules and checks an invariant under each one, in the style of Hypothesis. Each thread fires a sys.settrace callback at every bytecode instruction, pausing to wait for its scheduler turn. No markers or annotations needed.

The random strategy often finds races very quickly — sometimes on the first attempt. It can also find races that are invisible to DPOR, because it doesn't need to understand why a schedule is bad; it just checks whether the invariant holds after the threads finish. If a C extension mutates shared state in a way that breaks your invariant, random exploration will stumble into it. DPOR won't, because it can't see the C-level mutation.

The trade-off: error traces are less interpretable. You get the specific opcode schedule that broke the invariant and a best-effort interleaved source trace, but not the causal conflict analysis that DPOR provides.

import frontrun

class Counter:
    def __init__(self, value=0):
        self.value = value

    def increment(self):
        temp = self.value
        self.value = temp + 1

def test_counter_is_atomic():
    result = frontrun.explore(
        setup=lambda: Counter(value=0),
        workers=Counter.increment,
        count=2,
        invariant=lambda c: c.value == 2,
        strategy="random",
        max_attempts=200,
        max_ops=200,
        seed=42,
    )
    result.assert_holds()

This fails with output like:

Race condition found after 1 interleavings.

  Lost update: threads 0 and 1 both read value before either wrote it back.

  Thread 1 | counter.py:7             temp = self.value
           | [read value]
  Thread 0 | counter.py:7             temp = self.value
           | [read value]
  Thread 1 | counter.py:8             self.value = temp + 1
           | [write value]
  Thread 0 | counter.py:8             self.value = temp + 1
           | [write value]

  Reproduced 10/10 times (100%)

The reproduce_on_failure parameter (default 10) controls how many times the counterexample schedule is replayed to measure reproducibility. Set to 0 to skip.

Note: Opcode-level schedules are not stable across Python versions. CPython does not guarantee bytecode compatibility between releases, so a counterexample from Python 3.12 may not reproduce on 3.13. Treat counterexample schedules as ephemeral debugging artifacts.

Automatic I/O Detection

Both the bytecode explorer and DPOR automatically detect socket and file I/O operations (enabled by default via detect_io=True). When two threads access the same network endpoint or file path, the operation is reported as a conflict so the scheduler explores their reorderings.

Python-level detection (monkey-patching):

  • Sockets: connect, send, sendall, sendto, recv, recv_into, recvfrom
  • Files: open() (read vs write determined by mode)

Resource identity is derived from the socket's peer address (host:port) or the file's resolved path — two threads hitting the same endpoint or file conflict; different endpoints are independent.

Redis Key-Level Conflict Detection

DPOR goes beyond coarse socket-level detection for Redis: it intercepts execute_command() on redis-py clients, classifies each command as a read or write on specific keys, and reports per-key resource IDs to the engine. Two threads operating on different Redis keys are independent; only operations on the same key (with at least one write) trigger interleaving exploration.

Sync DPOR — Redis patching is active automatically when detect_io=True (the default):

import frontrun
import redis

def test_redis_counter_race(redis_port):
    class State:
        def __init__(self):
            r = redis.Redis(port=redis_port, decode_responses=True)
            r.set("counter", "0")
            r.close()

    def increment(state):
        r = redis.Redis(port=redis_port, decode_responses=True)
        val = int(r.get("counter"))
        r.set("counter", str(val + 1))
        r.close()

    result = frontrun.explore(
        setup=State,
        workers=[increment, increment],
        invariant=lambda s: int(redis.Redis(port=redis_port).get("counter")) == 2,
        detect_io=True,   # default — activates Redis key-level patching
    )
    assert not result.property_holds  # DPOR finds the lost-update race

Async DPORdetect_io=True covers Redis in async too:

import frontrun
import redis.asyncio as aioredis

async def test_async_redis_race(redis_port):
    async def increment(state):
        r = aioredis.Redis(port=redis_port, decode_responses=True)
        val = int(await r.get("counter"))
        await r.set("counter", str(val + 1))
        await r.aclose()

    result = await frontrun.explore(
        setup=lambda: None,
        workers=increment,
        count=2,
        invariant=lambda s: True,  # check Redis directly in a real test
        detect_io=True,
    )

The same key-level precision applies to hashes (HGET/HSET), lists, sets, sorted sets, and all other Redis data structures — 160+ commands are classified. See the Redis technical details for a full walkthrough.

C-Level I/O Interception

When run under the frontrun CLI, a native LD_PRELOAD library (libfrontrun_io.so) intercepts libc I/O functions directly. This covers opaque C extensions — database drivers (libpq, mysqlclient), Redis clients, HTTP libraries, and anything else that calls libc's send(), recv(), read(), write(), etc.

Intercepted functions: connect, send, sendto, sendmsg, write, writev, recv, recvfrom, recvmsg, read, readv, close

The library maintains a process-global file-descriptor → resource map:

connect(fd, sockaddr{127.0.0.1:5432}, ...)  →  record fd=7 → "socket:127.0.0.1:5432"
send(fd=7, ...)                              →  report write to "socket:127.0.0.1:5432"
recv(fd=7, ...)                              →  report read from "socket:127.0.0.1:5432"
close(fd=7)                                  →  remove fd=7 from map

Events are transmitted to the Python side via one of two channels:

  • Pipe (preferred): IOEventDispatcher creates an os.pipe() and sets FRONTRUN_IO_FD to the write-end fd. The Rust library writes directly to the pipe (no open/close overhead per event), and a Python reader thread dispatches events to registered listener callbacks in arrival order. The pipe's FIFO ordering provides a natural total order without timestamps.
  • Log file (legacy): FRONTRUN_IO_LOG points to a temp file. Events are appended per-call (open + write + close each time) and read back in batch after execution.
from frontrun._preload_io import IOEventDispatcher

with IOEventDispatcher() as dispatcher:
    dispatcher.add_listener(lambda ev: print(f"{ev.kind} {ev.resource_id}"))
    # ... run code under LD_PRELOAD / DYLD_INSERT_LIBRARIES ...
# all events are also available as dispatcher.events

Trace Filtering (trace_packages)

By default, frontrun only traces user code — files outside the stdlib, site-packages, and frontrun's own internals. When the code under test lives inside an installed package (Django apps, plugin architectures, etc.), pass trace_packages to widen the filter:

import frontrun

result = frontrun.explore(
    setup=make_state,
    workers=[thread_a, thread_b],
    invariant=check_invariant,
    trace_packages=["mylib.*", "django_filters.*"],
)

Patterns use fnmatch syntax and are matched against dotted module names (e.g. django_filters.views). All exploration entry points (explore, explore_random, and their async variants) accept this parameter. See trace filtering docs for details.

Async Support

Trace markers, random interleaving exploration, and DPOR all have async support.

Async Trace Markers

from frontrun import TraceExecutor
from frontrun.common import Schedule, Step

class AsyncCounter:
    def __init__(self):
        self.value = 0

    async def get_value(self):
        return self.value

    async def set_value(self, new_value):
        self.value = new_value

    async def increment(self):
        # frontrun: read_value
        temp = await self.get_value()
        # frontrun: write_value
        await self.set_value(temp + 1)

def test_async_counter_lost_update():
    counter = AsyncCounter()

    schedule = Schedule([
        Step("task1", "read_value"),
        Step("task2", "read_value"),
        Step("task1", "write_value"),
        Step("task2", "write_value"),
    ])

    executor = TraceExecutor(schedule)
    executor.run({
        "task1": counter.increment,
        "task2": counter.increment,
    })

    assert counter.value == 1  # One increment lost

Async Exploration

Async exploration works at natural await boundaries instead of opcodes, making schedules stable across Python versions. frontrun.explore() detects async workers automatically:

import asyncio
import frontrun

class Counter:
    def __init__(self):
        self.value = 0

    async def increment(self):
        temp = self.value
        await asyncio.sleep(0)  # any natural await is a scheduling point
        self.value = temp + 1

# DPOR (default) — systematic
async def test_async_counter_dpor():
    result = await frontrun.explore(
        setup=Counter,
        workers=Counter.increment,
        count=2,
        invariant=lambda c: c.value == 2,
    )
    result.assert_holds()

# Random strategy — fast, probabilistic
async def test_async_counter_random():
    result = await frontrun.explore(
        setup=Counter,
        workers=Counter.increment,
        count=2,
        invariant=lambda c: c.value == 2,
        strategy="random",
        max_attempts=200,
    )
    result.assert_holds()

CLI

The frontrun CLI wraps any command with the I/O interception environment:

# Run pytest with frontrun I/O interception
frontrun pytest -vv tests/

# Run any Python program
frontrun python examples/orm_race.py

# Run a web server
frontrun uvicorn myapp:app

The CLI:

  1. Sets FRONTRUN_ACTIVE=1 so frontrun knows it's running under the CLI
  2. Sets LD_PRELOAD (Linux) or DYLD_INSERT_LIBRARIES (macOS) to load libfrontrun_io.so/.dylib
  3. Runs the command as a subprocess

Pytest Plugin

Frontrun ships a pytest plugin (registered via the pytest11 entry point) that patches threading.Lock, threading.RLock, queue.Queue, and related primitives with cooperative versions before test collection.

Patching is on by default when running under the frontrun CLI. When running plain pytest without the CLI, patching is off unless explicitly requested:

frontrun pytest                    # cooperative lock patching is active (auto)
pytest --frontrun-patch-locks      # explicitly enable without CLI
pytest --no-frontrun-patch-locks   # explicitly disable even under CLI

Tests that use frontrun.explore() or frontrun.explore_random() will be automatically skipped when run without the frontrun CLI, preventing confusing failures when the environment isn't properly set up.

Platform Compatibility

Feature Linux macOS Windows
Trace markers (sync + async) Yes Yes Yes
Bytecode exploration (sync + async) Yes Yes Yes
DPOR (Rust engine) Yes Yes Yes
frontrun CLI + C-level I/O interception Yes Yes No

Linux is the primary development platform and has full support for all features including the LD_PRELOAD I/O interception library.

macOS supports all features. The frontrun CLI uses DYLD_INSERT_LIBRARIES to load libfrontrun_io.dylib. Note that macOS System Integrity Protection (SIP) strips DYLD_INSERT_LIBRARIES from Apple-signed system binaries (/usr/bin/python3, etc.). Use a Homebrew, pyenv, or venv Python to avoid this limitation.

Windows support is limited to trace markers, bytecode exploration, and DPOR — the pure-Python and Rust PyO3 components that don't rely on LD_PRELOAD. The frontrun CLI and C-level I/O interception library are not available on Windows because they depend on the Unix dynamic linker's symbol interposition mechanism, which has no direct Windows equivalent.

Development

Prefer assert_holds() over manual asserts

InterleavingResult exposes a convenience helper that raises AssertionError with the race explanation on failure and returns None silently on success:

result = frontrun.explore(setup=setup, workers=[thread1, thread2], invariant=invariant)
result.assert_holds()  # preferred over: assert result.property_holds, result.explanation

An optional msg_prefix is prepended to the explanation:

result.assert_holds(msg_prefix="transfer race: ")

Running Tests

# Build everything and run tests
make test-3.10

# Or via the frontrun CLI
make build-dpor-3.10 build-io
frontrun .venv-3.10/bin/pytest -v

Download files

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

Source Distribution

frontrun-0.6.0.tar.gz (282.0 kB view details)

Uploaded Source

Built Distributions

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

frontrun-0.6.0-cp314-cp314t-manylinux_2_39_x86_64.whl (787.4 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.39+ x86-64

frontrun-0.6.0-cp314-cp314t-manylinux_2_39_aarch64.whl (781.6 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.39+ ARM64

frontrun-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl (716.6 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

frontrun-0.6.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (787.7 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

frontrun-0.6.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (783.8 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

frontrun-0.6.0-cp314-cp314-macosx_11_0_arm64.whl (716.9 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

frontrun-0.6.0-cp313-cp313t-manylinux_2_39_x86_64.whl (787.5 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.39+ x86-64

frontrun-0.6.0-cp313-cp313t-manylinux_2_39_aarch64.whl (781.7 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.39+ ARM64

frontrun-0.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (787.4 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

frontrun-0.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (783.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

frontrun-0.6.0-cp313-cp313-macosx_11_0_arm64.whl (716.5 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

frontrun-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (787.5 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

frontrun-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (783.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

frontrun-0.6.0-cp312-cp312-macosx_11_0_arm64.whl (716.1 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

frontrun-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (787.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

frontrun-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (783.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

frontrun-0.6.0-cp311-cp311-macosx_11_0_arm64.whl (720.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

frontrun-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (788.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

frontrun-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (783.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

frontrun-0.6.0-cp310-cp310-macosx_11_0_arm64.whl (719.6 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file frontrun-0.6.0.tar.gz.

File metadata

  • Download URL: frontrun-0.6.0.tar.gz
  • Upload date:
  • Size: 282.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for frontrun-0.6.0.tar.gz
Algorithm Hash digest
SHA256 13df4f2a72f9a987b37ad65b7814f4e1b74b6151b9e70cbe360ffce5722bde41
MD5 9017f87bc94c404bdccacc7c47824910
BLAKE2b-256 2647a37d104a33beed630eee2681d8f9f03127f392533e3296ee00546b70a2ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0.tar.gz:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp314-cp314t-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp314-cp314t-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 41fcb6dcf58c3cc43134a6cbae31db836f552c52df1924f665bc451cf802aec2
MD5 733225cbaf0c61b3b499350ed87034ef
BLAKE2b-256 3de0aadbc3b30817c7c7937cd689d117468d336e34c6c0229a6d9d84fc5e37a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp314-cp314t-manylinux_2_39_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp314-cp314t-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp314-cp314t-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 04f3679cf96d415efb9d0a05263451f386763ed41ce18b01e9cfeb9cac83d9ea
MD5 36feb5e6b071c23bf5457dfaf1f0b750
BLAKE2b-256 aa91a3d5cf91df9cf4fe8a06aeb121d288ecb7b3b0513a95a3a9abc167e0192a

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp314-cp314t-manylinux_2_39_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b7a7d168ecd9658dd93884f26443e9521fbb7ee8807d0fa8dd386f5d00e704cf
MD5 737a95b11418594a1f0f4899639ff768
BLAKE2b-256 9bfe1f07d16c1387df1af6ab0ddf66e0e26559ce9c7050680ad2580fd82d7834

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9b58ad34921f03d8b2872a984b0b743c718b8ab334f2cf66ec3f1fec2ff8ce1a
MD5 e465c7aeebf7e69cfc99f988ae0a4c25
BLAKE2b-256 2d50402bea155f0fa49dcfa7cbc1bd798ca4d640d0bb7145c200ca0323ed991d

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 545badc97c5223a357f7456f9f919a3b12cb4740cab9a32d831c6fc93df74f1b
MD5 02b81a23c2b12fae548fa2355e7487d4
BLAKE2b-256 c5d8db6c0a17cbc51307deabdda42898876cb8fc2c343e6685a0b9a4ac9dfebe

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b73b407eebe7d951936a8e7095efbff5cc11e7828bd60c70877c8d23d2ad05fb
MD5 f25980f4f0176cd119269c0c3e8d19ee
BLAKE2b-256 b3a8a7044cbe5db233a51c54bb04adbbbcf4b2c04c69442c728514700664abd9

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp313-cp313t-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp313-cp313t-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 18002f784de66f2657a2905f239a14de92474dc722cb10ea8111622a1e1e79f5
MD5 73f6c0cf3c87c077ba9ffd11f5a9c6de
BLAKE2b-256 85bada9443e6c371cb5bea3c95e7a2f7aa9157321892fdd7cec5355d749385cf

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp313-cp313t-manylinux_2_39_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp313-cp313t-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp313-cp313t-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 f31201fe2f86448046e2023e8233080d7bf28653de43895aa5bc74160bbaf31f
MD5 2d571a2100342d63e28c3ee9407f3498
BLAKE2b-256 57e54481e7a154f362d68300ae6719d6639613de32c00c8ab3769897f8d1cf22

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp313-cp313t-manylinux_2_39_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a22ec2cf7bb87c9c965279b30efa06ab3d4f261d34c4eb9e3911715dcf586f52
MD5 9ec16a272be8c97a88e600b16f58dd04
BLAKE2b-256 365fdcc81f8546149ac0b6d952a3d318d80ed38c264d09c6ef6069d1ee1dba38

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 56854f52f5a742ad875a3950c815b29f5320b5a24e67694217b60d18a11e2200
MD5 1d20c752c5960de7e43ed8a0a56668f5
BLAKE2b-256 99967c7beed087a275cf7c3bda67a0ea42a549d178dafb03a1a0ef4b7046450b

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6399091c457125ee665372c7723120f3cc1a497eeb7b830e840b1111e2f42ab7
MD5 ea7ea2fbb6a58dec3fd0ea9985a1c81e
BLAKE2b-256 0dfaa2c517dfe8a4d058324f2ab54197b21a0bf8130ab232d4fbbd9ecd8609b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4b4bbd58c5e5b53b9fabe3ac946994cb8dfb00b1826c36f5fed10e8f0a2f5a82
MD5 3afb96cfd124b699c177fe3444f49bce
BLAKE2b-256 10f189a1028820d2b2683fcffca5727e5a442695ff0bd53209e6c15b3a5bbbb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6741a67cc3fc12765872f849e289ab2757d39ede2fbc3bbc8ddec9edf3700011
MD5 8976679ce342b5adc62c44cae2759022
BLAKE2b-256 9b5ff08a8814856abf122db79b1b74a7187527c1d52661f89506ca567587dfc4

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 485a33cfa4008204b300ecd4c7dcfb7ecedc5256e7202a4b6e84b8ce47cd1ef1
MD5 f890d6bc221d99bab00a3b52b59331b1
BLAKE2b-256 25bead8925bd6044cb6ed631aa263d9591b0e3b012dc3c0a6ea4c654e058ac06

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 dfb53d13194497a5af98bc68b33e625aab89cc192090ad3caf147ffd3c01e973
MD5 36e0d21d40d73d785db48a6871ecb757
BLAKE2b-256 a837071adf8779c792d4b75bdfd9eb4df7d9220f20af1731616cd3ccd25beea3

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 814f5e81006e9ed65411dd49f3611d0dd1b6720894df389545d0cf2edaf94386
MD5 48012a9df9319b781907e17ffff236bc
BLAKE2b-256 dfcb9a657dfe1ae83b0967ebdedea5048f5e9dd5f060dfe787426ced8e3ad011

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 82ab957cfc28e651b6c0721a37f1eca8b3b6ef84d2dd90e46120bb4b5ef62a50
MD5 1f3ea32907118d17b2011096507d4a70
BLAKE2b-256 eafb54e77cc1c88b537d90d72bc9d4fdebf7700351a97c89c8d1d6aa4805ba6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 61cca42f20baf24748cd34ede9c123ff57719f6edcead431a4e21dfababce564
MD5 593a237b930fd01c326951db15312c2b
BLAKE2b-256 4f4c814c10036790fec9ae52ec6090c347d0404be90ae0f174e115a15c6aba50

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3a7b544497856aa174e65f0350e326ab8ed8cf3d9f6e25f5ce512e3c949fecf2
MD5 45c442de1c6d3f7054d0e7ec06d19121
BLAKE2b-256 7b7392d528d4b0225519f6a711626684a022424642e4223101c2d5e1d2b00e2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file frontrun-0.6.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for frontrun-0.6.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d4167ad68f7e041ab1f877ef8676b171227962a38e47aceeb421f929bc6752bb
MD5 c5c928800599c053e6895595d8b18ac4
BLAKE2b-256 ee9d726fca34133e0baf27cffa4b06174ecc52c26f49258cce103471e85649e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for frontrun-0.6.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: publish.yml on lucaswiman/frontrun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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