Skip to content
CAI
Software that uses CAICheck a score

benfred/py-spy

59.9

Adequate · 28 September 2026

69.2k

lines of production code

Rust

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a low-overhead, cross-platform profiler for Python applications, implemented in Rust. It captures stack traces, local variables, and thread states from running processes, supporting a wide range of Python versions and operating systems including FreeBSD, macOS, Linux, and Windows. The tool provides profiling data in standard formats like Chrome Trace and integrates with native extensions, while also offering a library interface for programmatic use.

Features

Add Chrome Trace format for recording samples

Users can now record profiling data in the Chrome Trace format (chrome://tracing) by specifying the chrometrace output format. This is implemented in src/chrometrace.rs, which generates trace events with start/end phases for stack frames, and is exposed as a new FileFormat variant in src/config.rs.

src · high confidence

Add example for dumping Python stack traces

A new example file, examples/dump\_traces.rs, demonstrates how to use the Rust API to retrieve and print stack traces from a running Python process. The example initializes a PythonSpy instance with default configuration, retrieves stack traces for all threads in the specified process ID, and prints the thread IDs, statuses, and frame details (name, filename, line number) to the console.

examples · high confidence

Introduce pre-commit hooks for automated linting

The project now uses pre-commit hooks to automatically enforce code quality standards before commits. This configuration integrates codespell for checking spelling in Python and TOML files, Rust formatting and cargo checks, and Prettier for YAML files, ensuring consistent code style across the repository.

(repo-wide) · high confidence

Removals

Removal of Python bindings module declarations

The Rust source file for the Python bindings has been deleted, removing the module declarations for versions 2.7.15, 3.3.7, 3.5.5, 3.6.6, and 3.7.0. This change eliminates the Python binding interface for these specific versions from the codebase.

python-bindings · high confidence

Removed vendored flamegraph.pl library

The project has removed the vendored \flamegraph.pl\ library and its associated CDDL license text from the \vendor/flamegraph\ directory. This change eliminates the local copy of Brendan Gregg's flame graph generation tool, meaning users can no longer rely on this specific vendored script for rendering flamegraphs within the project.

vendor · high confidence

Behavioural changes

Automated Python version matrix updates and new FreeBSD CI infrastructure

The CI pipeline now automatically updates the GitHub Actions test matrix to include the latest supported Python versions by fetching data from the GitHub python-versions manifest, ensuring coverage of new releases without manual intervention. Additionally, new scripts and configuration files have been added to support FreeBSD builds, including a Vagrantfile for local development, a test script for building and caching artifacts, and a publish script to upload FreeBSD release tarballs to GitHub Releases.

ci · high confidence

Expanded Python version support and cross-platform GIL detection

The Python bindings module now includes generated bindings for Python versions 3.10, 3.11, 3.12, 3.13, and 3.14, extending the previously supported range. To ensure accurate thread state and Global Interpreter Lock (GIL) detection across these versions, the module introduces version- and architecture-specific offset calculations for the \interp\_head\ and \tstate\_current\ members of the \PyRuntime\ structure, covering platforms such as macOS, Linux (x86, ARM, aarch64, x86\_64), and Windows. Additionally, the bindings directory has been reorganized into a submodule, and existing bindings have been updated to use modern Clippy lint allowances.

_src/python\bindings · high confidence

Test coverage

Added Cython test data for native extension profiling; Added integration test scripts for subprocesses, threads, and local variables; Added integration tests for py-spy profiling capabilities.

Dependencies

py-spy 0.4.2 dependency overhaul and CLI feature gating

The py-spy project has been updated to version 0.4.2, introducing a comprehensive dependency upgrade and structural change. The CLI interface is now gated behind an optional \cli\ feature flag, allowing the core library to be used without pulling in command-line dependencies like \clap\, \console\, and \inferno\. Key library dependencies have been significantly upgraded, including \clap\ to 4.6.1, \remoteprocess\ to 0.5.2, \goblin\ to 0.10.5, and \console\ to 0.16. The build system has also migrated to \maturin\ (\>=1.0) for Python bindings, replacing the previous \python-bindings\ crate structure.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 61 → 60 (-0.9)
  • Rubric changed (rubric-2026.09.8 → rubric-2026.09.16) — scores are not directly comparable.

Lenses

  • Code Health 83 → 83 (+0.0)
  • Architecture 100 → 84 (-16.5)
  • Maturity 50 → 51 (+0.5)
  • Readiness 65 → 62 (-3.1)
  • Security 61 → 68 (+6.4)

Resolved (15)

  • Documentation: no installation or build instructions (README.md)
  • Hotspot: src/binary_parser.rs (src/binary_parser.rs)
  • Hotspot: src/config.rs (src/config.rs)
  • Hotspot: src/python_process_info.rs (src/python_process_info.rs)
  • Hotspot: src/python_spy.rs (src/python_spy.rs)
  • Members sharing a duplicated core (12 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
  • Members sharing a duplicated core (12 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
  • Members sharing a duplicated core (15 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/mod.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/v3_11_0.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/v3_11_0.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/v3_11_0.rs)
  • Members sharing a duplicated core (5 members, 50+ identical tokens) (src/python_bindings/v3_3_7.rs)
  • Members sharing a duplicated core (5 members, 50+ identical tokens) (src/python_bindings/v3_3_7.rs)
  • Off-boarding risk: anonymized user #1

New (16)

  • Constructor vs Factory Method inconsistency: new is used as a constructor, but retry_new is a factory method with similar intent (creating a PythonSpy instance) but different signature and naming convention. This breaks the standard Rust pattern where constructors are new and complex creation logic is either in new or a distinct Builder/from_* method.
  • Dependency hygiene PARTLY measured — Cargo dependencies read, dependency currency not (crates.io unreachable)
  • Duplicate intent with different signatures: Both PythonCoreDump.print_traces and dump.print_traces handle printing stack traces. The former takes pre-fetched traces, while the latter takes a PID and config (presumably fetching internally). This creates confusion about whether to use the core dump object or the dump module for printing.
  • Duplicate intent with different signatures: PythonCoreDump.print_traces and dump.print_trace both print stack traces. One takes a collection and config, the other takes a single trace and a boolean flag. This inconsistency in handling single vs. multiple traces and configuration parameters is confusing.
  • Inconsistent naming: print_traces (plural) vs print_traces (plural) but different behaviors. One is a method on a specific core dump object, the other is a free function in the dump module. This suggests a lack of clear ownership for the printing responsibility.
  • Members sharing a duplicated core (12 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
  • Members sharing a duplicated core (12 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
  • Members sharing a duplicated core (15 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/mod.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/v3_11_0.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/v3_11_0.rs)
  • Members sharing a duplicated core (4 members, 50+ identical tokens) (src/python_bindings/v3_11_0.rs)
  • Members sharing a duplicated core (5 members, 50+ identical tokens) (src/python_bindings/v3_3_7.rs)
  • Members sharing a duplicated core (5 members, 50+ identical tokens) (src/python_bindings/v3_3_7.rs)
  • Off-boarding risk: anonymized user #1
  • Projects may be oversized for their cohesion

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

benfred/py-spy was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 28 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 32080cc0c22bc23938541dfa7dabb6090e40be14 — the exact code this score is about.
  • Scored under rubric-2026.09.16 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-d46da229e3fd.