pytest-shape CLI
rpytest mirrors pytest flags and selectors — -k, -m, --lf, -x, --maxfail, --collect-only, and node-ID selectors — so your existing invocations run unchanged.
Home / Features
rpytest keeps the pytest surface unchanged and adds exactly the machinery that removes per-invocation overhead — a warm daemon, built-in parallelism, and a verifier to prove it all still behaves like pytest. Here is the whole feature set, grouped by what it is for.
rpytest is pytest where pytest already works. Same surface, nothing to migrate.
rpytest mirrors pytest flags and selectors — -k, -m, --lf, -x, --maxfail, --collect-only, and node-ID selectors — so your existing invocations run unchanged.
pytest.ini, pyproject.toml ([tool.pytest.ini_options]), tox.ini, and setup.cfg are all read where they live. There is no rpytest config to migrate to.
Exit codes and JUnit XML match pytest exactly, so CI gates and report parsers keep working. Console stdout is similar but not byte-identical.
Interpreter startup, plugin import, and collection move from per-invocation to per-session cost.
The first invocation spawns a background Python process that imports your suite once and caches the collected node IDs; later invocations are small RPCs into a warm interpreter.
The daemon hosts a real pytest process. Your fixtures, conftest.py, parametrization, and hooks run in genuine pytest — they are not re-implemented.
The CLI is a small Rust binary (crates rpytest, rpytest-core, rpytest-ipc) that parses flags, applies selectors, and dispatches over IPC without paying Python overhead.
Built-in parallelism, sharding, and flakiness controls — no extra plugins.
rpytest -n N and -n auto run tests across workers with duration-aware load balancing. No pytest-xdist install required; the flag surface matches.
--shard 0 --total-shards 4 splits a suite deterministically across CI jobs, so shards are stable and reproducible.
--reruns N retries failing tests and --flaky-report surfaces quietly unreliable tests, without adding a rerun plugin.
The inner TDD loop, tightened around a warm daemon.
rpytest --watch re-runs the affected tests on each file change against the warm daemon, so a save triggers execution rather than a fresh collection.
--lf and keyword/marker selectors filter against the cached inventory, so re-running just what broke is near-instant.
The daemon is a local process with no remote control plane. Manage it with --daemon-status, --daemon-stop, and --cleanup.
Prove the swap is safe before you rely on it.
rpytest --verify-dropin runs both pytest and rpytest and diffs collected node IDs, per-test outcomes, and exit codes — reporting exactly which tests disagree and whether at collection or execution time.
The published BENCHMARK.md numbers come from one machine and a synthetic 500-test suite, presented as-is and not extrapolated. Measure your own suite with the verifier.
rpytest is built by Neul Labs, MIT-licensed, with source on GitHub. A memory-safe Rust CLI over a real pytest core.
Install rpytest, run your suite, and prove parity with --verify-dropin.