Skip to content

refactor(whisper_cpp): extract methods from transcribe to fix too-many-statements#1540

Merged
raivisdejus merged 17 commits into
chidiwilliams:mainfrom
josiasdev:refactor/extract-methods-from-whispercpp-transcribe
Jul 1, 2026
Merged

refactor(whisper_cpp): extract methods from transcribe to fix too-many-statements#1540
raivisdejus merged 17 commits into
chidiwilliams:mainfrom
josiasdev:refactor/extract-methods-from-whispercpp-transcribe

Conversation

@josiasdev

Copy link
Copy Markdown
Contributor

Why is this change needed?

The WhisperCpp.transcribe method had 166 statements, far exceeding Pylint's default limit of 50 (too-many-statements / R0915). This made the method difficult to read, test, and maintain, as it combined multiple responsibilities in a single monolithic block:

  • Audio format conversion via FFmpeg
  • Command-line construction for whisper-cli
  • Subprocess execution
  • JSON output parsing (with two distinct modes: word-level and segment-level timestamps)
  • Temporary file cleanup

What was done?

The method was decomposed into smaller, cohesive units:

Module-level functions (extracted from nested inner functions):

  • _make_offset_mapper — maps VAD-compressed token offsets back to original audio timeline
  • _flush_complete_chars — decodes multi-token UTF-8 characters (for CJK languages)
  • _append_word — decodes space-separated word segments

Static methods on WhisperCpp:

  • _convert_to_wav — handles FFmpeg conversion from unsupported formats
  • _build_command — assembles the whisper-cli command line
  • _run_whisper — runs the subprocess and forwards stderr output
  • _read_json_output — reads the generated JSON file
  • _parse_word_level_timings — parses word-level timestamps from JSON
  • _parse_segment_timings — parses segment-level timestamps from JSON
  • _cleanup_files — removes temporary files

The transcribe method now acts as an orchestrator (~30 statements), delegating each step to these helpers.

How was it tested?

All 10 existing tests (both integration and mocked unit tests) pass:
tests/transcriber/whisper_cpp_test.py ............. [100%] ======================= 10 passed in 4.97s =======================

Tests were run with uv run pytest tests/transcriber/whisper_cpp_test.py -v. No functionality was changed — only code was rearranged.

Notes for the reviewer

  • The refactoring is behavior-preserving: no logic was modified, only extracted.
  • The three module-level functions (_make_offset_mapper, _flush_complete_chars, _append_word) were previously defined as nested inner functions inside transcribe. They were lifted to module scope to reduce the method's statement count. The segments list is now passed as an explicit parameter instead of being captured via closure.
  • The _run_whisper method intentionally drops the stderr_output list that was previously accumulated but never used outside the loop.
  • Mocked tests that use non-existent file paths produce expected "Failed to remove JSON output file" warnings in stderr — this is the same behavior as before (the exception is caught and logged).

josiasdev and others added 16 commits June 17, 2026 16:42
Decompose ModelDownloader.download_model (142 statements, > 50 limit)
into four focused helpers:
  _prepare_resume_download  - existing file validation & resume logic
  _check_range_support      - server Range-request capability
  _stream_download          - HTTP streaming with progress/cancel
  _verify_sha256            - post-download integrity check

download_model now acts as a high-level orchestrator (~16 statements).
…statements (R0915)

Extraiu 7 métodos auxiliares e 3 funções modulares do método
transcribe (166 statements, limite 50), reduzindo-o para ~30 statements.

Métodos extraídos para WhisperCpp:
  - _convert_to_wav, _build_command, _run_whisper
  - _read_json_output, _parse_word_level_timings
  - _parse_segment_timings, _cleanup_files

Funções extraídas para o módulo:
  - _make_offset_mapper, _flush_complete_chars, _append_word
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.58824% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.91%. Comparing base (e5179fc) to head (e0b9226).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
buzz/transcriber/whisper_cpp.py 80.58% 33 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1540      +/-   ##
==========================================
+ Coverage   82.88%   82.91%   +0.03%     
==========================================
  Files         108      108              
  Lines       11653    11668      +15     
==========================================
+ Hits         9659     9675      +16     
+ Misses       1994     1993       -1     
Flag Coverage Δ
Linux 81.69% <80.58%> (+0.05%) ⬆️
macOS 82.43% <80.58%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@raivisdejus raivisdejus merged commit a591037 into chidiwilliams:main Jul 1, 2026
25 of 31 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.

2 participants