athena-python-docx 0.21.1__tar.gz → 0.21.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/PKG-INFO +1 -1
  2. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/__init__.py +1 -1
  3. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_buffer.py +6 -4
  4. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_citations.py +5 -0
  5. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/table.py +87 -32
  6. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/pyproject.toml +1 -1
  7. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/firm_templates/test_pw_corpus.py +2 -14
  8. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_citations.py +1 -0
  9. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_positional_cell_id.py +142 -0
  10. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_ptc.py +35 -0
  11. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/uv.lock +1 -1
  12. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/.gitignore +0 -0
  13. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/CLAUDE.md +0 -0
  14. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/DOCX_EXEC_LAB.md +0 -0
  15. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/README.md +0 -0
  16. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_athena_extension.py +0 -0
  17. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_batching.py +0 -0
  18. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_execution.py +0 -0
  19. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_http.py +0 -0
  20. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_http_doc.py +0 -0
  21. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_image_utils.py +0 -0
  22. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_postproc.py +0 -0
  23. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_ptc.py +0 -0
  24. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_references.py +0 -0
  25. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_table_styles.py +0 -0
  26. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/_timeouts.py +0 -0
  27. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/api.py +0 -0
  28. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/bookmarks.py +0 -0
  29. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/charts.py +0 -0
  30. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/client.py +0 -0
  31. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/commands.py +0 -0
  32. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/comments.py +0 -0
  33. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/document.py +0 -0
  34. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/enum/__init__.py +0 -0
  35. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/enum/section.py +0 -0
  36. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/enum/shape.py +0 -0
  37. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/enum/style.py +0 -0
  38. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/enum/table.py +0 -0
  39. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/enum/text.py +0 -0
  40. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/errors.py +0 -0
  41. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/exceptions.py +0 -0
  42. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/fields.py +0 -0
  43. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/footnotes.py +0 -0
  44. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/math.py +0 -0
  45. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/opc/__init__.py +0 -0
  46. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/opc/coreprops.py +0 -0
  47. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/oxml/__init__.py +0 -0
  48. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/revisions.py +0 -0
  49. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/sdt.py +0 -0
  50. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/section.py +0 -0
  51. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/session.py +0 -0
  52. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/settings.py +0 -0
  53. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/shape.py +0 -0
  54. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/shared.py +0 -0
  55. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/styles/__init__.py +0 -0
  56. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/styles/style.py +0 -0
  57. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/styles/styles.py +0 -0
  58. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/__init__.py +0 -0
  59. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/font.py +0 -0
  60. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/hyperlink.py +0 -0
  61. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/pagebreak.py +0 -0
  62. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/paragraph.py +0 -0
  63. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/parfmt.py +0 -0
  64. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/run.py +0 -0
  65. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/text/tabstops.py +0 -0
  66. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/toc.py +0 -0
  67. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/docx/typing.py +0 -0
  68. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/docx_exec_lab.py +0 -0
  69. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  70. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  71. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/docx_exec_lab_server.py +0 -0
  72. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/dump_wire_fixtures.py +0 -0
  73. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/publish.sh +0 -0
  74. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/release.sh +0 -0
  75. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/round_trip_smoke.py +0 -0
  76. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/smoke_test_block_not_found.py +0 -0
  77. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/scripts/validate_find_replace_asset.py +0 -0
  78. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/__init__.py +0 -0
  79. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/conftest.py +0 -0
  80. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/METHODOLOGY.md +0 -0
  81. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/README.md +0 -0
  82. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/__init__.py +0 -0
  83. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/ab_probe_cases.py +0 -0
  84. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/ab_probe_runner.py +0 -0
  85. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/auto_gen_cases.py +0 -0
  86. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/binary_round_trip.py +0 -0
  87. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/cases.py +0 -0
  88. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/complex_cases.py +0 -0
  89. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/coverage_report.py +0 -0
  90. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/extract.py +0 -0
  91. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/extreme_cases.py +0 -0
  92. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/fake_session.py +0 -0
  93. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/firm_templates/README.md +0 -0
  94. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/firm_templates/__init__.py +0 -0
  95. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/firm_templates/_runner.py +0 -0
  96. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/firm_templates/extractor.py +0 -0
  97. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  98. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/local_runner.py +0 -0
  99. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/mega_cases.py +0 -0
  100. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshot.py +0 -0
  101. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  102. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  103. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  104. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  105. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  106. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  107. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  108. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  109. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  110. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  111. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  112. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  113. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  114. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  115. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  116. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  117. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  118. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  119. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  120. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  121. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  122. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  123. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  124. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  125. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  126. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  127. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  128. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  129. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  130. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  131. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  132. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  133. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  134. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  135. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  136. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  137. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  138. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  139. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  140. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  141. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  142. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  143. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  144. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  145. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  146. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  147. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  148. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  149. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  150. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  151. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  152. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  153. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  154. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  155. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  156. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  157. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  158. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  159. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  160. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  161. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  162. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  163. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  164. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  165. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  166. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  167. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  168. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  169. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  170. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  171. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  172. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  173. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  174. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  175. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  176. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  177. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  178. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  179. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  180. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  181. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  182. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  183. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  184. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  185. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  186. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  187. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  188. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  189. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  190. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  191. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  192. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  193. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  194. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  195. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  196. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  197. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  198. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  199. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  200. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  201. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  202. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  203. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  204. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  205. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  206. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  207. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  208. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  209. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  210. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  211. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  212. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  213. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  214. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  215. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  216. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  217. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  218. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  219. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  220. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  221. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  222. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  223. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  224. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  225. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  226. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  227. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  228. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  229. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  230. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  231. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  232. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  233. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  234. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  235. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  236. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  237. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  238. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  239. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  240. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  241. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  242. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  243. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  244. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  245. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  246. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  247. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  248. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/ours_spec.json +0 -0
  249. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/parity_crawl.py +0 -0
  250. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/parity_diff.json +0 -0
  251. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/real_world_cases.py +0 -0
  252. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/round_trip_tests.py +0 -0
  253. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/stock_spec.json +0 -0
  254. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/fidelity/test_e2e_against_staging.py +0 -0
  255. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/README.md +0 -0
  256. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/__init__.py +0 -0
  257. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/baseline_gaps.json +0 -0
  258. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/compare.py +0 -0
  259. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/intentional_deviations.json +0 -0
  260. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/introspect.py +0 -0
  261. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  262. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/reports/gap_report.json +0 -0
  263. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/run_parity.py +0 -0
  264. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/snapshots/athena_latest.json +0 -0
  265. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  266. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/parity/test_parity_gap.py +0 -0
  267. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_add_section_extract_items.py +0 -0
  268. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_athena_extensions_contract.py +0 -0
  269. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_athena_extensions_registry.py +0 -0
  270. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_batching_perf.py +0 -0
  271. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_block_not_found_error.py +0 -0
  272. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_buffer.py +0 -0
  273. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  274. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_add_table_not_supported.py +0 -0
  275. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  276. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  277. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_inner_format_stash.py +0 -0
  278. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_inner_run_format_stash.py +0 -0
  279. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_inner_run_guard.py +0 -0
  280. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_text_plain_fastpath.py +0 -0
  281. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_cell_text_replace_semantics.py +0 -0
  282. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_collapsed_range_format.py +0 -0
  283. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_command_dataclasses.py +0 -0
  284. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_commands.py +0 -0
  285. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_comments.py +0 -0
  286. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_document_asset_id_property.py +0 -0
  287. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_document_clear.py +0 -0
  288. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_document_create.py +0 -0
  289. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_document_create_from_template.py +0 -0
  290. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_document_factory_validation.py +0 -0
  291. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_docx_exec_lab.py +0 -0
  292. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_docx_exec_lab_server.py +0 -0
  293. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_e2e_partial_failure_cascade.py +0 -0
  294. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_execution_scope.py +0 -0
  295. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_find_replace_session_open.py +0 -0
  296. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_http_transport.py +0 -0
  297. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_hyperlink_coalescing.py +0 -0
  298. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_image_url_data_uri.py +0 -0
  299. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_insert_deferred.py +0 -0
  300. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_iter_inner_content.py +0 -0
  301. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_list_styles.py +0 -0
  302. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_merged_cell_secondary_slot.py +0 -0
  303. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_merged_cells.py +0 -0
  304. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_oxml_shim.py +0 -0
  305. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_paragraph_text_len_cache.py +0 -0
  306. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_parity_misc.py +0 -0
  307. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_parity_round2.py +0 -0
  308. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_partial_failure_cascade.py +0 -0
  309. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_phase_a_behavior.py +0 -0
  310. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_phase_b_headers_footers.py +0 -0
  311. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_phase_c_tables.py +0 -0
  312. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_postproc_cell_format_rewrite.py +0 -0
  313. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  314. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_postproc_ref_restore.py +0 -0
  315. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_pr19766_review_fixes.py +0 -0
  316. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_python_docx_api_parity.py +0 -0
  317. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_revisions.py +0 -0
  318. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  319. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_add_picture.py +0 -0
  320. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_add_run.py +0 -0
  321. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  322. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_comments_add_comment.py +0 -0
  323. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_comments_get.py +0 -0
  324. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_document_audit.py +0 -0
  325. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_document_element.py +0 -0
  326. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_enum_section.py +0 -0
  327. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_font_audit.py +0 -0
  328. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_header_footer.py +0 -0
  329. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_hyperlink.py +0 -0
  330. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_inline_shape.py +0 -0
  331. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  332. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_misc.py +0 -0
  333. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_paragraph_strict.py +0 -0
  334. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_paragraph_style.py +0 -0
  335. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  336. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_parfmt.py +0 -0
  337. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_row_col_cell.py +0 -0
  338. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_run_add_break.py +0 -0
  339. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_run_bool_setters.py +0 -0
  340. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_run_style.py +0 -0
  341. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_run_style_strict.py +0 -0
  342. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_run_text.py +0 -0
  343. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_run_underline.py +0 -0
  344. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_section_audit.py +0 -0
  345. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_section_dimensions.py +0 -0
  346. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_section_onoff.py +0 -0
  347. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_settings.py +0 -0
  348. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_shared_audit.py +0 -0
  349. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_style.py +0 -0
  350. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_styles.py +0 -0
  351. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_table_audit.py +0 -0
  352. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_table_cell.py +0 -0
  353. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_table_dimensions.py +0 -0
  354. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_silent_stub_table_layout.py +0 -0
  355. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_smoke_integration.py +0 -0
  356. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_style_acceptance.py +0 -0
  357. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_style_font.py +0 -0
  358. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_style_setters_contract.py +0 -0
  359. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_table_set_cell_perf.py +0 -0
  360. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_table_style_id_resolution.py +0 -0
  361. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_temporarily_unavailable.py +0 -0
  362. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_validate_find_replace_asset_script.py +0 -0
  363. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_wire_contract.py +0 -0
  364. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_xml_attr_guard.py +0 -0
  365. {athena_python_docx-0.21.1 → athena_python_docx-0.21.3}/tests/test_zod_wire_contract.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: athena-python-docx
3
- Version: 0.21.1
3
+ Version: 0.21.3
4
4
  Summary: Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack
5
5
  Project-URL: Homepage, https://athenaintelligence.ai
6
6
  Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
@@ -6,7 +6,7 @@ See CLAUDE.md for the API parity contract.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.21.1"
9
+ __version__ = "0.21.3"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import flush_all
@@ -124,10 +124,12 @@ if TYPE_CHECKING:
124
124
  # HTTP POST to agora (see ``_ptc._send``), so emitting one card per low-level
125
125
  # mutation produces hundreds of sub-cards per script and pays full network
126
126
  # RTT on every one. The allow-list keeps the per-action signal — one card
127
- # per logical block creation (paragraph, heading, table) — without the spam
128
- # or the cumulative latency. Asset-level creation events (``CreateDocument``)
129
- # are emitted from ``Document.create`` directly, not through this buffer path.
130
- _PTC_EMIT_TOOLS: frozenset[str] = frozenset({"CreateParagraph", "CreateHeading", "CreateTable"})
127
+ # per logical block/citation creation — without the spam or the cumulative
128
+ # latency. Asset-level creation events (``CreateDocument``) are emitted from
129
+ # ``Document.create`` directly, not through this buffer path.
130
+ _PTC_EMIT_TOOLS: frozenset[str] = frozenset(
131
+ {"CreateParagraph", "CreateHeading", "CreateTable", "AddCitation"}
132
+ )
131
133
 
132
134
 
133
135
  def _should_emit_ptc(cmd: Command) -> bool:
@@ -53,6 +53,11 @@ def normalize_citation_string(citation_string: str) -> str:
53
53
 
54
54
  if not parsed.scheme and value.startswith("/"):
55
55
  relative = urlparse(value)
56
+ if relative.netloc:
57
+ raise ValueError(
58
+ "protocol-relative Athena Spaces citation URLs are not allowed; "
59
+ "use an absolute Athena host"
60
+ )
56
61
  if relative.path.rstrip("/") == "/dashboard/spaces":
57
62
  asset_ids = parse_qs(relative.query).get("asset_ids")
58
63
  if asset_ids and asset_ids[0]:
@@ -108,6 +108,37 @@ def _normalize_border_spec(spec: "dict | str | None", *, edge: str) -> "dict | N
108
108
  )
109
109
 
110
110
 
111
+ def _table_node_id_from_item(item: object) -> str | None:
112
+ if not isinstance(item, dict):
113
+ return None
114
+ addr = item.get("address")
115
+ if isinstance(addr, dict):
116
+ nid = addr.get("nodeId")
117
+ if isinstance(nid, str) and nid:
118
+ return nid
119
+ nid = item.get("nodeId")
120
+ if isinstance(nid, str) and nid:
121
+ return nid
122
+ return None
123
+
124
+
125
+ def _table_items_from_blocks_list_result(result: object) -> list[dict]:
126
+ if isinstance(result, dict):
127
+ blocks_obj: object = result.get("blocks", [])
128
+ blocks = blocks_obj if isinstance(blocks_obj, list) else []
129
+ elif isinstance(result, list):
130
+ blocks = result
131
+ else:
132
+ blocks = []
133
+ return [
134
+ block
135
+ for block in blocks
136
+ if isinstance(block, dict)
137
+ and block.get("nodeType") == "table"
138
+ and _table_node_id_from_item(block)
139
+ ]
140
+
141
+
111
142
  if TYPE_CHECKING:
112
143
  from docx.client import Session
113
144
  from docx.enum.table import (
@@ -474,25 +505,33 @@ class Table:
474
505
  return self._node_id, info
475
506
  except Exception:
476
507
  pass
477
- # Fallback: scan top-level tables via doc.find. The find result is
478
- # in document order, so a Table created by ``Document.add_table``
479
- # — which always appends to ``documentEnd`` — can be located by
480
- # its stored ``_doc_index`` (the position it had at creation
481
- # time, captured from the in-session counter at append time).
482
- # That preserves the 1:1 mapping between proxy and server table
483
- # across rotations, instead of the pre-0.11.4 "take the last
484
- # item" heuristic that collapsed N rotated proxies onto one
485
- # target.
486
- find_result: object = run_sync(
487
- self._session.doc.find({"type": "table"}),
488
- )
489
- items_obj: object = find_result.get("items", []) if isinstance(find_result, dict) else []
490
- items: list = items_obj if isinstance(items_obj, list) else []
508
+ # Fallback: scan top-level tables in document order. Prefer
509
+ # ``blocks.list`` because docx-editor supports it on the same engine
510
+ # path used by ``Document.tables``; ``doc.find({"type": "table"})`` is
511
+ # not implemented by older docx-editor appliers and caused immediate
512
+ # failures when agents styled a freshly-created table cell. Keep
513
+ # ``doc.find`` only as a compatibility fallback for transports that
514
+ # do not expose ``blocks.list``.
515
+ items: list = []
516
+ try:
517
+ blocks_result: object = run_sync(
518
+ self._session.doc.blocks.list(
519
+ {"nodeTypes": ["table"], "includeText": False},
520
+ ),
521
+ )
522
+ items = _table_items_from_blocks_list_result(blocks_result)
523
+ except Exception as exc: # noqa: BLE001
524
+ _log_debug(f"table rotation lookup via blocks.list failed: {type(exc).__name__}: {exc}")
525
+ if not items:
526
+ find_result: object = run_sync(
527
+ self._session.doc.find({"type": "table"}),
528
+ )
529
+ items_obj: object = find_result.get("items", []) if isinstance(find_result, dict) else []
530
+ raw_items: list = items_obj if isinstance(items_obj, list) else []
531
+ items = [item for item in raw_items if isinstance(item, dict)]
491
532
  for item in items:
492
- if not isinstance(item, dict):
493
- continue
494
- addr = item.get("address", {})
495
- if isinstance(addr, dict) and addr.get("nodeId") == self._node_id:
533
+ nid = _table_node_id_from_item(item)
534
+ if nid == self._node_id:
496
535
  info_obj = run_sync(
497
536
  self._session.doc.tables.get({"nodeId": self._node_id}),
498
537
  )
@@ -522,17 +561,15 @@ class Table:
522
561
  ):
523
562
  pos = len(items) - session_count + self._doc_index
524
563
  cand = items[pos]
525
- if isinstance(cand, dict):
526
- ca = cand.get("address", {})
527
- if isinstance(ca, dict) and ca.get("nodeId"):
528
- rotated_addr = ca
564
+ cand_id = _table_node_id_from_item(cand)
565
+ if cand_id:
566
+ rotated_addr = {"nodeId": cand_id}
529
567
  elif len(items) == 1:
530
568
  # Unambiguous: only one table in the doc.
531
569
  cand = items[0]
532
- if isinstance(cand, dict):
533
- ca = cand.get("address", {})
534
- if isinstance(ca, dict) and ca.get("nodeId"):
535
- rotated_addr = ca
570
+ cand_id = _table_node_id_from_item(cand)
571
+ if cand_id:
572
+ rotated_addr = {"nodeId": cand_id}
536
573
  else:
537
574
  # Multi-table doc, ``_doc_index`` unknown (proxy resolved
538
575
  # via iteration / find rather than ``Document.add_table``)
@@ -1504,11 +1541,13 @@ class _Cell:
1504
1541
 
1505
1542
  Reads the proxy's stored ``_node_id`` with NO round-trip. DOCX Studio
1506
1543
  tables carry real (non-``t:N``) node ids → returns ``None`` so the
1507
- caller queries (DOCX Studio is pooled, so that read is cheap anyway). A
1508
- freshly-created docx-editor table still holds a client UUID until its
1509
- create flushes, so the first cell op falls back to the query (which
1510
- flushes + rotates ``_node_id`` to ``t:N``) and every subsequent cell
1511
- op fast-paths.
1544
+ caller queries (DOCX Studio is pooled, so that read is cheap anyway).
1545
+ A freshly-created docx-editor table still holds a client UUID until its
1546
+ create flushes. For docx-editor, :meth:`Document.add_table` already
1547
+ knows the table's eventual document-order index, so SDK-created body
1548
+ tables can fast-path before a fragile first ``tables.get_cells`` query.
1549
+ We first try to flush the pending create so DOCX Studio's non-positional
1550
+ table ids can still fall back to the query path after the id rewrite.
1512
1551
 
1513
1552
  Gated to a **known uniform grid**: the table must have been created
1514
1553
  via :meth:`Document.add_table` (so ``_doc_index`` is set and the full
@@ -1520,11 +1559,27 @@ class _Cell:
1520
1559
  fall back to the query path to stay address-correct.
1521
1560
  """
1522
1561
  table = self._table
1523
- if getattr(table, "_doc_index", None) is None or getattr(table, "_has_merges", False):
1562
+ doc_index = getattr(table, "_doc_index", None)
1563
+ if doc_index is None or getattr(table, "_has_merges", False):
1524
1564
  return None
1525
1565
  nid = getattr(table, "_node_id", None)
1526
1566
  if isinstance(nid, str) and nid.startswith("t:") and nid[2:].isdigit():
1527
1567
  return f"tc:{nid[2:]}:{self._row}:{self._col}"
1568
+ if (
1569
+ isinstance(nid, str)
1570
+ and nid.startswith("t_")
1571
+ and getattr(table, "_header_footer_ref_id", None) is None
1572
+ ):
1573
+ handle = getattr(table._session, "_doc_handle", None)
1574
+ buf = getattr(handle, "buffer", None) if handle is not None else None
1575
+ if buf is not None:
1576
+ buf.flush()
1577
+ nid = getattr(table, "_node_id", None)
1578
+ if isinstance(nid, str) and nid.startswith("t:") and nid[2:].isdigit():
1579
+ return f"tc:{nid[2:]}:{self._row}:{self._col}"
1580
+ if not (isinstance(nid, str) and nid.startswith("t_")):
1581
+ return None
1582
+ return f"tc:{doc_index}:{self._row}:{self._col}"
1528
1583
  return None
1529
1584
 
1530
1585
  def _cell_id(self) -> str:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-docx"
7
- version = "0.21.1"
7
+ version = "0.21.3"
8
8
  description = "Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -52,8 +52,7 @@ class CorpusDoc:
52
52
 
53
53
  # Per-doc captured scorecards. Captured 2026-05-17 from the corpus
54
54
  # source files via ``extractor.py``; these values pin the round-trip
55
- # output too (the bytes-in == bytes-out guarantee for everything
56
- # except Purchase_Agreement, which is xfailed below).
55
+ # output too (the bytes-in == bytes-out guarantee for everything).
57
56
  CORPUS: list[CorpusDoc] = [
58
57
  CorpusDoc(
59
58
  label="AI_Research_Digest",
@@ -246,15 +245,6 @@ CORPUS: list[CorpusDoc] = [
246
245
  paragraph_style_defs=119, character_style_defs=54,
247
246
  table_style_defs=2, custom_style_defs=118, image_files=0,
248
247
  ),
249
- xfail_reason=(
250
- "DOCX Studio § 18 strips REF field codes on import: 1989 → 1974 "
251
- "bookmarks (15 _9kMxxx co-author bookmarks dropped) AND every "
252
- "REF cross-reference's visible result text disappears, leaving "
253
- 'definitions like "Estimated Cash shall have the meaning set forth in" '
254
- "without their trailing Section reference. Pinned strict so a DOCX Studio "
255
- "fix surfaces as UNEXPECTED PASS. See docs/PW_CORPUS_FIDELITY_ASSESSMENT.md "
256
- "§ 3 and DOCX_STUDIO_LIMITATIONS.md § 18."
257
- ),
258
248
  ),
259
249
  ]
260
250
 
@@ -335,9 +325,7 @@ def test_round_trip_preserves_scorecard(
335
325
  ) -> None:
336
326
  """The DOCX Studio round-trip must preserve the per-doc scorecard.
337
327
 
338
- Docs in the ``xfail_reason`` regime are marked ``xfail(strict=True)``
339
- — currently only the Harvey Purchase Agreement, which loses all 301
340
- REF field result texts (see DOCX Studio upstream § 18).
328
+ Docs in the ``xfail_reason`` regime are marked ``xfail(strict=True)``.
341
329
  """
342
330
  # Make sure bun + corpus are available; otherwise skip with a clean
343
331
  # reason. ``require_case`` raises a pytest.skip on missing source.
@@ -279,6 +279,7 @@ def test_add_citation_rejects_non_reference_source() -> None:
279
279
  "mailto:source@example.com",
280
280
  "https://",
281
281
  "https://example.com/dashboard/spaces/?asset_ids=asset_pdf",
282
+ "//evil.com/dashboard/spaces/?asset_ids=asset_pdf",
282
283
  ):
283
284
  with pytest.raises(ValueError, match="citation_string|asset_ids|Athena host"):
284
285
  paragraph.add_citation(source) # type: ignore[arg-type]
@@ -19,6 +19,15 @@ address-correct.
19
19
  from __future__ import annotations
20
20
 
21
21
 
22
+ class _RecordingSession:
23
+ def __init__(self) -> None:
24
+ self.commands: list[object] = []
25
+
26
+ async def send_command(self, command: object) -> dict:
27
+ self.commands.append(command)
28
+ return {}
29
+
30
+
22
31
  class _CountingGetCells:
23
32
  """Async ``tables.get_cells`` stub that counts invocations."""
24
33
 
@@ -31,6 +40,42 @@ class _CountingGetCells:
31
40
  return {"cells": [{"nodeId": self._cell_id, "colspan": 1, "rowspan": 1}]}
32
41
 
33
42
 
43
+ class _CountingTablesGet:
44
+ """Async ``tables.get`` stub that records node-id lookups."""
45
+
46
+ def __init__(self, table_info_by_id: dict[str, dict] | None = None) -> None:
47
+ self.calls: list[dict] = []
48
+ self._table_info_by_id = table_info_by_id or {}
49
+
50
+ async def __call__(self, params: dict) -> dict:
51
+ self.calls.append(params)
52
+ node_id = params.get("nodeId")
53
+ if isinstance(node_id, str):
54
+ return self._table_info_by_id.get(node_id, {})
55
+ return {}
56
+
57
+
58
+ class _CountingBlocksList:
59
+ """Async ``blocks.list`` stub used by table rotation fallback tests."""
60
+
61
+ def __init__(self, blocks: list[dict]) -> None:
62
+ self.calls: list[dict] = []
63
+ self._blocks = blocks
64
+
65
+ async def __call__(self, params: dict) -> dict:
66
+ self.calls.append(params)
67
+ return {"blocks": list(self._blocks)}
68
+
69
+
70
+ class _FailingFind:
71
+ def __init__(self) -> None:
72
+ self.calls = 0
73
+
74
+ async def __call__(self, params: dict) -> dict: # noqa: ARG002
75
+ self.calls += 1
76
+ raise AssertionError("doc.find should not be used when blocks.list resolves tables")
77
+
78
+
34
79
  class _TableStub:
35
80
  def __init__(
36
81
  self,
@@ -53,6 +98,17 @@ class _TableStub:
53
98
  return self._node_id
54
99
 
55
100
 
101
+ class _RewritingBuffer:
102
+ def __init__(self, table: _TableStub, real_node_id: str) -> None:
103
+ self.calls = 0
104
+ self._table = table
105
+ self._real_node_id = real_node_id
106
+
107
+ def flush(self) -> None:
108
+ self.calls += 1
109
+ self._table._node_id = self._real_node_id
110
+
111
+
56
112
  def test_docx_editor_cell_id_is_positional_with_no_query() -> None:
57
113
  from docx.table import _Cell
58
114
 
@@ -79,6 +135,32 @@ def test_docx_editor_cell_address_shape_no_query() -> None:
79
135
  assert gc.calls == 0
80
136
 
81
137
 
138
+ def test_fresh_client_id_table_uses_known_doc_index_no_query() -> None:
139
+ from docx.table import _Cell
140
+
141
+ gc = _CountingGetCells()
142
+ table = _TableStub("t_client_abc", gc, doc_index=4)
143
+ cell = _Cell(table=table, row=1, col=1) # type: ignore[arg-type]
144
+
145
+ assert cell._cell_id() == "tc:4:1:1"
146
+ assert gc.calls == 0
147
+
148
+
149
+ def test_fresh_client_id_table_flushes_buffer_then_uses_rewritten_positional_id() -> None:
150
+ from docx.table import _Cell
151
+
152
+ gc = _CountingGetCells()
153
+ table = _TableStub("t_client_abc", gc, doc_index=4)
154
+ buffer = _RewritingBuffer(table, "t:8")
155
+ table._session._doc_handle = type("_Handle", (), {"buffer": buffer})()
156
+ cell = _Cell(table=table, row=1, col=1) # type: ignore[arg-type]
157
+
158
+ assert cell._cell_id() == "tc:8:1:1"
159
+ assert table._node_id == "t:8"
160
+ assert buffer.calls == 1
161
+ assert gc.calls == 0
162
+
163
+
82
164
  def test_docx_studio_cell_id_falls_back_to_query() -> None:
83
165
  from docx.table import _Cell
84
166
 
@@ -117,3 +199,63 @@ def test_read_loaded_table_falls_back_to_query() -> None:
117
199
 
118
200
  assert cell._cell_id() == "tc:0:0:1"
119
201
  assert gc.calls >= 1
202
+
203
+
204
+ def test_unflushed_client_table_uses_doc_index_not_find_for_cell_id() -> None:
205
+ from docx.table import Table, _Cell
206
+
207
+ get_cells = _CountingGetCells(cell_id="tc:0:0:0")
208
+ tables_get = _CountingTablesGet(
209
+ table_info_by_id={
210
+ "t:0": {"nodeId": "t:0", "rows": 2, "columns": 2},
211
+ },
212
+ )
213
+ blocks_list = _CountingBlocksList(
214
+ blocks=[
215
+ {"nodeType": "table", "nodeId": "t:0"},
216
+ ],
217
+ )
218
+ failing_find = _FailingFind()
219
+ doc = type(
220
+ "_Doc",
221
+ (),
222
+ {
223
+ "tables": type(
224
+ "_Tables",
225
+ (),
226
+ {"get": tables_get, "get_cells": get_cells},
227
+ )(),
228
+ "blocks": type("_Blocks", (), {"list": blocks_list})(),
229
+ "find": failing_find,
230
+ },
231
+ )()
232
+ session = type("_S", (), {"doc": doc})()
233
+ table = Table(session=session, node_id="t_client_uuid", rows=2, columns=2, doc_index=0)
234
+ cell = _Cell(table=table, row=0, col=0)
235
+
236
+ assert cell._cell_id() == "tc:0:0:0"
237
+ assert table._node_id == "t_client_uuid"
238
+ assert blocks_list.calls == []
239
+ assert failing_find.calls == 0
240
+
241
+
242
+ def test_set_shading_uses_positional_cell_target_without_query() -> None:
243
+ from docx.table import Table, _Cell
244
+
245
+ session = _RecordingSession()
246
+ table = Table(session=session, node_id="t:2", rows=2, columns=2, doc_index=2)
247
+ cell = _Cell(table=table, row=0, col=1)
248
+
249
+ cell.set_shading(fill="1F497D")
250
+
251
+ assert len(session.commands) == 1
252
+ command = session.commands[0]
253
+ assert command.to_dict() == {
254
+ "type": "SetCellShading",
255
+ "target": {
256
+ "kind": "block",
257
+ "nodeType": "tableCell",
258
+ "nodeId": "tc:2:0:1",
259
+ },
260
+ "fill": "1F497D",
261
+ }
@@ -524,6 +524,41 @@ def test_buffer_emits_for_create_table(monkeypatch: Any) -> None:
524
524
  assert calls["end"][0]["is_error"] is False
525
525
 
526
526
 
527
+ def test_buffer_emits_for_add_citation(monkeypatch: Any) -> None:
528
+ """``AddCitation`` is allow-listed so agent-authored citations are
529
+ visible as PTC sub-tool-cards instead of silently only updating the
530
+ Athena citation layer."""
531
+ from docx._buffer import CommandBuffer
532
+ from docx.commands import AddCitation
533
+
534
+ calls = _stub_ptc(monkeypatch)
535
+ client = _FakeHttpClient()
536
+ buf = CommandBuffer(client, asset_id="asset-1", auto_flush_seconds=0)
537
+
538
+ buf.call(
539
+ AddCitation(
540
+ destination_anchor={"type": "pm_node", "nodeId": "p_1"},
541
+ citation_string="/dashboard/spaces/?asset_ids=asset_pdf&type=pdf&page=2",
542
+ citation_id="citation_abc",
543
+ excerpt="20,049 total vulnerabilities",
544
+ display_value="Vulnerability total",
545
+ )
546
+ )
547
+
548
+ assert len(calls["begin"]) == 1
549
+ assert calls["begin"][0][0] == "AddCitation"
550
+ assert calls["begin"][0][1]["citationString"] == (
551
+ "/dashboard/spaces/?asset_ids=asset_pdf&type=pdf&page=2"
552
+ )
553
+ assert calls["begin"][0][3] == "asset-1"
554
+ assert len(calls["end"]) == 0
555
+
556
+ buf.flush()
557
+ assert len(calls["end"]) == 1
558
+ assert calls["end"][0]["tool_name"] == "AddCitation"
559
+ assert calls["end"][0]["is_error"] is False
560
+
561
+
527
562
  def test_buffer_skips_ptc_for_non_body_creates(monkeypatch: Any) -> None:
528
563
  """Allow-listed creates that target a non-body story (header/footer/
529
564
  footnote via ``in_``) do NOT emit a PTC card: the frontend locate
@@ -8,7 +8,7 @@ resolution-markers = [
8
8
 
9
9
  [[package]]
10
10
  name = "athena-python-docx"
11
- version = "0.21.0"
11
+ version = "0.21.2"
12
12
  source = { editable = "." }
13
13
  dependencies = [
14
14
  { name = "athena-references" },