Fix/export bug#101
Merged
Merged
Conversation
- CONFIG_PATH 与 NODE_TYPE 相同时自动回退,删除 8 个冗余声明 - FormatNode.load_config 合并到 TreeNode.load_config(消除重复) - 删除死代码 load_yaml_config 及无用 import - 新增 @register 装饰器,替代手动维护 CATEGORY_TO_CLASS/LEVEL_MAP - 修复 _write_comment_groups 中重复统计 bug
核心变更: - 每个 FormatNode 子类声明 DEFAULTS 字典代替 Pydantic 模型 - load_config 合并 DEFAULTS + YAML → DotDict(保留 cfg.alignment 点号访问) - 删除 CONFIG_MODEL、CONFIG_PATH、FormatNode 泛型参数 - 删除 BaseHeadingNode/BaseKeywordsNode 自定义 load_config - config/loader.py 直接返回 dict(不再依赖 Pydantic 验证) - NodeConfigRoot 改为 dict 包装器(向后兼容) - 新增 BASE_FORMAT 共享默认值、@register 自动注册装饰器 剩余:68 个测试失败,主要是直接构造 Pydantic 模型的测试断言需更新
- TestLoadConfig → 测试实际配置值(不再检查 _pydantic_config) - 删除测试已移除行为的测试(TypeError、ValueError) - DotDict.__getattr__ 缺失 key 返回 None(更安全) - 修复 node.py handler 检查方式(hasattr → is None) 41/953 失败,大部分是 KeywordsCoverageBoost 和 Caption 测试
- 938 passed, 3 failed(均为预先存在的 bug,与本次改动无关) - 测试不再依赖 Pydantic 模型实例 - DotDict.__getattr__ 缺失 key 返回 None(安全默认值) - NodeConfigRoot 支持 __getattr__ 点号访问(向后兼容) - 修复 caption.py numbering_cfg 兼容 dict/DotDict - 修复 pipeline numbering 字段缺失
- models.py 精简至 NodeConfigRoot + 编号兼容层(49行 vs 500行) - 删除 TestDataModelValidation(测试已移除的 Pydantic 验证) - 测试中所有 Pydantic 模型构造替换为 NodeConfigRoot/dict - numbering.py isinstance 检查改为 dict 检查 - 932 passed, 2 failed(预存 bug)
- registry.py 新增 export_defaults(),遍历所有 @register 类 按 NODE_TYPE 路径重建完整 YAML 配置树 - CLI `wordf config -o` 改用 export_defaults() 导出 - 消除各文件中重复的 _BASE/_KW/_H/_ACK/_REF_BASE, 统一用 dotdict.BASE_FORMAT - 修复测试 YAML 缺失字段(font_color, english_font_name 等) - 934 passed, 0 failed
_show_config() 改用 export_defaults() + yaml.dump, 遍历所有注册类打印完整字段和默认值。
test_rules.py (1288行) → 8 个文件: - test_node.py (298行): FormatNode 基类测试 - test_abstract.py (443行): 摘要相关节点测试 - test_heading.py (265行): 标题节点测试 - test_keywords.py (178行): 关键词节点测试 - test_body.py (194行): 正文节点测试 - test_caption.py (152行): 题注节点测试 - test_references.py (178行): 参考文献节点测试 - test_acknowledgement.py (202行): 致谢节点测试 934 passed, 0 failed
- rules/ 子目录: test_abstract, test_acknowledgement, test_body, test_caption, test_heading, test_keywords, test_node, test_references - style/ 子目录: test_defs, test_diff, test_reader, test_writer - api/, classify/ 子目录 - test_integration.py, test_coverage_boost.py 待后续拆分 - 943 passed, 0 failed
- rules/ 子目录: 8 个文件对应 rules/*.py - style/ 子目录: 4 个文件对应 style/*.py - api/, classify/, utils/ 子目录 - 新增 tests/utils/test_text.py(罗马数字、中文数字、题注解析) - 976 passed, 0 failed - test_coverage_boost, test_caption_numbering, test_integration 暂保持独立 待后续拆入 pipeline/, agent/, config/, structure/ 子目录
已迁移到子目录: - rules/: test_abstract, test_acknowledgement, test_body, test_caption, test_heading, test_keywords, test_node, test_references - style/: test_defs, test_diff, test_reader, test_writer - api/: test_api - classify/: test_tag 保持在根目录(自包含、待后续清理): - test_integration.py, test_coverage_boost.py - test_caption_numbering.py, test_numbering.py - test_tree.py, test_utils.py 943 passed, 0 failed
- config/loader.py: LazyConfig 改为普通类(移除 __new__ 单例), 每个实例独立加载;测试可创建独立实例避免全局状态污染 - style/diff.py: 模块变量 style_checks_warning 改为 _warnings_cache 懒加载,_load_warnings() 处理配置未加载的情况 - conftest.py: 更新 reset_style_warning fixture - 943 passed, 0 failed
…ption - tests/utils/test_text.py (186行): FromRoman, FromChineseNum, ParseCaptionText 零外部依赖,只 import wordformat.utils 的三个函数 - tests/rules/test_caption.py (778行): 合并题注格式测试 + 编号集成测试 - 删除 test_caption_numbering.py - 943 passed, 0 failed
- test_tree.py: +TestDotDict (5测) +TestExportDefaults (1测) - rules/test_caption.py: +TestCaptionEdgeCases (3测) +TestNodeConfigRoot (3测) - 覆盖 dotdict.__delattr__, deep_merge, export_defaults, NodeConfigRoot.__setattr__/__getattr__, caption 边界分支
- CLAUDE.md: 更新架构描述(移除 set_style/set_tag/datamodel/word_structure 等过期引用), 测试文件路径(test_rules.py → rules/*.py),覆盖阈值(85→87%), FormatNode 子类模式(移除 CONFIG_MODEL/CONFIG_PATH,添加 DEFAULTS/@register) - docs/usage.md: 修正 Python API import 路径 (wordformat.set_tag → wordformat.classify.tag, wordformat.set_style → wordformat.pipeline.orchestrate) - docs/configuration.md: 修正配置验证说明(移除 Pydantic 字段校验, 改为 YAML 语法校验 + wordf config -o 导出)
- _color_last_comment: 修复 Comments 对象不支持下标的问题, 改用 _comments_elm XML 树找最后一条批注 - _write_comment_groups: 严重→红(FF0000),提醒→蓝(0000FF),一般→默认黑 - FigureImage.DEFAULTS: 补 alignment + first_line_indent 默认值, 兜底 None → "居中对齐"/"0字符"
- 严重度合并为两档:错误(红 FF0000) / 提醒(蓝 0000FF) - 新增 add_styled_comment/apply_run_style/split_comment_line 接口,可单独设置批注片段样式 - 移除事后改 XML 的 _color_last_comment,改用 python-docx Comment run API
新增 style/inheritance.py:按 OOXML 五层链(直接格式→字符样式→段落样式 basedOn 链→docDefaults→主题字体)解析有效格式,提取器注册表可扩展。 所有 reader getter 委托 resolver,删除各处手写 base_style 循环与 _get_style_spacing / _get_with_style_fallback。 修复 run 级 bold/italic/underline/字体/字号此前只读直接格式、漏样式继承 导致的标题类误报。行为变化:空 run 字号 12.0→11.0(docDefaults)、 英文字体 None→主题字体。 新增 tests/style/test_inheritance.py(33 例);删除针对已移除内部函数的 旧用例,行为变化用例改用真实 basedOn 链。959 passed,覆盖率 87.67%。
- inheritance.py: run 提取器改用 CT_RPr 类型化子元素(.b/.i/.u/.sz/.color/
.style),主题命名空间用 qn("a:*"),parse_xml 替代裸 lxml,
Mock 守卫改用 BaseOxmlElement
- reader.py: 元素守卫改用 BaseOxmlElement
- hyperlinks.py: 超链接属性用 CT_Hyperlink 的 .anchor/.history 描述符
- body.py: w:vertAlign 手工增删改用 Font.superscript / CT_RPr.superscript
东亚/主题字体(CT_Fonts 未建模)、CJK 单位(行/字符)、szCs/bCs 伴随元素、
自动编号生成等 python-docx 覆盖不到的部分保持裸 XML。959 passed。
- config/loader: LazyConfig 类简化为 load_config + get_config 两个函数 - diff.py: _WARNING_DEFAULTS 改为 WarningConfig dataclass,registry.py 从此导出 - diff.py: _char/_para_warning_enabled 合并为 _warning_enabled,warnings 注入 to_string - stages.py: _fix_style_* 优先使用 Style.font / Style.paragraph_format API - writer.py: SetSpacing.set_hang() 用 get_or_add_pPr() 替代 parse_xml - comments.py: para.clear() 替代 XML 元素逐个删除 - units.py: convert_to_emu 用 docx.shared 替代手写 EMU 换算 - defs.py: UnitLabelEnum 通过 _meta_funcs 非空自动判断是否 split_unit;FontSize 覆盖 rel_value - defs.py: LineSpacingRule / Alignment 加 _LABEL_MAP_REVERSE,diff.py 不再硬编码标签映射 - inheritance.py: 全部函数补 docstring - reader.py: _para/_run/_run_font 内部函数补 docstring
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 关联 Issue
🎯 变更概述
受影响的用户场景
具体变更点
迁移建议
是否提供自动迁移工具?
scripts/migrate_v02_to_v03.py)✅ 提交前自查清单
🔹 测试保障
make test(或等效命令)tests/目录)io.BytesIO,未保存任何临时.docx文件到磁盘🔹 配置与兼容性
example/中提供示例requirements.txt或pyproject.toml已更新)🔹 文档与示例
README.md已更新(如新增功能说明、命令参数)example/)能正常运行且反映最新能力python-docx底层操作的部分)🔹 安全与资源
pickle、yaml.load未指定Loader)🔹 其他
master切出,无无关提交feat: add table caption check)