Coverage for lintro / formatters / styles / grid.py: 89%
27 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Grid output style implementation."""
3from typing import Any
5from lintro.formatters.core.format_registry import OutputStyle
7# Try to import tabulate
8try:
9 from tabulate import tabulate
11 TABULATE_AVAILABLE = True
12except ImportError:
13 TABULATE_AVAILABLE = False
16class GridStyle(OutputStyle):
17 """Output format that renders data as a formatted grid table.
19 This style creates a nicely formatted table with proper column alignment
20 and borders, similar to what you might see in a terminal or console.
21 """
23 def format(
24 self,
25 columns: list[str],
26 rows: list[list[Any]],
27 tool_name: str | None = None,
28 **kwargs: Any,
29 ) -> str:
30 """Format a table given columns and rows as a grid.
32 Args:
33 columns: List of column header names.
34 rows: List of row values (each row is a list of cell values).
35 tool_name: Optional tool name to include in context.
36 **kwargs: Extra options ignored by this formatter.
38 Returns:
39 Formatted data as grid table string.
40 """
41 if not rows:
42 return ""
44 # Use tabulate if available
45 if TABULATE_AVAILABLE:
46 # Provide sane defaults for alignment and column widths to avoid
47 # terminal wrapping that misaligns the grid. We keep most columns
48 # left-aligned, numeric columns right-aligned, and cap wide
49 # columns like File/Message.
50 colalign_map = {
51 "Line": "right",
52 "Column": "right",
53 "Fixable": "center",
54 }
55 colalign = [colalign_map.get(col, "left") for col in columns]
57 # Cap very wide columns so tabulate wraps within cells, preserving
58 # alignment instead of letting the terminal wrap mid-grid.
59 width_map: dict[str, int] = {
60 "File": 48,
61 "Message": 64,
62 "Code": 12,
63 "Line": 8,
64 "Column": 8,
65 "Fixable": 8,
66 "Docs": 52,
67 }
68 maxcolwidths = [width_map.get(col) for col in columns]
70 return tabulate(
71 tabular_data=rows,
72 headers=columns,
73 tablefmt="grid",
74 stralign="left",
75 numalign="right",
76 colalign=colalign,
77 maxcolwidths=maxcolwidths,
78 disable_numparse=True,
79 )
81 # Fallback to simple format when tabulate is not available
82 if not columns:
83 return ""
85 # Build the header
86 header = " | ".join(columns)
87 separator = "-" * len(header)
89 # Build the rows
90 formatted_rows = []
91 for row in rows:
92 # Ensure row has same number of elements as columns
93 padded_row = row + [""] * (len(columns) - len(row))
94 formatted_rows.append(" | ".join(str(cell) for cell in padded_row))
96 # Combine all parts
97 result = [header, separator] + formatted_rows
98 return "\n".join(result)