Skip to content

Commit 91547e6

Browse files
Use PrettyTable library for human-readable table output (#4994)
* Use PrettyTable library for human-readable table output Replace the custom to_table() implementation in twodim.py with the PrettyTable library (prettytable~=3.0). The old implementation produced tables that fell apart on long lines. PrettyTable handles long content gracefully with proper box-drawing borders and correct column alignment. - Rewrite to_table() using PrettyTable with SINGLE_BORDER style - Left-align all columns to match previous formatting convention - Support separate_head and headerless table modes - Add prettytable~=3.0 to analyzer/requirements.txt - Add prettytable~=3.0 to report-converter dev requirements Other output formats (csv, json, rows, dictlist) are unchanged. * Fix unused separate_footer argument in to_table() pylint flagged separate_footer as an unused argument. Implement it properly: when True, the last row is printed as a separate table below the main one, visually distinguishing footer rows (e.g. totals) from regular data rows. * Update expected test output files for PrettyTable format The analyze_and_parse functional tests compare CodeChecker parse output against stored .output files. Update all 61 expected output files to reflect the new PrettyTable table format (box-drawing borders) instead of the old plain-dash format. * Fix: use TableStyle enum instead of deprecated SINGLE_BORDER constant pylint reported no-name-in-module because SINGLE_BORDER is a deprecated alias not listed in prettytable's __all__. Switch to the proper TableStyle.SINGLE_BORDER enum introduced in prettytable 3.x. * Fix test encoding: ensure UTF-8 output in codechecker_env() PrettyTable uses Unicode box-drawing characters (┌─┬─┐) which require UTF-8 encoding to render correctly. In CI environments with a non-UTF-8 locale, these characters were outputting replacement chars (?) causing golden-output mismatches in the analyze_and_parse functional tests. Set PYTHONIOENCODING, LC_ALL and LANG to UTF-8 in codechecker_env() so that all subprocess invocations produce stable UTF-8 output regardless of the runner's locale. * Fix: remove broken _supports_unicode, fix summary table separator Two issues: 1. Leftover _supports_unicode() reference caused NameError - removed. 2. PrettyTable with SINGLE_BORDER adds a separator (├───┤) between rows only when hrules includes ROWS. The Summary table (separate_head=False) was rendering with a mid-row separator that doesn't belong there. Updated all 61 .output test files to match the correct output where the summary block has no separator between its two data rows. * Fix test output files: restore missing header separator line The conversion script stripped the ├───┤ separator between the header row and data rows in headed tables. Restore it in all 61 .output files to match what PrettyTable SINGLE_BORDER actually produces. * Fix unsupported item assignment on PrettyTable align property * Fix Summary table separator row and PrettyTable HRuleStyle import * Fix line too long in statistics.py * Fix test assertions: update old pipe-format table checks to PrettyTable format * Address PR review: fit table to terminal width, restore | 1 test check - twodim.py: add _fit_table_to_width() which detects terminal width via shutil.get_terminal_size() and proportionally distributes column widths. Short columns keep their natural width; only wide columns are shortened. No column types are hard-coded — widths are computed from actual data. max_table_width is applied as a safety net for rounding errors. - test_analyze.py: restore the check that the processed-file count is actually 1 (not just that the label appears). The old assertIn with '| 1' broke because PrettyTable uses Unicode box-drawing characters instead of ASCII pipes, so the assertion now checks that the label and the token '1' appear on the same output line. * Fix linter errors in twodim.py - Split overlong comment line (E501/C0301) - Rename MIN_COL_WIDTH to min_col_width (C0103 snake_case) - Refactor _fit_table_to_width() from 6 to 3 args by extracting natural-width computation into a separate _compute_natural_widths() helper, eliminating the too-many-positional-arguments warning (R0917) * Fix mypy type errors in twodim.py - Change assigned from List[Optional[int]] to List[int] (initialised to 0) so mypy knows every element is always an int before use - Add type: ignore[assignment] on table.align = 'l' to suppress mypy complaint about PrettyTable's dict-typed align property * Honour COLUMNS env var for terminal width detection shutil.get_terminal_size() reads directly from the OS TTY and ignores the COLUMNS environment variable when a real TTY is attached. Check COLUMNS first so users can override the detected width, then fall back to shutil.get_terminal_size() and finally to 80 columns. * Fix column-width algorithm: protect short columns from truncation The previous proportional-share approach could truncate short columns like 'Severity' (8 chars) when the proportional share fell just below the natural width due to rounding. New approach: in each fixpoint iteration, lock any column whose natural width fits within the *equal share* (remaining / num_unassigned). This guarantees short columns always keep their full natural width. Only the genuinely wide columns are then shortened proportionally from what remains. * Fix test: use Unicode │ separator to match PrettyTable output The reviewer asked to keep the '| 1' check to assert the processed-file count is exactly 1. PrettyTable uses │ (U+2502) instead of ASCII |, so replace the previous any()-loop with a direct assertIn using the Unicode box-drawing character. * Address PR review comments - twodim.py: move 'import os' to top of file (was inline inside to_table) - twodim.py: move _compute_natural_widths() call inside _fit_table_to_width() so nat_widths is no longer an external parameter at the call site - test_store.py: restore the '| 6' check to assert the report count is exactly 6; use Unicode │ (U+2502) to match PrettyTable's separator * Fix test_store_stats: use regex for flexible whitespace matching The PrettyTable output may have variable spacing around the number depending on column width calculations. Use assertRegex instead of assertIn to allow flexible whitespace around the value and separator. * Fix test_store_stats: use regex with \s+ to match PrettyTable padding PrettyTable pads column content with spaces, so the output is: '│ Number of analyzer reports │ 6 │' Use assertRegex with \s+ to match the whitespace padding while still asserting the count is exactly 6. * Update test assertions for PrettyTable format Clean up test assertions * Derive field names and rows from table object in width fitting --------- Co-authored-by: Muteeb Haider <muteeb-haider@users.noreply.github.com>
1 parent 6a7f48f commit 91547e6

68 files changed

Lines changed: 1286 additions & 1088 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

analyzer/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ setuptools~=80.0
1616
types-setuptools~=80.0
1717
semver~=3.0
1818
argcomplete~=3.0
19+
prettytable~=3.0

analyzer/tests/functional/analyze/test_analyze.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ def test_reproducer_postprocesses_failures(self):
536536
# The key bug: with --generate-reproducer, postprocessing was skipped
537537
# so parse would show 0 processed files. After the fix, it should
538538
# show 1 processed file.
539-
self.assertIn("Number of processed analyzer result files | 1", out)
539+
self.assertIn("Number of processed analyzer result files 1", out)
540540

541541
shutil.rmtree(reproducer_dir)
542542

analyzer/tests/functional/analyze_and_parse/test_files/all_checkers_off_except_return_stack_address.output

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,35 @@ Found 1 defect(s) in all_checkers_off_except_return_stack_address.c
2626

2727

2828
----==== Severity Statistics ====----
29-
----------------------------
30-
Severity | Number of reports
31-
----------------------------
32-
MEDIUM | 1
33-
----------------------------
29+
┌──────────┬───────────────────┐
30+
Severity Number of reports
31+
├──────────┼───────────────────┤
32+
MEDIUM │ 1
33+
└──────────┴───────────────────┘
3434
----=================----
3535

3636
----==== Checker Statistics ====----
37-
--------------------------------------------------------------------
38-
Checker name | Severity | Number of reports
39-
--------------------------------------------------------------------
40-
clang-diagnostic-return-stack-address | MEDIUM | 1
41-
--------------------------------------------------------------------
37+
┌───────────────────────────────────────┬──────────┬───────────────────┐
38+
Checker name Severity Number of reports
39+
├───────────────────────────────────────┼──────────┼───────────────────┤
40+
clang-diagnostic-return-stack-address MEDIUM │ 1
41+
└───────────────────────────────────────┴──────────┴───────────────────┘
4242
----=================----
4343

4444
----==== File Statistics ====----
45-
------------------------------------------------------------------
46-
File name | Number of reports
47-
------------------------------------------------------------------
48-
all_checkers_off_except_return_stack_address.c | 1
49-
------------------------------------------------------------------
45+
┌────────────────────────────────────────────────┬───────────────────┐
46+
File name Number of reports
47+
├────────────────────────────────────────────────┼───────────────────┤
48+
all_checkers_off_except_return_stack_address.c │ 1
49+
└────────────────────────────────────────────────┴───────────────────┘
5050
----=================----
5151

5252
----======== Summary ========----
53-
---------------------------------------------
54-
Number of processed analyzer result files | 1
55-
Number of analyzer reports | 1
56-
---------------------------------------------
53+
┌───────────────────────────────────────────┬───┐
54+
│ Number of processed analyzer result files │ 1 │
55+
├───────────────────────────────────────────┼───┤
56+
│ Number of analyzer reports │ 1 │
57+
└───────────────────────────────────────────┴───┘
5758
----=================----
5859
[] - ----==== Summary ====----
5960
[] - Up-to-date analysis results

analyzer/tests/functional/analyze_and_parse/test_files/compiler_error.output

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,35 @@ Found 1 defect(s) in compiler_error.cpp
2525

2626

2727
----==== Severity Statistics ====----
28-
----------------------------
29-
Severity | Number of reports
30-
----------------------------
31-
CRITICAL | 1
32-
----------------------------
28+
┌──────────┬───────────────────┐
29+
Severity Number of reports
30+
├──────────┼───────────────────┤
31+
CRITICAL │ 1
32+
└──────────┴───────────────────┘
3333
----=================----
3434

3535
----==== Checker Statistics ====----
36-
-----------------------------------------------------
37-
Checker name | Severity | Number of reports
38-
-----------------------------------------------------
39-
clang-diagnostic-error | CRITICAL | 1
40-
-----------------------------------------------------
36+
┌────────────────────────┬──────────┬───────────────────┐
37+
Checker name Severity Number of reports
38+
├────────────────────────┼──────────┼───────────────────┤
39+
clang-diagnostic-error CRITICAL │ 1
40+
└────────────────────────┴──────────┴───────────────────┘
4141
----=================----
4242

4343
----==== File Statistics ====----
44-
--------------------------------------
45-
File name | Number of reports
46-
--------------------------------------
47-
compiler_error.cpp | 1
48-
--------------------------------------
44+
┌────────────────────┬───────────────────┐
45+
File name Number of reports
46+
├────────────────────┼───────────────────┤
47+
compiler_error.cpp │ 1
48+
└────────────────────┴───────────────────┘
4949
----=================----
5050

5151
----======== Summary ========----
52-
---------------------------------------------
53-
Number of processed analyzer result files | 1
54-
Number of analyzer reports | 1
55-
---------------------------------------------
52+
┌───────────────────────────────────────────┬───┐
53+
│ Number of processed analyzer result files │ 1 │
54+
├───────────────────────────────────────────┼───┤
55+
│ Number of analyzer reports │ 1 │
56+
└───────────────────────────────────────────┴───┘
5657
----=================----
5758
[] - ----==== Summary ====----
5859
[] - Up-to-date analysis results

analyzer/tests/functional/analyze_and_parse/test_files/compiler_error_disabled.output

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ NORMAL#CodeChecker parse $OUTPUT$
1919
[] - ----=================----
2020

2121
----======== Summary ========----
22-
---------------------------------------------
23-
Number of processed analyzer result files | 0
24-
Number of analyzer reports | 0
25-
---------------------------------------------
22+
┌───────────────────────────────────────────┬───┐
23+
│ Number of processed analyzer result files │ 0 │
24+
├───────────────────────────────────────────┼───┤
25+
│ Number of analyzer reports │ 0 │
26+
└───────────────────────────────────────────┴───┘
2627
----=================----
2728
[] - ----==== Summary ====----
2829
[] - Up-to-date analysis results

analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_default_checker_priority.output

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,35 @@ Found 1 defect(s) in compiler_warning.cpp
2626

2727

2828
----==== Severity Statistics ====----
29-
----------------------------
30-
Severity | Number of reports
31-
----------------------------
32-
MEDIUM | 1
33-
----------------------------
29+
┌──────────┬───────────────────┐
30+
Severity Number of reports
31+
├──────────┼───────────────────┤
32+
MEDIUM │ 1
33+
└──────────┴───────────────────┘
3434
----=================----
3535

3636
----==== Checker Statistics ====----
37-
---------------------------------------------------------------
38-
Checker name | Severity | Number of reports
39-
---------------------------------------------------------------
40-
clang-diagnostic-unused-variable | MEDIUM | 1
41-
---------------------------------------------------------------
37+
┌──────────────────────────────────┬──────────┬───────────────────┐
38+
Checker name Severity Number of reports
39+
├──────────────────────────────────┼──────────┼───────────────────┤
40+
clang-diagnostic-unused-variable MEDIUM │ 1
41+
└──────────────────────────────────┴──────────┴───────────────────┘
4242
----=================----
4343

4444
----==== File Statistics ====----
45-
----------------------------------------
46-
File name | Number of reports
47-
----------------------------------------
48-
compiler_warning.cpp | 1
49-
----------------------------------------
45+
┌──────────────────────┬───────────────────┐
46+
File name Number of reports
47+
├──────────────────────┼───────────────────┤
48+
compiler_warning.cpp │ 1
49+
└──────────────────────┴───────────────────┘
5050
----=================----
5151

5252
----======== Summary ========----
53-
---------------------------------------------
54-
Number of processed analyzer result files | 1
55-
Number of analyzer reports | 1
56-
---------------------------------------------
53+
┌───────────────────────────────────────────┬───┐
54+
│ Number of processed analyzer result files │ 1 │
55+
├───────────────────────────────────────────┼───┤
56+
│ Number of analyzer reports │ 1 │
57+
└───────────────────────────────────────────┴───┘
5758
----=================----
5859
[] - ----==== Summary ====----
5960
[] - Up-to-date analysis results

analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_simple.output

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,35 @@ Found 1 defect(s) in compiler_warning.cpp
2626

2727

2828
----==== Severity Statistics ====----
29-
----------------------------
30-
Severity | Number of reports
31-
----------------------------
32-
MEDIUM | 1
33-
----------------------------
29+
┌──────────┬───────────────────┐
30+
Severity Number of reports
31+
├──────────┼───────────────────┤
32+
MEDIUM │ 1
33+
└──────────┴───────────────────┘
3434
----=================----
3535

3636
----==== Checker Statistics ====----
37-
---------------------------------------------------------------
38-
Checker name | Severity | Number of reports
39-
---------------------------------------------------------------
40-
clang-diagnostic-unused-variable | MEDIUM | 1
41-
---------------------------------------------------------------
37+
┌──────────────────────────────────┬──────────┬───────────────────┐
38+
Checker name Severity Number of reports
39+
├──────────────────────────────────┼──────────┼───────────────────┤
40+
clang-diagnostic-unused-variable MEDIUM │ 1
41+
└──────────────────────────────────┴──────────┴───────────────────┘
4242
----=================----
4343

4444
----==== File Statistics ====----
45-
----------------------------------------
46-
File name | Number of reports
47-
----------------------------------------
48-
compiler_warning.cpp | 1
49-
----------------------------------------
45+
┌──────────────────────┬───────────────────┐
46+
File name Number of reports
47+
├──────────────────────┼───────────────────┤
48+
compiler_warning.cpp │ 1
49+
└──────────────────────┴───────────────────┘
5050
----=================----
5151

5252
----======== Summary ========----
53-
---------------------------------------------
54-
Number of processed analyzer result files | 1
55-
Number of analyzer reports | 1
56-
---------------------------------------------
53+
┌───────────────────────────────────────────┬───┐
54+
│ Number of processed analyzer result files │ 1 │
55+
├───────────────────────────────────────────┼───┤
56+
│ Number of analyzer reports │ 1 │
57+
└───────────────────────────────────────────┴───┘
5758
----=================----
5859
[] - ----==== Summary ====----
5960
[] - Up-to-date analysis results

analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_wno_group.output

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,35 @@ Found 1 defect(s) in compiler_warning.cpp
2626

2727

2828
----==== Severity Statistics ====----
29-
----------------------------
30-
Severity | Number of reports
31-
----------------------------
32-
MEDIUM | 1
33-
----------------------------
29+
┌──────────┬───────────────────┐
30+
Severity Number of reports
31+
├──────────┼───────────────────┤
32+
MEDIUM │ 1
33+
└──────────┴───────────────────┘
3434
----=================----
3535

3636
----==== Checker Statistics ====----
37-
---------------------------------------------------------------
38-
Checker name | Severity | Number of reports
39-
---------------------------------------------------------------
40-
clang-diagnostic-unused-variable | MEDIUM | 1
41-
---------------------------------------------------------------
37+
┌──────────────────────────────────┬──────────┬───────────────────┐
38+
Checker name Severity Number of reports
39+
├──────────────────────────────────┼──────────┼───────────────────┤
40+
clang-diagnostic-unused-variable MEDIUM │ 1
41+
└──────────────────────────────────┴──────────┴───────────────────┘
4242
----=================----
4343

4444
----==== File Statistics ====----
45-
----------------------------------------
46-
File name | Number of reports
47-
----------------------------------------
48-
compiler_warning.cpp | 1
49-
----------------------------------------
45+
┌──────────────────────┬───────────────────┐
46+
File name Number of reports
47+
├──────────────────────┼───────────────────┤
48+
compiler_warning.cpp │ 1
49+
└──────────────────────┴───────────────────┘
5050
----=================----
5151

5252
----======== Summary ========----
53-
---------------------------------------------
54-
Number of processed analyzer result files | 1
55-
Number of analyzer reports | 1
56-
---------------------------------------------
53+
┌───────────────────────────────────────────┬───┐
54+
│ Number of processed analyzer result files │ 1 │
55+
├───────────────────────────────────────────┼───┤
56+
│ Number of analyzer reports │ 1 │
57+
└───────────────────────────────────────────┴───┘
5758
----=================----
5859
[] - ----==== Summary ====----
5960
[] - Up-to-date analysis results

0 commit comments

Comments
 (0)