feat: data_models 扩展 MixedParagraph/MixedSheet(段落容器)
This commit is contained in:
@@ -33,3 +33,4 @@
|
||||
|
||||
| 2026-08-09 03:30 | 整体迭代 | 里程碑2 最终评审修正(must-fix x2):① find_header_row 结果未传入 extract_table(恒 header_row=0,标题行置上的 sheet 会损坏表头)→ excel_parser.py 结构化路径改用 find_header_row(filled) 并 <0 回落 0;② cell_formatting 死代码(CellValue.formatting 恒 None,取消线/背景色到不了下游)→ extract_table 新增可选 formatting_map 参数,excel_parser 遍历 ws.iter_rows 构建 fmt_map 传入。tests/test_excel_parser.py 新增 2 用例(标题行表头定位、strikethrough 回填);pytest 全量 41 passed | src/genesis/parsers/excel_parser.py, src/genesis/parsers/table_extractor.py, tests/test_excel_parser.py | deepseek-v4-flash-free |
|
||||
| 2026-08-09 03:59 | Agent 实现 | 里程碑2.5 Task9 实现:段落分割器 split_paragraphs(MIXED 完整段落解析第一步,纯函数)。新建 src/genesis/parsers/paragraph_splitter.py(_is_blank_row 行空白判定 + split_paragraphs(matrix)→list[(start,end)] 含端点 0-based,以全空行为界返回段落区间,空矩阵→[])与 tests/test_paragraph_splitter.py(5 用例:空矩阵/单段落无空行/中间空行分割/尾部空行不产生多余段落/前导空行从首个非空行开始);TDD 验证 RED(ModuleNotFoundError: No module named 'genesis.parsers.paragraph_splitter')→ GREEN(5 passed);pytest 全量 46 passed(41 baseline + 5 新增);不依赖 openpyxl 与 data_models;提交 34ef28b | src/genesis/parsers/paragraph_splitter.py, tests/test_paragraph_splitter.py | deepseek-v4-flash-free |
|
||||
| 2026-08-09 04:20 | Agent 实现 | 里程碑2.5 Task10 实现:data_models 扩展 MixedParagraph/MixedSheet 段落容器,并新增 ExcelParseResult.mixed 字段(默认空列表)。TDD:先追加 3 个测试(字段存在性与默认行为)确认 RED(ImportError: cannot import name 'MixedParagraph'),再在 data_models.py 末尾追加两个 dataclass(顶部 from typing 加 Literal、dataclasses 加 field),excel_parser.py 更新导入并为 ExcelParseResult 加 mixed 字段,确认 GREEN(3 passed),全量 pytest 49 passed(46 baseline + 3)。未修改既有类与字段,仅追加。 | src/genesis/data_models.py, src/genesis/parsers/excel_parser.py, tests/test_excel_parser.py | deepseek-v4-flash-free |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
from typing import Any, Literal
|
||||
|
||||
|
||||
class SheetType(Enum):
|
||||
@@ -222,4 +222,21 @@ class StructuredSource:
|
||||
rule_docs: list[RuleDocument]
|
||||
image_analyses: list[ImageAnalysis]
|
||||
existing_system: ExistingSystemInfo | None
|
||||
comments: list[CellComment]
|
||||
comments: list[CellComment]
|
||||
|
||||
|
||||
@dataclass
|
||||
class MixedParagraph:
|
||||
"""混合 sheet 的一个段落(表格或自由文本)"""
|
||||
kind: Literal["table", "free_text"]
|
||||
matrix: list[list[Any]] | None = None # 该段原始矩阵(调试/重现)
|
||||
table: ExcelTable | None = None # kind="table" 时填充
|
||||
text: str | None = None # kind="free_text" 时填充(段全文)
|
||||
source_range: tuple[int, int] | None = None # (first_row, last_row) 矩阵 0-based
|
||||
|
||||
|
||||
@dataclass
|
||||
class MixedSheet:
|
||||
"""混合 sheet 的段落集合"""
|
||||
name: str
|
||||
paragraphs: list[MixedParagraph] = field(default_factory=list)
|
||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
from genesis.data_models import CellComment, ExcelTable
|
||||
from genesis.data_models import CellComment, ExcelTable, MixedSheet
|
||||
from genesis.parsers.excel_reader import open_workbook, sheet_matrix
|
||||
from genesis.parsers.sheet_detector import detect_sheet_type
|
||||
from genesis.parsers.sheet_nature import SheetNature, classify_sheet, find_header_row
|
||||
@@ -19,6 +19,7 @@ class ExcelParseResult:
|
||||
tables: list[ExcelTable] = field(default_factory=list)
|
||||
comments: list[CellComment] = field(default_factory=list)
|
||||
skipped: list[str] = field(default_factory=list)
|
||||
mixed: list[MixedSheet] = field(default_factory=list)
|
||||
|
||||
|
||||
class ExcelParser:
|
||||
|
||||
@@ -57,3 +57,27 @@ def test_parse_attaches_strikethrough_formatting(tmp_path):
|
||||
cv = result.tables[0].rows[0]["機能ID"]
|
||||
assert cv.formatting is not None
|
||||
assert cv.formatting.strikethrough is True
|
||||
|
||||
|
||||
from genesis.data_models import MixedParagraph, MixedSheet
|
||||
from genesis.parsers.excel_parser import ExcelParseResult
|
||||
|
||||
|
||||
def test_excel_parse_result_has_mixed_default():
|
||||
r = ExcelParseResult(file_name="f.xlsx")
|
||||
assert r.mixed == []
|
||||
|
||||
|
||||
def test_mixed_paragraph_defaults():
|
||||
p = MixedParagraph(kind="table")
|
||||
assert p.table is None
|
||||
assert p.text is None
|
||||
assert p.source_range is None
|
||||
|
||||
|
||||
def test_mixed_sheet_holds_paragraphs():
|
||||
p1 = MixedParagraph(kind="table")
|
||||
p2 = MixedParagraph(kind="free_text", text="备注")
|
||||
ms = MixedSheet(name="混合", paragraphs=[p1, p2])
|
||||
assert ms.name == "混合"
|
||||
assert [p.kind for p in ms.paragraphs] == ["table", "free_text"]
|
||||
|
||||
Reference in New Issue
Block a user