Identify which measured CPython releases could be behind a restricted evaluator. This helps defenders test whether an evaluator leaks enough behavior or binary-layout detail to reveal its runtime.
It runs harmless behavior checks, compares their fingerprint with real container measurements, and returns every matching release.
This is by no means a comprehensive reference; contributions that increase coverage are welcome.
pip install .circaetus generate > probe.j2
circaetus analyze 'SD1[A:0B:0C:1]'Run the generated payload in the evaluator, then analyze its SD1[...] output. Targets are jinja (default), asteval, reportlab, and python. Use -o FILE to write a payload to a file; omit the fingerprint to read it from stdin.
One release means the available checks separate that release in the measured matrix. A release range means the evaluator hides the differences needed to narrow it further.
Build: unknown means the binary layout did not exactly match a measured image.
Coverage is a set of real container measurements. OS, architecture, libc, image family, and CPython patch can all affect a layout.
The shipped matrix contains 169 measurements across 37 CPython releases:
| Image family | Base | Architectures | Rows |
|---|---|---|---|
| Docker Official Python, Alpine | Alpine | amd64, arm64, 386, ARMv7, ppc64le, riscv64, s390x | 65 |
| Docker Official Python, slim | Debian | amd64, arm64, 386, ARMv7, ppc64le, riscv64, s390x | 60 |
| Canonical Ubuntu Python | Ubuntu 22.04–26.04 | amd64, arm64, ppc64le, s390x | 16 |
| AWS Lambda Python | Amazon Linux 2/2023 | amd64, arm64 | 10 |
| Azure Functions Python | Azure Functions | amd64 | 5 |
| Google Cloud Run Python | google-22/24 | amd64 | 5 |
| Chainguard Python | Wolfi | amd64, arm64 | 2 |
| Google Distroless Python | Debian 13 | amd64, arm64 | 2 |
| Red Hat UBI Python | UBI 9 | amd64, arm64 | 2 |
| Miniconda | conda | amd64, arm64 | 2 |
Every row records the runtime's CPython patch, platform, image family, and platform-specific image digest.
# Refresh the catalog on amd64 and arm64.
python3 scripts/collect_docker.py
# Measure a focused family across every architecture its manifest advertises.
python3 scripts/collect_docker.py \
--families docker-official-alpine \
--versions 3.14.7 \
--platforms autoA row is saved only after its container runs and reports the requested architecture. Use --remove-images to clean up pulled image tags after collection, or --help for custom images, executables, and platforms.
- A fingerprint identifies only what the evaluator exposes. Heavily restricted targets may leave a wide release range.
- Different builds can have the same measured layout.
- Vendor backports can produce unseen behavior. The tool reports a conflict instead of guessing.
- A build outside the matrix remains unknown.