Coverage for src\genesis\parsers\sheet_nature.py: 100%
29 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 14:20 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 14:20 +0800
1from __future__ import annotations
3from enum import Enum
4from typing import Any
7class SheetNature(Enum):
8 TABLE = "table"
9 FREE_TEXT = "free_text"
10 MIXED = "mixed"
13def _non_empty(row: list[Any]) -> list[Any]:
14 return [c for c in row if c is not None and str(c).strip() != ""]
17def find_header_row(matrix: list[list[Any]]) -> int:
18 for i, row in enumerate(matrix):
19 if len(_non_empty(row)) >= 2:
20 return i
21 return -1
24def _free_text_like(matrix: list[list[Any]]) -> bool:
25 if not matrix:
26 return True
27 max_cols = max((len(row) for row in matrix), default=0)
28 if max_cols <= 1:
29 return True
30 non_empty_rows = [r for r in matrix if _non_empty(r)]
31 if len(non_empty_rows) / len(matrix) < 0.7:
32 return True
33 return find_header_row(matrix) == -1
36def classify_sheet(matrix: list[list[Any]]) -> SheetNature:
37 if _free_text_like(matrix):
38 return SheetNature.FREE_TEXT
39 header_row = find_header_row(matrix)
40 if header_row >= 0: # pragma: no cover — _free_text_like()==False 时 find_header_row 恒 ≥0
41 for row in matrix[header_row + 1:]:
42 if any(str(c).strip().startswith(("・", "■")) for c in _non_empty(row)):
43 return SheetNature.MIXED
44 return SheetNature.TABLE