Commit 91547e6
authored
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
- analyzer
- tests
- functional
- analyze_and_parse/test_files
- analyze
- libtest
- tools/report-converter
- codechecker_report_converter
- report
- requirements_py/dev
- web/tests/functional/store
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
536 | 536 | | |
537 | 537 | | |
538 | 538 | | |
539 | | - | |
| 539 | + | |
540 | 540 | | |
541 | 541 | | |
542 | 542 | | |
| |||
Lines changed: 20 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
Lines changed: 20 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
| |||
Lines changed: 5 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
Lines changed: 20 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
Lines changed: 20 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
Lines changed: 20 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
0 commit comments