Skip to content

Add 'bencher' console-script entry point for the render/compare CLI#964

Merged
blooop merged 2 commits into
mainfrom
add-bencher-console-script
Jun 21, 2026
Merged

Add 'bencher' console-script entry point for the render/compare CLI#964
blooop merged 2 commits into
mainfrom
add-bencher-console-script

Conversation

@blooop

@blooop blooop commented Jun 21, 2026

Copy link
Copy Markdown
Owner

What

Register a bencher console-script entry point so the render/compare CLI is a real command instead of only python -m bencher.render.

[project.scripts]
bencher = "bencher.render:main"

After install:

bencher <result.pkl> <out_dir> [--json result.json]   # render (+ optional JSON export)
bencher compare <a.pkl> <b.pkl> --json comparison.json # machine-readable diff

Why

python -m bencher.render is non-obvious and easy to mistype — the module name render doesn't hint that it also does JSON export and result comparison. A first-time user (or an agent told to "use the bencher CLI") has to go discover the module path. A named command matches the mental model and makes bencher --help self-documenting.

Non-breaking

This is purely additive:

  • python -m bencher.render … is unchanged and keeps working — same main().
  • No argument names, subcommand structure, or exit codes changed.
  • The only behaviour change is help/usage text, which is now invocation-aware via a small _prog() helper: it reads bencher under the console script and python -m bencher.render from a source checkout, so the displayed command always matches how the tool was run.

Verification

  • test/test_render.py — added test_prog_name_is_invocation_aware; full module green (22 passed). Existing CLI tests drive render.main([...]) directly and are unaffected.
  • Built + installed the wheel in an isolated venv and confirmed the bencher script resolves and dispatches:
    • bencher --helpusage: bencher …
    • bencher compare --helpusage: bencher compare …
    • no-arg → Usage: bencher <result_path> <output_dir> [--json PATH], exit 2
  • ruff check / ruff format / prek run all clean.

Version bumped 1.107.0 → 1.108.0 (minor — new feature) with a CHANGELOG entry, per the auto-publish-on-version-bump convention.

Summary by Sourcery

Introduce a named bencher CLI entry point while keeping the existing python -m bencher.render invocation working unchanged.

New Features:

  • Add a bencher console-script entry point that invokes the existing render/compare CLI main entry.

Enhancements:

  • Make CLI usage and help text invocation-aware so it reflects whether the tool is run via the bencher script or python -m bencher.render.

Build:

  • Register the bencher console script in pyproject.toml and bump the project version to 1.108.0.

Documentation:

  • Document the new bencher CLI entry and behavior in the changelog.

Tests:

  • Add a test ensuring the computed program name matches the actual invocation for usage/help output.

The render/compare CLI was only reachable via 'python -m bencher.render',
which is non-obvious and easy to mistype. Register a 'bencher' console
script (project.scripts -> bencher.render:main) so it can be invoked as
'bencher <result.pkl> <out> [--json PATH]' and 'bencher compare ...'.

Purely additive: 'python -m bencher.render' is unchanged. Usage/--help text
is now invocation-aware via a _prog() helper so the displayed command
matches how the tool was run.
@sourcery-ai

sourcery-ai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds a new bencher console-script entry point wired to bencher.render:main, and makes CLI help/usage text dynamically reflect how the command was invoked, while keeping the existing python -m bencher.render entrypoint fully backward compatible. Also bumps the project version and documents the change in the changelog, plus adds tests to pin the new invocation-aware behaviour.

Sequence diagram for bencher CLI invocation paths

sequenceDiagram
    actor User
    participant Shell
    participant bencher_script as bencher_console_script
    participant python_module as bencher.render
    participant main as main
    participant prog as _prog

    User->>Shell: bencher ...
    Shell->>bencher_script: execute entry point
    bencher_script->>python_module: import bencher.render
    bencher_script->>main: main(argv)
    main->>prog: _prog()
    prog-->>main: bencher
    main-->>User: usage/help with bencher

    alt python -m bencher.render
        User->>Shell: python -m bencher.render ...
        Shell->>python_module: python -m bencher.render
        python_module->>main: main(argv)
        main->>prog: _prog()
        prog-->>main: python -m bencher.render
        main-->>User: usage/help with python -m bencher.render
    end
Loading

File-Level Changes

Change Details Files
Introduce an invocation-aware program-name helper and update CLI parsers/usage to use it so help text matches the actual command used (console script vs python -m).
  • Add a private _prog() helper that inspects sys.argv[0] and returns bencher when invoked via the console script, otherwise python -m bencher.render.
  • Switch _render_parser() and _compare_parser() to use _prog() for their prog value, with the compare parser building f"{_prog()} compare".
  • Update main() docstring examples to reference bencher instead of python -m bencher.render and describe both invocation forms.
  • Change the no-argument usage error message to print a Usage: line built from _prog() so it tracks the invocation form.
bencher/render.py
Add tests to cover the new invocation-aware _prog() behaviour.
  • Add test_prog_name_is_invocation_aware to assert _prog() returns bencher when sys.argv[0] looks like the installed console script and python -m bencher.render otherwise, using mock.patch on bencher.render.sys.argv.
  • Keep existing CLI tests unchanged so they continue to exercise render.main([...]) directly.
test/test_render.py
Register a bencher console-script entry point and bump project version with corresponding changelog entry.
  • Add a [project.scripts] section mapping bencher to "bencher.render:main" so installers generate a bencher console script.
  • Increment the project version from 1.107.0 to 1.108.0 to reflect the new feature.
  • Document the new bencher CLI entry point, its non-breaking nature, and the invocation-aware _prog() helper in a new 1.108.0 changelog entry.
pyproject.toml
CHANGELOG.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The _prog() helper assumes the console script name is exactly bencher, which may not hold on some platforms or packaging setups (e.g., bencher.exe, bencher-3.12); consider a more robust detection (e.g., exe.startswith("bencher") or checking sys.argv[0] for a suffix) so usage/help stays accurate in those cases.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `_prog()` helper assumes the console script name is exactly `bencher`, which may not hold on some platforms or packaging setups (e.g., `bencher.exe`, `bencher-3.12`); consider a more robust detection (e.g., `exe.startswith("bencher")` or checking `sys.argv[0]` for a suffix) so usage/help stays accurate in those cases.

## Individual Comments

### Comment 1
<location path="bencher/render.py" line_range="142" />
<code_context>
+    to the explicit ``python -m bencher.render`` form otherwise, so the usage
+    line always names a command the reader can actually run.
+    """
+    exe = Path(sys.argv[0]).name
+    return "bencher" if exe == "bencher" else "python -m bencher.render"
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Handle Windows console-script suffixes when deriving the program name.

On Windows, installed console scripts are usually invoked via `bencher.exe` or `bencher-script.py`, so `Path(sys.argv[0]).name` will rarely equal `"bencher"`. That means `_prog()` will still report `"python -m bencher.render"`, even when users actually run `bencher`, which makes the usage text misleading for Windows users.

To avoid this, make the comparison extension-agnostic, for example by stripping common suffixes before comparing, or simply using `Path(sys.argv[0]).stem` instead of `.name` when checking for `"bencher"`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread bencher/render.py
@github-actions

Copy link
Copy Markdown

Performance Report for e01506e

Metric Value
Total tests 1681
Total time 123.71s
Mean 0.0736s
Median 0.0020s
Top 10 slowest tests
Test Time (s)
test.test_bench_examples.TestBenchExamples::test_example_meta 17.120
test.test_over_time_save_perf::test_save_faster_without_aggregated_tab 5.072
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_drift.py] 4.519
test.test_generated_examples::test_generated_example[cartesian_animation/example_cartesian_animation.py] 2.965
test.test_split_render_examples::test_split_render_subprocess_media 2.953
test.test_hash_persistent.TestCrossProcessDeterminism::test_hash_stable_across_two_processes[ResultBool] 2.815
test.test_over_time_repeats.TestMaxSliderPoints::test_default_subsampling_caps_at_max 2.810
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_noise.py] 2.787
test.test_generated_examples::test_generated_example[result_types/result_image/example_result_image_to_video.py] 2.777
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_step.py] 2.491

Full report

Updated by Performance Tracking workflow

Match a 'bencher' prefix on argv[0] basename rather than an exact 'bencher'
so platform/packaging variants of the console script still resolve the usage
text correctly: bencher.exe on Windows, bencher-3.12 for a versioned install.
The module form's render.py basename never matches. Addresses PR review.
@blooop blooop enabled auto-merge June 21, 2026 17:28
@github-actions

Copy link
Copy Markdown

Performance Report for 496ba5b

Metric Value
Total tests 1681
Total time 124.41s
Mean 0.0740s
Median 0.0020s
Top 10 slowest tests
Test Time (s)
test.test_bench_examples.TestBenchExamples::test_example_meta 17.703
test.test_over_time_save_perf::test_save_faster_without_aggregated_tab 4.969
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_drift.py] 4.547
test.test_split_render_examples::test_split_render_subprocess_media 2.989
test.test_generated_examples::test_generated_example[cartesian_animation/example_cartesian_animation.py] 2.948
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_noise.py] 2.785
test.test_generated_examples::test_generated_example[result_types/result_image/example_result_image_to_video.py] 2.782
test.test_hash_persistent.TestCrossProcessDeterminism::test_hash_stable_across_two_processes[ResultBool] 2.724
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_step.py] 2.493
test.test_over_time_repeats.TestMaxSliderPoints::test_default_subsampling_caps_at_max 2.409

Full report

Updated by Performance Tracking workflow

@blooop blooop merged commit a875b66 into main Jun 21, 2026
7 of 8 checks passed
@blooop blooop deleted the add-bencher-console-script branch June 21, 2026 17:33
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