Skip to content

fix(build): declare capstone>=5.0.2 - #405

Merged
danielplohmann merged 2 commits into
masterfrom
fix/capstone-lower-bound
Oct 16, 2026
Merged

danielplohmann merged 2 commits into
masterfrom
fix/capstone-lower-bound

Conversation

@danielplohmann

Copy link
Copy Markdown
Owner

What this changes

Raises smda's declared capstone requirement from capstone<6 to capstone>=5.0.2,<6, with the rationale beside the existing comment in pyproject.toml, plus a CHANGELOG.md entry under ### Fixed.

StringExtractor imports CS_GRP_BRANCH_RELATIVE since #382, and capstone 4.x does not have that constant. With no lower bound declared, pip resolves capstone 4.0.2 whenever another package pins it. dumpulator 0.2.6 does (capstone~=4.0.2). pip check then reports nothing, and import smda.Disassembler raises ImportError. This came up in a fresh Ubuntu 26.04 course-host install that put smda 4.11.0, mcrit and dumpulator into one venv.

Why the floor is 5.0.2 and not 5.0.0: capstone 5.0.0.post1 and 5.0.1 import distutils, which Python 3.12 removed, so on the interpreters smda supports they fail at import.

Cost: smda no longer installs into the same environment as dumpulator 0.2.6. That conflict existed before as a runtime ImportError. pip now reports it at install time as ResolutionImpossible.

How it was verified

Python 3.14.4, branched from bff1bfd (v4.11.0):

capstone Result
4.0.2 collection fails: ImportError: cannot import name 'CS_GRP_BRANCH_RELATIVE'
5.0.0.post1, 5.0.1 import capstone fails: No module named 'distutils'
5.0.2 full suite: 2397 passed, 2 skipped, 2789 subtests passed
5.0.9 full suite: 2397 passed, 2 skipped, 2789 subtests passed
  • Installed metadata reads capstone<6,>=5.0.2.

  • pip install --dry-run . dumpulator==0.2.6 now fails with ResolutionImpossible, where it used to install.

  • make lint and make format (ruff check: all passed; ruff format: 304 files already formatted)

  • make test-all (full suite on 5.0.2 and 5.0.9, see the table)

  • CHANGELOG.md entry under ## [Unreleased]

  • Golden fixtures unchanged (metadata-only change, no source touched)

🤖 Generated with Claude Code

StringExtractor imports CS_GRP_BRANCH_RELATIVE since #382, which capstone 4.x
lacks, but only capstone<6 was declared. Beside dumpulator (capstone~=4.0.2)
pip resolved 4.0.2, pip check passed, and import smda.Disassembler failed.
5.0.0.post1 and 5.0.1 import distutils and fail on Python 3.12+, so the floor
is 5.0.2.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

📊 SMDA Performance Evaluation Benchmark Results

Generated on: 2026-10-16 13:31:30

Summary

Metric Result
Correctness ✅ PASS — 0 / 155 common file(s) differ
Determinism ✅ PASS — base 3 run(s), PR 3 run(s)
Verdict inconclusive — within run-to-run noise (±1.5%)
Median paired speedup +0.36% (95% CI [+0.17%, +0.61%])
Timing noise band ±1.5%

Per-side Timing Context (best of 3/3 runs per file)

Side Files Functions Median best time/file (s) Sum of best times (s) Throughput estimate (func/s)
base 155 173540 0.6138 215.23 ~806
pr 155 173540 0.6205 214.50 ~809

These context rows sum each file's best observed time across repeated runs; they are normalized comparison estimates, not single-run CI wall-clock times.

Paired per-file timing (positive speedup = PR faster):

Statistic Value
Files compared 155
Median paired speedup +0.36% (95% CI [+0.17%, +0.61%])
Mean speedup +0.06% (95% CI [-0.60%, +0.68%])
Std dev / IQR 4.08% / 3.05%
Wilcoxon signed-rank p 0.0088 (n=155)

ℹ️ base and PR are timed in the same job on the same runner, with their passes interleaved base/PR/PR/base/base/PR so that drift over the job cancels rather than landing on whichever side ran last. The noise band above is therefore run-to-run variation on one machine, which is what it is able to measure; a difference inside it is reported as inconclusive. Correctness and determinism are not timing-based and are unaffected either way.

Determinism (self-check across repeated runs)

Side Runs Files Deterministic Median timing CV
base 3 155 ✅ 1.5%
pr 3 155 ✅ 1.3%
Pairwise run matrix (individual run medians, diagnostic)

Diagnostic only: each row compares one raw PR run against one raw base run. The headline verdict above uses paired per-file best-of-runs timings.

Comparison Run PR Files Base Files Common Function Set Matches Med PR (s) Med Base (s) Med Diff (s) Speedup %
pr_0 vs base_0 155 155 155 155/155 0.6382s 0.6583s -0.0201s +3.06%
pr_0 vs base_1 155 155 155 155/155 0.6382s 0.6270s +0.0112s -1.78%
pr_0 vs base_2 155 155 155 155/155 0.6382s 0.6193s +0.0188s -3.04%
pr_1 vs base_0 155 155 155 155/155 0.6399s 0.6583s -0.0183s +2.79%
pr_1 vs base_1 155 155 155 155/155 0.6399s 0.6270s +0.0129s -2.06%
pr_1 vs base_2 155 155 155 155/155 0.6399s 0.6193s +0.0206s -3.33%
pr_2 vs base_0 155 155 155 155/155 0.6346s 0.6583s -0.0237s +3.60%
pr_2 vs base_1 155 155 155 155/155 0.6346s 0.6270s +0.0076s -1.21%
pr_2 vs base_2 155 155 155 155/155 0.6346s 0.6193s +0.0153s -2.46%

@danielplohmann danielplohmann added this to the v5.0.0 milestone Oct 16, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@danielplohmann
danielplohmann merged commit f25e51c into master Oct 16, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant