Report writing utility file - #978
Open
kyle-hoffmeyer wants to merge 8 commits into
Open
kyle-hoffmeyer wants to merge 8 commits into
kyle-hoffmeyer wants to merge 8 commits into
Conversation
kyle-hoffmeyer
marked this pull request as ready for review
August 28, 2026 22:10
kyle-hoffmeyer
requested review from
ajassani,
devalshahamd,
gabeweisz and
tsrikris
as code owners
August 28, 2026 22:10
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
kyle-hoffmeyer
force-pushed
the
cleanup/report_writing_utility
branch
from
September 1, 2026 00:24
d55c0ef to
8ecf927
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR creates a report writing utility file and creates utility functions for exporting dataframes to csvs/excel files.
Every report generator in
TraceLens/Reporting/ended with its own copy of the same "write these DataFrames out" boilerplate: make the CSV directory, loop and write one CSV per sheet, check thatopenpyxlis importable, open anExcelWriter, and loop again writing one sheet per DataFrame. Ten generators carried a near-identical version of this block — roughly 300 lines of duplicated logic.Because each copy drifted independently, they had also become inconsistent in ways that were quietly buggy:
[:31](which silently collides when two long names share a prefix), some did collision-safe truncation, and several did no truncation at all — meaning a long sheet name would make the whole report fail.openpyxlhandling. Half the generators prompted the user topip install openpyxl; the other half raisedImportError; a couple didn't check at all.openpyxlis in fact a declared install dependency, so all of this was dead defensive code.This PR consolidates all of that into a single shared utility and migrates every generator onto it, which both removes the duplication and makes the behavior uniform.
Implementation
New
write_report_outputs()inTraceLens/Reporting/reporting_utils.py. This is the one place report DataFrames get written. It takes the{sheet_name: DataFrame}mapping plus optionalxlsx_pathandcsvs_dir, and writes whichever outputs were requested (both, if both are given). Two smaller behaviors are folded in:hide_columns— an optional{sheet_name: [column, ...]}mapping for columns that should be hidden in the Excel view (they stay in the file, just collapsed). This exists so the comparison report, the one generator that post-processes its worksheets, can express its column-hiding declaratively instead of reaching into the writer itself.skip_empty— dropsNone/empty DataFrames from all outputs. Off by default (an empty-but-present sheet is often a meaningful "we looked and found nothing" signal), opted into only by the genesis report.Sheet-name sanitization is handled once, in the new
_safe_sheet_name()helper (promoted from the genesis report, which already had the only collision-safe implementation): truncate to 31 chars, and if the name of the sheet already exists append_1,_2, ... to the end of the name while staying within the 31 char limit.New
derive_pftrace_output_path()inTraceLens/Reporting/pftrace_utils.py. The three pftrace generators each had an identical block for turning an input trace path into a default.xlsxpath (stripping.pftrace/.json.gz/ other suffixes). That block is now a single helper parameterized by the report-specific suffix.Tests
TestWriteReportOutputs,TestSafeSheetName, andTestDerivePftraceOutputPathtotests/test_reporting_utils.py(18 cases). Coverage includes CSV-only, Excel-only, and both-at-once output; the no-op case; long-name truncation and dedup;skip_emptybehavior in both directions;hide_columnshiding the right column while leaving the data intact and ignoring column names that don't exist; and a regression test for the"sheet"-name collision described above.tests/test_genesis.py(where they imported the helper from the genesis module) intotests/test_reporting_utils.py, so they now live next to the function's actual home.