#!/usr/bin/env python3 """Run the upstream pyperformance benchmark suite (https://github.com/python/pyperformance) against a Python executable -- RustPython, a real CPython, or both -- and catalog which benchmarks pass, fail, or time out under each. Background ---------- pyperformance cannot be installed as-is on RustPython: its runtime dependency `pyperf` hard-depends on `psutil`, a C-extension package. RustPython has no CPython C-API / extension-module loading support (no `_imp.create_dynamic` / `_imp.exec_dynamic`, no compiler config vars such as LDCXXSHARED in `_sysconfigdata`), so building or loading any C extension fails. Workaround: `pyperf` itself already disables psutil usage on interpreters that report `Py_GIL_DISABLED=1` (see `pyperf._utils.USE_PSUTIL`), which is exactly what RustPython reports (it has no GIL). So a functionality-free, pure-Python "psutil" stub (see stub_psutil/) is enough to satisfy pip's dependency resolution -- pyperf never actually calls into it at runtime on RustPython. This unblocks any *pure-Python* pyperformance benchmark; any benchmark whose own workload (not just pyperf) requires a real C extension (e.g. lxml, numpy, greenlet) will still fail, and that failure is a genuine finding: it marks a real C-extension gap in RustPython, not a tooling artifact of this script. A real CPython target doesn't need this workaround at all -- pass --no-psutil-stub for it, so it installs and uses the genuine psutil. This script: 1. Ensures a *host* CPython venv with pyperformance installed (pyperformance itself only runs under a real CPython; the --python target is just the interpreter it benchmarks, which may be that same CPython or RustPython). 2. Builds the pure-Python psutil stub wheel once (skipped with --no-psutil-stub). 3. Runs every benchmark pyperformance knows about, one at a time, against the given --python target, with a timeout per benchmark. 4. Writes a JSON + Markdown catalog of the results under results/