athena-python-docx 0.25.0__tar.gz → 0.27.0__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 (425) hide show
  1. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/AGENTS.md +274 -76
  2. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/PKG-INFO +1 -1
  3. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/__init__.py +1 -1
  4. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_http_doc.py +23 -2
  5. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_image_utils.py +95 -22
  6. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_postproc.py +102 -141
  7. athena_python_docx-0.27.0/docx/blkcntnr.py +58 -0
  8. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/client.py +3 -0
  9. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/commands.py +157 -12
  10. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/comments.py +135 -53
  11. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/document.py +82 -88
  12. athena_python_docx-0.27.0/docx/drawing/__init__.py +60 -0
  13. athena_python_docx-0.27.0/docx/enum/base.py +151 -0
  14. athena_python_docx-0.27.0/docx/enum/dml.py +42 -0
  15. athena_python_docx-0.27.0/docx/enum/section.py +59 -0
  16. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/enum/style.py +13 -23
  17. athena_python_docx-0.27.0/docx/enum/table.py +68 -0
  18. athena_python_docx-0.27.0/docx/enum/text.py +241 -0
  19. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/errors.py +18 -0
  20. athena_python_docx-0.27.0/docx/image/__init__.py +5 -0
  21. athena_python_docx-0.27.0/docx/image/exceptions.py +13 -0
  22. athena_python_docx-0.27.0/docx/image/image.py +153 -0
  23. athena_python_docx-0.27.0/docx/opc/coreprops.py +253 -0
  24. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/section.py +224 -193
  25. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/shape.py +62 -66
  26. athena_python_docx-0.27.0/docx/styles/_table.py +596 -0
  27. athena_python_docx-0.27.0/docx/styles/latent.py +220 -0
  28. athena_python_docx-0.27.0/docx/styles/style.py +923 -0
  29. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/styles/styles.py +78 -93
  30. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/table.py +238 -262
  31. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/hyperlink.py +9 -3
  32. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/paragraph.py +344 -81
  33. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/parfmt.py +12 -7
  34. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/run.py +414 -204
  35. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/tabstops.py +18 -65
  36. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/pyproject.toml +1 -1
  37. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/release.sh +2 -2
  38. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/fake_session.py +82 -15
  39. athena_python_docx-0.27.0/tests/fidelity/op_snapshots/104_core_properties_datetime.json +21 -0
  40. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/17_table_basic.json +1 -0
  41. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/45_cell_text_round_trip.json → athena_python_docx-0.27.0/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +1 -0
  42. athena_python_docx-0.27.0/tests/fidelity/op_snapshots/28_section_add_new.json +3 -0
  43. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +2 -1
  44. athena_python_docx-0.27.0/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +8 -0
  45. athena_python_docx-0.27.0/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +5 -0
  46. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -4
  47. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +2 -2
  48. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -5
  49. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +1 -0
  50. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -8
  51. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +1 -0
  52. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/68_invoice.json +1 -0
  53. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/69_newsletter.json +2 -5
  54. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +1 -0
  55. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +1 -0
  56. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +1 -1
  57. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -4
  58. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +1 -0
  59. athena_python_docx-0.27.0/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +12 -0
  60. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +15 -120
  61. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +1 -0
  62. athena_python_docx-0.27.0/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +35 -0
  63. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +1 -0
  64. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -2
  65. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +12 -24
  66. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +1 -0
  67. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +1 -0
  68. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -2
  69. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +1 -0
  70. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +1 -0
  71. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw11_header_text.json +1 -0
  72. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +2 -0
  73. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +2 -0
  74. athena_python_docx-0.27.0/tests/fixtures/field_reads.json +863 -0
  75. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/README.md +4 -1
  76. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/intentional_deviations.json +14 -24
  77. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/test_parity_gap.py +32 -11
  78. athena_python_docx-0.27.0/tests/test_add_section.py +206 -0
  79. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_athena_extensions_registry.py +1 -0
  80. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_fastpath_runs.py +35 -3
  81. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_format_stash.py +8 -0
  82. athena_python_docx-0.27.0/tests/test_cell_merge.py +443 -0
  83. athena_python_docx-0.27.0/tests/test_cell_paragraphs_listed.py +234 -0
  84. athena_python_docx-0.27.0/tests/test_cell_text_replace_semantics.py +76 -0
  85. athena_python_docx-0.27.0/tests/test_color_format_theme.py +134 -0
  86. athena_python_docx-0.27.0/tests/test_comments.py +436 -0
  87. athena_python_docx-0.27.0/tests/test_core_properties.py +191 -0
  88. athena_python_docx-0.27.0/tests/test_drawing_image.py +267 -0
  89. athena_python_docx-0.27.0/tests/test_enum_parity.py +449 -0
  90. athena_python_docx-0.27.0/tests/test_field_reads_python_docx_parity.py +105 -0
  91. athena_python_docx-0.27.0/tests/test_field_runs.py +386 -0
  92. athena_python_docx-0.27.0/tests/test_inline_shape_size.py +58 -0
  93. athena_python_docx-0.27.0/tests/test_missing_modules.py +238 -0
  94. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_page_break.py +31 -0
  95. athena_python_docx-0.27.0/tests/test_paragraph_runs_hyperlinks.py +85 -0
  96. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_parity_round2.py +54 -36
  97. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_phase_a_behavior.py +10 -2
  98. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_phase_b_headers_footers.py +282 -3
  99. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_postproc_cell_format_rewrite.py +75 -154
  100. athena_python_docx-0.27.0/tests/test_restart_numbering.py +207 -0
  101. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_revisions.py +38 -0
  102. athena_python_docx-0.27.0/tests/test_run_formatting_wire.py +154 -0
  103. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_run_identity.py +8 -2
  104. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_run_mark_inheritance.py +52 -13
  105. athena_python_docx-0.27.0/tests/test_run_table_style_objects.py +329 -0
  106. athena_python_docx-0.27.0/tests/test_run_text_python_docx.py +190 -0
  107. athena_python_docx-0.27.0/tests/test_run_text_refreshes_paragraph.py +60 -0
  108. athena_python_docx-0.27.0/tests/test_sdk_reads_served.py +191 -0
  109. athena_python_docx-0.27.0/tests/test_section_read_lengths.py +91 -0
  110. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_add_picture.py +9 -11
  111. athena_python_docx-0.27.0/tests/test_silent_stub_enum_section.py +54 -0
  112. athena_python_docx-0.27.0/tests/test_silent_stub_inline_shape.py +73 -0
  113. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_misc.py +7 -14
  114. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_paragraph_strict.py +13 -9
  115. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_parfmt.py +44 -13
  116. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_row_col_cell.py +3 -1
  117. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_underline.py +1 -1
  118. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_section_dimensions.py +43 -8
  119. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_style.py +13 -11
  120. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_audit.py +1 -1
  121. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_layout.py +1 -1
  122. athena_python_docx-0.27.0/tests/test_style_formatting_writes.py +290 -0
  123. athena_python_docx-0.27.0/tests/test_style_metadata_writes.py +276 -0
  124. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_names.py +85 -0
  125. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_setters_contract.py +11 -14
  126. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_table_style_id_resolution.py +4 -2
  127. athena_python_docx-0.27.0/tests/test_text_control_characters.py +233 -0
  128. athena_python_docx-0.27.0/tests/test_uv_lock_version.py +23 -0
  129. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_wire_contract.py +121 -10
  130. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/uv.lock +1 -1
  131. athena_python_docx-0.25.0/docx/enum/section.py +0 -72
  132. athena_python_docx-0.25.0/docx/enum/table.py +0 -52
  133. athena_python_docx-0.25.0/docx/enum/text.py +0 -258
  134. athena_python_docx-0.25.0/docx/opc/coreprops.py +0 -248
  135. athena_python_docx-0.25.0/docx/styles/_table.py +0 -303
  136. athena_python_docx-0.25.0/docx/styles/style.py +0 -611
  137. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -1
  138. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -9
  139. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/28_section_add_new.json +0 -5
  140. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -1
  141. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -32
  142. athena_python_docx-0.25.0/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -34
  143. athena_python_docx-0.25.0/tests/test_cell_text_replace_semantics.py +0 -116
  144. athena_python_docx-0.25.0/tests/test_comments.py +0 -238
  145. athena_python_docx-0.25.0/tests/test_silent_stub_enum_section.py +0 -83
  146. athena_python_docx-0.25.0/tests/test_silent_stub_inline_shape.py +0 -105
  147. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/.gitignore +0 -0
  148. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/CLAUDE.md +0 -0
  149. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/DOCX_EXEC_LAB.md +0 -0
  150. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/README.md +0 -0
  151. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_athena_extension.py +0 -0
  152. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_batching.py +0 -0
  153. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_buffer.py +0 -0
  154. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_citations.py +0 -0
  155. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_execution.py +0 -0
  156. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_http.py +0 -0
  157. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_ptc.py +0 -0
  158. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_references.py +0 -0
  159. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_run_order.py +0 -0
  160. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_table_styles.py +0 -0
  161. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_timeouts.py +0 -0
  162. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/api.py +0 -0
  163. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/bookmarks.py +0 -0
  164. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/charts.py +0 -0
  165. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/enum/__init__.py +0 -0
  166. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/enum/shape.py +1 -1
  167. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/exceptions.py +0 -0
  168. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/fields.py +0 -0
  169. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/footnotes.py +0 -0
  170. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/math.py +0 -0
  171. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/opc/__init__.py +0 -0
  172. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/oxml/__init__.py +0 -0
  173. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/revisions.py +0 -0
  174. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/sdt.py +0 -0
  175. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/session.py +0 -0
  176. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/settings.py +0 -0
  177. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/shared.py +0 -0
  178. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/styles/__init__.py +0 -0
  179. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/__init__.py +0 -0
  180. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/font.py +0 -0
  181. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/pagebreak.py +0 -0
  182. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/toc.py +0 -0
  183. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/typing.py +0 -0
  184. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab.py +0 -0
  185. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  186. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  187. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab_server.py +0 -0
  188. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/dump_wire_fixtures.py +0 -0
  189. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/round_trip_smoke.py +0 -0
  190. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/smoke_test_block_not_found.py +0 -0
  191. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/validate_find_replace_asset.py +0 -0
  192. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/__init__.py +0 -0
  193. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/conftest.py +0 -0
  194. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/METHODOLOGY.md +0 -0
  195. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/README.md +0 -0
  196. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/__init__.py +0 -0
  197. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/ab_probe_cases.py +0 -0
  198. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/ab_probe_runner.py +0 -0
  199. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/auto_gen_cases.py +0 -0
  200. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/binary_round_trip.py +0 -0
  201. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/cases.py +0 -0
  202. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/complex_cases.py +0 -0
  203. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/coverage_report.py +0 -0
  204. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/extract.py +0 -0
  205. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/extreme_cases.py +0 -0
  206. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/README.md +0 -0
  207. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/__init__.py +0 -0
  208. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/_runner.py +0 -0
  209. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/extractor.py +0 -0
  210. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  211. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  212. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/local_runner.py +0 -0
  213. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/mega_cases.py +0 -0
  214. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshot.py +0 -0
  215. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  216. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  217. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  218. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  219. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  220. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  221. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  222. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  223. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  224. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  225. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  226. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  227. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  228. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  229. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  230. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  231. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  232. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  233. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  234. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  235. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  236. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  237. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  238. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  239. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  240. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  241. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  242. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  243. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  244. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  245. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  246. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  247. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  248. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  249. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  250. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  251. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  252. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  253. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  254. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  255. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  256. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  257. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  258. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  259. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  260. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  261. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  262. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  263. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  264. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  265. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  266. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  267. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  268. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  269. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  270. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  271. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  272. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  273. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  274. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  275. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  276. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  277. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  278. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  279. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  280. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  281. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  282. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  283. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  284. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  285. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  286. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  287. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  288. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  289. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  290. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  291. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  292. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  293. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  294. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  295. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  296. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  297. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  298. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  299. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  300. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  301. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  302. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  303. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  304. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  305. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  306. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  307. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  308. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  309. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  310. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  311. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  312. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  313. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  314. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  315. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  316. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  317. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  318. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  319. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  320. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  321. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  322. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  323. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  324. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  325. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  326. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  327. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/ours_spec.json +0 -0
  328. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/parity_crawl.py +0 -0
  329. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/parity_diff.json +0 -0
  330. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/real_world_cases.py +0 -0
  331. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/round_trip_tests.py +0 -0
  332. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/stock_spec.json +0 -0
  333. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
  334. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/__init__.py +0 -0
  335. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/baseline_gaps.json +0 -0
  336. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/compare.py +0 -0
  337. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/introspect.py +0 -0
  338. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  339. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/reports/gap_report.json +0 -0
  340. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/run_parity.py +0 -0
  341. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/snapshots/athena_latest.json +0 -0
  342. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  343. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_add_section_extract_items.py +0 -0
  344. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_athena_extension_creates_session_open.py +0 -0
  345. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_athena_extensions_contract.py +0 -0
  346. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_batching_perf.py +0 -0
  347. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_block_not_found_error.py +0 -0
  348. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_buffer.py +0 -0
  349. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  350. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_add_table_not_supported.py +0 -0
  351. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_borders_spec.py +0 -0
  352. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  353. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  354. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_run_format_stash.py +0 -0
  355. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_run_guard.py +0 -0
  356. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_text_plain_fastpath.py +0 -0
  357. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_citations.py +0 -0
  358. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_collapsed_range_format.py +0 -0
  359. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_command_dataclasses.py +0 -0
  360. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_commands.py +0 -0
  361. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_asset_id_property.py +0 -0
  362. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_clear.py +0 -0
  363. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_create.py +0 -0
  364. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_create_from_template.py +0 -0
  365. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_factory_validation.py +0 -0
  366. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_docx_exec_lab.py +0 -0
  367. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_docx_exec_lab_server.py +0 -0
  368. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
  369. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_execution_scope.py +0 -0
  370. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_find_replace_session_open.py +0 -0
  371. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_http_transport.py +0 -0
  372. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_hyperlink_coalescing.py +0 -0
  373. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_image_url_data_uri.py +0 -0
  374. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_inline_shape_alt_text.py +0 -0
  375. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_insert_deferred.py +0 -0
  376. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_iter_inner_content.py +0 -0
  377. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_list_styles.py +0 -0
  378. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_merged_cell_secondary_slot.py +0 -0
  379. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_merged_cells.py +0 -0
  380. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_oxml_shim.py +0 -0
  381. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_paragraph_text_len_cache.py +0 -0
  382. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_parity_misc.py +0 -0
  383. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_partial_failure_cascade.py +0 -0
  384. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_pdf_export_and_page_renders.py +0 -0
  385. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_phase_c_tables.py +0 -0
  386. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_positional_cell_id.py +0 -0
  387. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  388. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_postproc_ref_restore.py +0 -0
  389. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_pr19766_review_fixes.py +0 -0
  390. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_ptc.py +0 -0
  391. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_python_docx_api_parity.py +0 -0
  392. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_run_add_picture_anchor.py +0 -0
  393. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  394. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_add_run.py +0 -0
  395. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  396. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
  397. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_comments_get.py +0 -0
  398. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_document_audit.py +0 -0
  399. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_document_element.py +0 -0
  400. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_font_audit.py +0 -0
  401. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_header_footer.py +0 -0
  402. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_hyperlink.py +0 -0
  403. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  404. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_paragraph_style.py +0 -0
  405. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  406. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_add_break.py +0 -0
  407. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
  408. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_style.py +0 -0
  409. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_style_strict.py +0 -0
  410. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_text.py +0 -0
  411. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_section_audit.py +0 -0
  412. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_section_onoff.py +0 -0
  413. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_settings.py +0 -0
  414. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_shared_audit.py +0 -0
  415. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_styles.py +0 -0
  416. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_cell.py +0 -0
  417. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_dimensions.py +0 -0
  418. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_smoke_integration.py +0 -0
  419. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_acceptance.py +0 -0
  420. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_font.py +0 -0
  421. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_table_set_cell_perf.py +0 -0
  422. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_temporarily_unavailable.py +0 -0
  423. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_validate_find_replace_asset_script.py +0 -0
  424. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_xml_attr_guard.py +0 -0
  425. {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_zod_wire_contract.py +0 -0
@@ -31,14 +31,14 @@ These standard python-docx members don't apply to a DOCX Studio-backed SDK:
31
31
 
32
32
  - `Paragraph._p`, `Run._r` — XML element access (no local XML)
33
33
  - `Document.part`, `Paragraph.part`, `Run.part` — package part access
34
- - `Document.core_properties.last_modified_by` — we use Keryx attribution instead
35
34
  - `Document.settings` — Word app settings (not surfaced by DOCX Studio)
36
35
  - `InlineShape.chart` — charts are not currently surfaced by the SDK.
37
36
  - `Comment.add_paragraph` / `Comment.add_table` /
38
37
  `Comment.iter_inner_content` / `Comment.paragraphs` /
39
- `Comment.tables` — DOCX Studio models a comment as a single text body,
40
- not a `BlockItemContainer`. Use `Comment.text` instead. The
41
- paragraph/table-bearing surface raises `CommentsNotImplementedError`.
38
+ `Comment.tables` — DOCX Studio models a comment as a single text body.
39
+ `Comment` is a `docx.blkcntnr.BlockItemContainer`, as `_Cell` and the
40
+ header/footer proxies are, but its paragraph/table-bearing surface raises
41
+ `CommentsNotImplementedError`. Use `Comment.text` instead.
42
42
  - **`_Cell.add_table(rows, cols)`** — surface preserved for parity
43
43
  (signature matches python-docx, no `width` kwarg) but raises
44
44
  :class:`docx.errors.NestedTableNotSupportedError` (subclass of
@@ -71,18 +71,41 @@ runtime, pending additional docx-editor command support. Behavior should be
71
71
  pinned by focused tests and documented in
72
72
  `docx-studio/DOCX_STUDIO_LIMITATIONS.md`.
73
73
 
74
- - **24 setters on `BaseStyle` / `CharacterStyle` / `ParagraphStyle`**
75
- (`name`, `style_id`, `hidden`, `locked`, `priority`, `quick_style`,
76
- `unhide_when_used`, `base_style`, `next_paragraph_style`) emit
77
- `PendingStyleMutationWarning` and stash on `_overrides`.
78
- The current `doc.styles.apply` command surface is constrained to
79
- `target.scope: "docDefaults"` — no per-style metadata variant.
80
- Behavior pinned by `tests/test_style_setters_contract.py` (11
81
- tests); when docx-editor lands a metadata op, those tests will need
82
- to flip to assert real bus calls.
83
- - **`Styles.latent_styles`** returns an empty `_LatentStyles` —
84
- `DocInfoResult.styles` only surfaces `paragraphStyles[]` (a flat
85
- usage-count list), not the OOXML `<w:latentStyles>` block.
74
+ - **Style setters on `BaseStyle` / `CharacterStyle` / `ParagraphStyle`.**
75
+ The metadata setters (`name`, `hidden`, `locked`, `priority`,
76
+ `quick_style`, `unhide_when_used`, `base_style`,
77
+ `next_paragraph_style`) write the style's definition
78
+ (`SetStyleMetadata`), `Styles.add_style` adds one (`CreateStyle`), and
79
+ a paragraph or character style's formatting (`style.font.*`,
80
+ `style.paragraph_format.*`) is written too (`SetStyleFormatting`); each
81
+ reads back from the style table, whose `metadata` / `font` /
82
+ `paragraphFormat` entries are the capability signal
83
+ (`tests/test_style_metadata_writes.py`,
84
+ `tests/test_style_formatting_writes.py`). `style_id`, `delete()`, a
85
+ table style's formatting and base, a style's tab stops, and every style write on
86
+ a docx-studio without that signal emit `PendingStyleMutationWarning`
87
+ (or its paragraph-format / registry variant) and stash on
88
+ `_overrides` (`tests/test_style_setters_contract.py`).
89
+ - **A picture is a run, and `Run.iter_inner_content()` yields its
90
+ `docx.drawing.Drawing`.** As python-docx reads a `w:r` holding a
91
+ `w:drawing`, `Paragraph.runs` and `iter_inner_content()` hold a run with
92
+ text `""` for each picture (docx-studio reports it as a
93
+ `{drawing: {imageId}}` inline), and a linked picture is a run of its
94
+ `Hyperlink`. `run.text = ...` and `run.clear()` on a picture run remove the
95
+ picture with its text (`Replace` with `removePictures`). The drawing's
96
+ `has_picture` is True and its `image` is a `docx.image.image.Image` read
97
+ through `ImagesGet` (python-docx's `blob`, `content_type`, `px_width`,
98
+ `horz_dpi`, `width`, `scaled_dimensions`, …). A picture in a table cell or
99
+ a header has no id to read its image by, so `.image` raises `ValueError`;
100
+ an older docx-studio does not report pictures, so they are not runs there.
101
+ - **`Styles.latent_styles`** (`docx.styles.latent.LatentStyles`) reads
102
+ the document's `<w:latentStyles>` (defaults and each `w:lsdException`)
103
+ from docx-studio's `Info` (`includeStyles` → `latentStyles`), as python-docx
104
+ reads them. Writing them is not supported: a setter, `add_latent_style`
105
+ and `_LatentStyle.delete` emit `PendingLatentStylesWriteWarning` and
106
+ change nothing. A docx-studio that predates the read (or a document
107
+ without a source copy) reads as empty, with
108
+ `PendingLatentStylesReadWarning`.
86
109
 
87
110
  ### Intentional deviations (additions / different semantics)
88
111
 
@@ -100,31 +123,36 @@ not file-backed. Each is documented in the relevant docstring.
100
123
  URIs. Local paths and file-like streams behave exactly as upstream.
101
124
  The dispatch lives in ``docx._image_utils.load_image_bytes``; a failed
102
125
  fetch/decode raises a ``ValueError`` at the call site rather than a
103
- bare transport error. This is the only image-input deviation — the
104
- resulting bytes still flow through the same magic-byte
105
- ``sniff_content_type`` → base64 ``data:`` URI → ``create.image`` path.
126
+ bare transport error. The resulting bytes go through the same
127
+ signature check as upstream: a stream that is no PNG, JPEG, GIF, BMP or
128
+ TIFF (nor, beyond python-docx, WebP or SVG) raises
129
+ ``docx.image.exceptions.UnrecognizedImageError`` whatever its file name,
130
+ where it used to land as a 6" x 4.5" guess
131
+ (``docx._image_utils.image_content_type``).
106
132
 
107
133
  - **Built-in table style friendly names resolve to OOXML styleIds.**
108
134
  Word's ``styles.xml`` ships built-in table styles whose styleIds
109
135
  (``LightGrid-Accent1``, ``MediumShading1-Accent2``, …) differ from
110
- their display names (``"Light Grid Accent 1"``, …). Stock
111
- python-docx resolves the friendly form against the loaded
112
- document's styles collection at write time. We can't read
113
- ``styles.xml`` over HTTP, so ``Document.add_table(style=...)`` /
114
- ``Table.style`` setter consult an in-process map
115
- (``docx._table_styles.BUILTIN_TABLE_STYLE_IDS``) covering every
116
- Word 2007 and Word 2013+ built-in table style (204 entries) before
117
- the value reaches ``<w:tblStyle w:val="..."/>``. Without this
118
- mapping Word can't resolve the friendly name in ``styles.xml``
119
- and silently falls back to ``Normal Table`` (no borders, no
120
- header fill, no banding). Custom user-defined style names pass
121
- through unchanged. Whether Word actually renders a Word 2013+
122
- style after resolution also depends on the exported
123
- ``styles.xml`` containing the matching ``<w:style w:type="table">``
124
- definition. If the exported ``styles.xml`` only carries the Word 2007
125
- set, Word 2013+ styleIds resolve in the ``<w:tblStyle>`` element but
126
- still fall back to ``Normal Table`` until the export path ships an
127
- expanded ``styles.xml``.
136
+ their display names (``"Light Grid Accent 1"``, …). Like python-docx,
137
+ ``Document.add_table(style=...)`` / the ``Table.style`` setter resolve
138
+ a name through the document's style table (docx-studio ``Info``) and
139
+ raise ``KeyError`` for a name it lacks — except a Word built-in table
140
+ style docx-studio holds Word's definition of (python-docx's default
141
+ template: Table Grid, Light Shading … Colorful Grid and their accents),
142
+ which resolves through an in-process map
143
+ (``docx._table_styles.BUILTIN_TABLE_STYLE_IDS``) when the document does
144
+ not define it: the editor draws it from that definition and the export
145
+ adds the definition to ``styles.xml``, as Word does when the style is
146
+ applied. A Word 2013+ table style (Grid Table, List Table, Plain Table)
147
+ the document lacks raises ``KeyError``, as in python-docx, whose
148
+ template defines none. Against a docx-studio that sends no table every
149
+ built-in name (Word 2007 and 2013+, 204 entries) is sent as its id, and
150
+ custom names pass through unchanged. ``Document.add_table`` with no
151
+ style keeps Athena's brand table look (direct cell borders and zebra
152
+ fill, no ``w:tblStyle``) where python-docx's table has none; a style
153
+ set on the table replaces that look, and borders and fills set on its
154
+ cells stay. ``table.style = None`` removes an existing table's style as
155
+ python-docx does (``DOCX_STUDIO_LIMITATIONS.md`` § 25).
128
156
 
129
157
  - **`Document.create(name=, base_url=, api_key=, parent_folder_id=, workspace_id=, docx=, agora_base_url=)`**
130
158
  classmethod. Stock python-docx returns a blank in-memory document
@@ -185,10 +213,10 @@ not file-backed. Each is documented in the relevant docstring.
185
213
 
186
214
  - **`Document.user_name: str | None` / `Document.user_email: str |
187
215
  None`** — author identity threaded through to DOCX Studio on session-
188
- open for tracked-change attribution. python-docx's
189
- `Document.core_properties.last_modified_by` is the closest upstream
190
- surface; we use the DOCX Studio-native fields directly because DOCX Studio
191
- bakes them into the change records.
216
+ open for tracked-change attribution; DOCX Studio bakes them into the
217
+ change records. Separate from `Document.core_properties.last_modified_by`,
218
+ the `docProps/core.xml` metadata the SDK reads and writes as python-docx
219
+ does.
192
220
 
193
221
  - **`Document.revisions: Revisions`** — collection of tracked changes
194
222
  with iteration, `get(id)`, `accept_all()`, `reject_all()`,
@@ -196,6 +224,26 @@ not file-backed. Each is documented in the relevant docstring.
196
224
  `Revision.reject()` resolve a single change. python-docx upstream
197
225
  has zero track-changes API, so this entire surface is an Athena
198
226
  extension wired to DOCX Studio's `doc.trackChanges.{list,get,decide}`.
227
+ A run's tracked formatting change (`w:rPrChange`) and a paragraph's
228
+ (`w:pPrChange`) are `"format"` revisions; `reject()` gives the run or
229
+ paragraph exactly the earlier properties the change recorded
230
+ (`tests/test_revisions.py`, docx-studio's
231
+ `tracked-run-property-changes.test.ts`).
232
+
233
+ - **Style writes refuse what would write a broken document.** python-docx
234
+ writes these into `styles.xml`; the SDK raises before anything is sent,
235
+ because the result would be a document Word cannot resolve
236
+ (`tests/test_style_metadata_writes.py`):
237
+ - `Styles.add_style` raises `ValueError` for a style id the document
238
+ already has (a name without the space, `"Heading1"`, derives the id
239
+ of the existing Heading 1), where python-docx appends a second
240
+ definition of that id;
241
+ - `base_style = ` a style whose `basedOn` chain reaches this one (itself
242
+ included) raises `ValueError`, where python-docx writes a chain Word
243
+ refuses;
244
+ - `priority = True` raises `TypeError`, where python-docx (to which a
245
+ `bool` is an `int`) writes `w:uiPriority w:val="True"`, not a
246
+ number; any other non-`int` raises `TypeError` in both.
199
247
 
200
248
  ### Athena extensions for most-requested upstream features (v0.11.0+)
201
249
 
@@ -287,7 +335,10 @@ Issue numbers reference `python-openxml/python-docx`.
287
335
  python-docx surfaces `_Cell.grid_span` (horizontal) but the
288
336
  vertical merge state and master detection are issue #1312, #1434,
289
337
  #1458. Pure derived properties from existing `tables.getCells`
290
- data.
338
+ data: docx-studio reports `vMerge` for the grid position asked
339
+ about (`"restart"` on the merged cell's first row, `"continue"`
340
+ below it), while `text`, `grid_span` and writes resolve to the
341
+ merged cell from any position it covers.
291
342
 
292
343
  - **`Table.add_row(*, copy_format_from=None)`** — when `copy_format_from`
293
344
  is provided (int row index or `_Row`), the new row inherits height,
@@ -373,6 +424,30 @@ Issue numbers reference `python-openxml/python-docx`.
373
424
  numbering reads. python-docx issue #471 (13 👍) demands access to
374
425
  list metadata. Routes through `NumberingGet`.
375
426
 
427
+ - **`Paragraph.restart_numbering(start=1)`** (0.26.0+) — restart the
428
+ paragraph's numbered list at `start`, as Word's "Restart at 1" does
429
+ ("Set Numbering Value" for another start). All `"List Number"`
430
+ paragraphs share one numbering, as in Word and python-docx, so a list
431
+ after a heading or table counts on (3, 4) until restarted. python-docx
432
+ has no way to restart a list: issue #25, open since 2014. Routes
433
+ through `ListsSplit` (`restartNumbering: true`, `start`), sent in a
434
+ request of its own after the buffered edits. docx-studio adds a `w:num`
435
+ on the list's `w:abstractNum` whose
436
+ `<w:lvlOverride w:ilvl="N"><w:startOverride w:val="start"/>` (ECMA-376
437
+ §17.9.27) starts the paragraph's level, and points the paragraph and the
438
+ later items of its `w:num` at it: up to the next item of a shallower
439
+ level, the next list restarted on its own, or the end of the document.
440
+ Headings, tables, body text and other lists between the items do not
441
+ end the list, because Word counts across them. A header or footer
442
+ paragraph restarts within its part, whose paragraphs count on their own.
443
+ The same restart again changes nothing. A paragraph that takes no number (plain, heading,
444
+ bullet) raises `docx.errors.NotNumberedListItemError` (a `ValueError`);
445
+ `start` outside 0..32767 raises `ValueError`; a docx-studio API without
446
+ the handler raises `DocxUnsupportedCommandError`. The new `w:num` lives
447
+ in the source package, so each restart stores the package again (one
448
+ copy in the room's history) until #41656 item 7's writers store it by
449
+ reference.
450
+
376
451
  - **`Document.to_pdf(*, quality=None, destination=None,
377
452
  include_revisions=False) -> bytes`** — render to PDF. python-docx
378
453
  issue #113 was closed as
@@ -752,28 +827,35 @@ gaps. The items below are the **residual intentional deviations** that
752
827
  remain because matching upstream would break the asset-backed/HTTP
753
828
  architecture or a DOCX Studio constraint:
754
829
 
755
- - **`WD_*` enum `.value` is the DOCX Studio wire string, not the MS Word
756
- integer constant.** `WD_ALIGN_PARAGRAPH.CENTER.value == "center"`
757
- (upstream: `1`); `int(member)` / `member == 1` / `WD_*(1)` therefore
758
- differ. The string value is load-bearing — every command serializes
759
- `enum.value` directly onto the wire (`underline=value.value`,
760
- `WD_COLOR_INDEX(v).value`, …), so int-valuing the enums would require
761
- re-plumbing the entire command layer. Members are accessed by name
762
- (`WD_ALIGN_PARAGRAPH.CENTER`), so the drift is academic for normal
763
- use. (`WD_STYLE`/`WD_BUILTIN_STYLE` and `WD_INLINE_SHAPE_TYPE` are NOT
764
- wire-load-bearing and DO carry the upstream int values.)
830
+ - **Enum-typed setters also take the member's DOCX Studio string.** The
831
+ `WD_*` / `MSO_*` enums are python-docx's (`docx.enum.base.BaseEnum` /
832
+ `BaseXmlEnum`): every member is its MS API int
833
+ (`WD_ALIGN_PARAGRAPH.CENTER == 1`, `str()` is `"CENTER (1)"`), XML
834
+ enums carry `xml_value` and `from_xml`/`to_xml`, and the aliases are
835
+ upstream's (`WD_ALIGN_PARAGRAPH is WD_PARAGRAPH_ALIGNMENT`,
836
+ `WD_BREAK.TEXT_WRAPPING is WD_BREAK.LINE_CLEAR_ALL`). Setters take a
837
+ member or its int value as upstream does; they additionally accept the
838
+ string DOCX Studio's commands carry for a member (`"center"`, `"wavy"`,
839
+ the `w:` XML value, …) where upstream rejects strings. The SDK sends
840
+ `member.to_docx_studio()` and reads with `from_docx_studio()`, never
841
+ `.value`. Members DOCX Studio can't apply are sent as their closest
842
+ value with `PendingEnumCoercionWarning` (distributed / kashida / Thai
843
+ justification → `"justify"`; `LIST`/`CLEAR`/`END`/`NUM`/`START` tabs →
844
+ `"left"`); `WD_ALIGN_VERTICAL.BOTH` goes as `"center"`. `INHERITED`
845
+ raises `ValueError` ("has no XML representation") as upstream's
846
+ `to_xml` does, and a bool is its int value (`True` is the member valued
847
+ 1), as upstream reads it. `Table.alignment`
848
+ reads as `WD_TABLE_ALIGNMENT` and takes its three members (upstream
849
+ reads the equal `WD_PARAGRAPH_ALIGNMENT` member and takes any of its
850
+ values), and `Table.table_direction` reads as `WD_TABLE_DIRECTION`
851
+ (upstream: the equal bool). `WD_BUILTIN_STYLE` members carry no
852
+ per-member docstring.
765
853
 
766
854
  - **`RGBColor.from_string` additionally accepts a leading `#`.** Upstream
767
855
  rejects `"#FF0000"`; agents routinely pass it, so a single `#` is
768
856
  stripped before the (otherwise byte-identical) upstream slice parse.
769
857
  A strict superset — every value upstream accepts parses identically.
770
858
 
771
- - **`_Cell.vertical_alignment` setter accepts the four DOCX Studio wire
772
- tokens** (`"top"`/`"center"`/`"bottom"`/`"both"`) in addition to
773
- `WD_ALIGN_VERTICAL` members. Upstream rejects all plain strings; this
774
- is an ergonomic superset (typos like `"middle"` still raise
775
- `ValueError`).
776
-
777
859
  - **`Table.cell(row, col)` bounds-checks each axis independently** and
778
860
  raises `IndexError` for an out-of-range row or column. Upstream
779
861
  indexes a single flat row-major `_cells` list, so a column overflow
@@ -783,35 +865,151 @@ architecture or a DOCX Studio constraint:
783
865
  cheaply enumerate every cell. `(0,0)` and in-range negative indices
784
866
  behave identically to upstream.
785
867
 
786
- - **Unknown paragraph style names raise only when Word has no such
787
- built-in.** Style names and ids follow python-docx: `.name` is the UI
788
- name (`"Heading 1"`), `.style_id` the id (`"Heading1"`), read from the
789
- document's style table (docx-studio `Info` with `includeStyles`, fetched
790
- once per session in `docx/styles/_table.py`). A style set by name or id
791
- is sent as the document's id, and an unstyled paragraph reads as the
868
+ - **Unknown paragraph style names raise only when docx-studio has no
869
+ definition for them.** Style names and ids follow python-docx: `.name` is
870
+ the UI name (`"Heading 1"`), `.style_id` the id (`"Heading1"`), read from
871
+ the document's style table (docx-studio `Info` with `includeStyles`,
872
+ fetched once per session in `docx/styles/_table.py`). A style set by name
873
+ or id is sent as the document's id, and an unstyled paragraph reads as the
792
874
  default paragraph style. `paragraph.style = …` raises `KeyError` for a
793
- name the document defines no style for, like python-docx — except Word's
794
- built-in styles (`"Heading 4"`, `"List Bullet"`, `"Title"`…), which many
795
- templates never write into `styles.xml` until used. Those are sent by
796
- their Word id; Word and docx-studio apply the built-in definition. Against
797
- an older docx-studio (no style table) a built-in name is sent as its id
798
- and anything else as given.
875
+ name the document defines no style for, like python-docx — except the
876
+ Word built-ins docx-studio holds a definition of
877
+ (`BUILTIN_PARAGRAPH_STYLE_NAMES`: `"Heading 4"`, `"List Bullet"`,
878
+ `"Footnote Text"`, `"TOC 1"`…), which many templates never write into
879
+ `styles.xml` until used. Those are sent by their Word id; the paragraph
880
+ holds `w:pStyle` alone, the editor paints it from that definition and
881
+ the export adds the definition (with a list of the document's own for a
882
+ numbered list style), as Word does when the style is applied. Heading 1–9,
883
+ Title, Subtitle, Quote, Intense Quote, List Paragraph, No Spacing and
884
+ Caption are defined by hand to current Word's definitions
885
+ (`packages/core/src/prosemirror/styles/latentBuiltInStyles.ts`); the
886
+ others are python-docx's default template's, and docx4j's
887
+ `KnownStyles.xml` (Word 2007) for the ones it lacks
888
+ (`packages/core/src/docx/builtInStyles.generated.ts`). `"List Bullet 4"`/
889
+ `"5"` and `"List Number 4"`/`"5"` raise `KeyError`: python-docx's template
890
+ holds no numbering for them. Against an older docx-studio (no style table)
891
+ a built-in name is sent as its id and anything else as given.
892
+ `Run.style` follows the same rule for character styles: it returns a
893
+ `CharacterStyle` (Default Paragraph Font for a run naming none), and a
894
+ name the document lacks raises `KeyError` unless docx-studio holds Word's
895
+ definition of it (`BUILTIN_CHARACTER_STYLE_NAMES` in
896
+ `docx/styles/_table.py`: `"Strong"`, `"Intense Emphasis"`, `"Book Title"`…).
897
+ `Document.add_table(style=)` and `Paragraph.add_run(style=)` resolve the
898
+ style before creating anything, so a rejected style leaves the document
899
+ untouched; python-docx raises after adding the table or run to its
900
+ in-memory tree, but an edit here is live.
799
901
 
800
902
  - **`Document.add_table(rows, cols)` requires `rows >= 1` and
801
903
  `cols >= 1`.** Upstream allows a 0-row/0-col grid you later populate,
802
904
  but DOCX Studio's ProseMirror table node can't represent one; the SDK
803
905
  raises eagerly rather than failing opaquely on the wire.
804
906
 
907
+ - **`_Cell.merge` raises `InvalidSpanError` for every span that would cut
908
+ through a merged cell.** It merges what python-docx merges and refuses
909
+ what python-docx refuses (an L- or T-shaped pair of corners), but where
910
+ a cell inside the rectangle crosses its edge python-docx sometimes
911
+ raises `ValueError` (no `w:tc` at the rectangle's left edge) or writes a
912
+ vertical merge Word reads as broken. docx-studio applies the merge, so
913
+ `merge()` sends a request of its own and raises at the call.
914
+
915
+ - **`core_properties.modified` follows saves that change the package.**
916
+ `doc.core_properties` reads and writes `docProps/core.xml` as python-docx
917
+ does (docx-studio `Info` with `includeCoreProperties`, `SetCoreProperties`;
918
+ `DOCX_STUDIO_LIMITATIONS.md` § 8), but docx-studio stamps `modified` with
919
+ the time of a save that changes the package, a core property included, as
920
+ Word does, where python-docx never stamps it. A `modified` the script sets
921
+ wins in the save that writes it (a later save in the same batch stamps
922
+ again). Every read asks docx-studio, which saves the batch's edits before it
923
+ answers, so a read sees the stamp, and a collaborator's save. A package
924
+ without `docProps/core.xml` reads
925
+ every property as missing, where python-docx adds its own default part
926
+ (title "Word Document", last modified by "python-docx").
927
+
805
928
  - **`Comment.comment_id` returns `str`, not `int`.** DOCX Studio uses
806
929
  non-numeric entity ids (`"c-42"`), so the upstream `int` contract
807
930
  can't be honored. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
808
931
 
809
- - **`Section` dimension setters and `ParagraphFormat.line_spacing_rule
810
- = None` warn-and-preserve on a clear** rather than raising (upstream
811
- accepts `None` to clear, but DOCX Studio's merging mutation ops have no
812
- single-attribute clear). They emit a `Pending…ClearWarning` and leave
813
- the value intact instead of destructively clearing the whole block.
814
- Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
932
+ - **`add_comment` without an `author` stores the session's name, not
933
+ `""`.** `Document.add_comment` / `Comments.add_comment` send `author`
934
+ and `initials` and docx-studio stores them as `w:author` /
935
+ `w:initials`, as python-docx does; with none (python-docx's default
936
+ `""`) the author is `Document.user_name`, else `"Athena"`, and no
937
+ initials are stored (`initials` then reads `None`). The SDK raises
938
+ `ValueError` for what lxml refuses in an attribute, as python-docx
939
+ does, and also past docx-studio's caps (255 UTF-16 code units for an
940
+ author, 32 for initials); docx-studio turns tabs, line breaks and other
941
+ control characters into spaces. The author is display text only:
942
+ Keryx attributes the edit to the signed-in user (and agent), and
943
+ nothing reads a comment's author as identity.
944
+
945
+ - **`ParagraphFormat.line_spacing_rule = None` warns-and-preserves on a
946
+ clear** rather than raising (upstream accepts `None` to clear, but DOCX
947
+ Studio's merging mutation ops have no single-attribute clear). It emits a
948
+ `Pending…ClearWarning` and leaves the value intact instead of
949
+ destructively clearing the whole block. The `Section` dimension setters
950
+ remove the attribute for `None`, as upstream does (`null` on the wire),
951
+ on a docx-studio whose section read reports `clearsDimensions`; on an
952
+ older one they warn (`PendingSectionDimensionClearWarning`) and keep the
953
+ value. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
954
+
955
+ - **`Run.text` / `Paragraph.text` read Word's run elements as upstream
956
+ does** (`-` for a non-breaking hyphen, nothing for a soft hyphen or a
957
+ symbol; `\t` for a `w:ptab` in a room that holds it as a tab), but a tab or
958
+ break of an imported run can read as a run of its own. Writes keep text as
959
+ given. `Run.add_tab()` and `Run.add_break()` take the run's formatting, as
960
+ upstream appends them to the run's `w:r`; `Run.add_break(WD_BREAK.COLUMN)`
961
+ sends a column break (`breakType: "column"`), which docx-studio writes after
962
+ the paragraph's content. `DOCX_STUDIO_LIMITATIONS.md` §26.
963
+
964
+ - **Tracked changes read as Word's final view.** `Paragraph.text`, `runs`,
965
+ `iter_inner_content()`, `Hyperlink.text` / `runs` and `_Cell.text` include
966
+ the runs of a tracked insertion (`w:ins`) and leave out a deletion's
967
+ (`w:del`); upstream omits both, as it reads only a `w:p`'s direct `w:r` and
968
+ `w:hyperlink` children. Upstream cannot write tracked changes, so it has no
969
+ write-then-read case to match; with `track_revisions` on (the Athena
970
+ extension), `with doc.tracked_revisions(): p.text = "Updated forecast"`
971
+ deletes the old text and inserts the new, and upstream's omission would
972
+ read the paragraph back as `""`. Word's default views (Simple Markup, No
973
+ Markup) show insertions and hide deletions, as these reads do.
974
+ `doc.revisions` lists every change (`tests/test_run_text_python_docx.py`).
975
+
976
+ - **A field's runs read as python-docx reads them; some writes to them
977
+ differ.** `Paragraph.text` includes a complex field's displayed result and
978
+ `Paragraph.runs` holds its begin, field code, separate, result and end runs
979
+ (each with its own formatting), as python-docx reads the `w:r` children of
980
+ a `w:p`; a simple field (`w:fldSimple`) reads as nothing, and a field in a
981
+ link is the link's, as in python-docx. Each paragraph of a field that spans
982
+ paragraphs (a table of contents) holds the field character runs it has
983
+ (`tests/test_field_reads_python_docx_parity.py`, against stock python-docx
984
+ on the same `.docx`; `DOCX_STUDIO_LIMITATIONS.md` § 27). A field takes no
985
+ room in the text-address space, so its runs stand at one offset. Writes:
986
+ - setting a result run's `.text` changes the field's displayed result,
987
+ as in python-docx (`Replace` with a `field` target), but the export
988
+ writes a changed result of several runs as one run, in the first run's
989
+ formatting, and a result run read before the field's result changed
990
+ (through another read's run, or by a collaborator) raises
991
+ `FieldRunWriteError` rather than write over that change, where
992
+ python-docx's run is live;
993
+ - formatting a result run formats the field's whole result (`FormatApply`
994
+ with a `field` target), from its source formatting, where python-docx
995
+ formats that run alone;
996
+ - `.text` (and `clear()`) on a field character or field code run raises
997
+ `docx.errors.FieldRunWriteError` naming the field: python-docx replaces
998
+ the run's `w:fldChar` or `w:instrText` with the text, which breaks the
999
+ field;
1000
+ - formatting set on a field character or field code run is not applied and
1001
+ emits `PendingFieldRunFormatWarning` (those runs show nothing; docx-studio
1002
+ has no command that writes their own `w:rPr`), where python-docx writes
1003
+ it, so `for run in p.runs: run.bold = True` formats the text and the
1004
+ field's result and warns for the rest;
1005
+ - `add_text`, `add_tab`, `add_break`, `add_picture`, `add_field`,
1006
+ `add_footnote`, `add_endnote`, `add_math` and `add_cross_reference` on
1007
+ any of a field's runs raise `FieldRunWriteError`; python-docx appends to
1008
+ that `w:r`.
1009
+ A field that `Run.add_field` adds is a simple field, so it reads as no
1010
+ runs and no text, though docx-studio's export writes it as a complex field.
1011
+ Against a docx-studio that predates `fieldRun` reads, a field reads as no
1012
+ runs and no text, as before (`tests/test_field_runs.py`).
815
1013
 
816
1014
  ### If you need a deviation
817
1015
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: athena-python-docx
3
- Version: 0.25.0
3
+ Version: 0.27.0
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.25.0"
9
+ __version__ = "0.27.0"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import discard_all, flush_all
@@ -76,6 +76,7 @@ from docx.commands import (
76
76
  CreateMath,
77
77
  CreateParagraph,
78
78
  CreateSectionBreak,
79
+ CreateStyle,
79
80
  CreateTable,
80
81
  CreateTOC,
81
82
  CreateWatermark,
@@ -132,6 +133,7 @@ from docx.commands import (
132
133
  SetCellShading,
133
134
  SetChartData,
134
135
  SetChartType,
136
+ SetCoreProperties,
135
137
  SetImageAltText,
136
138
  SetImageAnchor,
137
139
  SetImageDecorative,
@@ -151,6 +153,8 @@ from docx.commands import (
151
153
  SetSectionPageSetup,
152
154
  SetSectionTitlePage,
153
155
  SetSectionsOddEvenHeadersFooters,
156
+ SetStyleFormatting,
157
+ SetStyleMetadata,
154
158
  SetTableBorders,
155
159
  TablesGet,
156
160
  TablesGetCells,
@@ -177,9 +181,11 @@ from docx.errors import (
177
181
  DocxStudioTemporarilyUnavailable,
178
182
  DocxUnsupportedCommandWarning,
179
183
  NotFoundError,
184
+ NotNumberedListItemError,
180
185
  SessionError,
181
186
  _missing_block_id,
182
187
  )
188
+ from docx.exceptions import InvalidSpanError
183
189
 
184
190
 
185
191
  _NOT_FOUND_ERROR_NAMES: frozenset[str] = frozenset(
@@ -632,6 +638,17 @@ def _http_post_json(
632
638
  err_obj = parsed.get("error") if isinstance(parsed, dict) else None
633
639
  if isinstance(err_obj, dict):
634
640
  base_msg = f"docx-studio batch reported a partial failure: {parsed!r}"
641
+ # A merge python-docx refuses (``_Cell.merge``) raises python-docx's
642
+ # own exception.
643
+ if err_obj.get("error") == "InvalidSpanError":
644
+ raise InvalidSpanError(
645
+ str(err_obj.get("message") or base_msg),
646
+ ).with_partial_applied(partial_applied)
647
+ # ``Paragraph.restart_numbering`` on a paragraph that takes no number.
648
+ if err_obj.get("error") == "NotNumberedListItem":
649
+ raise NotNumberedListItemError(
650
+ str(err_obj.get("message") or base_msg),
651
+ ).with_partial_applied(partial_applied)
635
652
  # ``BlockNotFoundError`` is the narrower miss — caller is most
636
653
  # likely targeting a cell-inner paragraph or stale-session
637
654
  # block id. Surface the typed exception plus an agent-readable
@@ -1011,6 +1028,10 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
1011
1028
  "format.paragraph.set_tab_stop": SetParagraphTabStop,
1012
1029
  "format.paragraph.clear_all_tab_stops": ClearParagraphTabStops,
1013
1030
  "styles.paragraph.set_style": SetParagraphStyle,
1031
+ "styles.set_formatting": SetStyleFormatting,
1032
+ "styles.set_metadata": SetStyleMetadata,
1033
+ "styles.create": CreateStyle,
1034
+ "core_properties.set": SetCoreProperties,
1014
1035
  # Sections
1015
1036
  "sections.set_page_margins": SetSectionPageMargins,
1016
1037
  "sections.set_page_setup": SetSectionPageSetup,
@@ -1069,8 +1090,8 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
1069
1090
  # consumed internally by ``Document.add_paragraph`` to make
1070
1091
  # ``style="List Bullet" | "List Number"`` produce real list
1071
1092
  # structure (not just a style attribute on a flat paragraph).
1072
- # ``lists.merge``/``lists.split`` stay typed-bus-only — no
1073
- # python-docx parity surface for them.
1093
+ # ``lists.split`` backs the Athena extension
1094
+ # ``Paragraph.restart_numbering``; ``lists.merge`` stays typed-bus-only.
1074
1095
  "lists.create": ListsCreate,
1075
1096
  "lists.attach": ListsAttach,
1076
1097
  "lists.merge": ListsMerge,