athena-python-docx 0.21.0__tar.gz → 0.21.2__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 (367) hide show
  1. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/CLAUDE.md +88 -57
  2. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/PKG-INFO +1 -4
  3. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/__init__.py +2 -2
  4. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_buffer.py +5 -5
  5. athena_python_docx-0.21.2/docx/_citations.py +154 -0
  6. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_http_doc.py +32 -24
  7. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_image_utils.py +3 -3
  8. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_postproc.py +48 -48
  9. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_references.py +1 -1
  10. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_timeouts.py +1 -1
  11. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/bookmarks.py +1 -1
  12. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/charts.py +1 -1
  13. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/client.py +1 -1
  14. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/commands.py +61 -61
  15. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/comments.py +23 -23
  16. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/document.py +57 -54
  17. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/enum/section.py +3 -3
  18. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/enum/table.py +5 -5
  19. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/enum/text.py +22 -22
  20. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/errors.py +11 -11
  21. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/footnotes.py +1 -1
  22. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/math.py +1 -1
  23. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/opc/coreprops.py +5 -6
  24. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/oxml/__init__.py +5 -5
  25. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/revisions.py +14 -14
  26. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/sdt.py +1 -1
  27. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/section.py +80 -80
  28. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/settings.py +4 -4
  29. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/shape.py +8 -8
  30. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/styles/style.py +31 -33
  31. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/styles/styles.py +11 -11
  32. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/table.py +128 -91
  33. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/hyperlink.py +4 -4
  34. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/pagebreak.py +9 -9
  35. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/paragraph.py +49 -46
  36. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/parfmt.py +12 -12
  37. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/run.py +32 -33
  38. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/tabstops.py +15 -15
  39. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/typing.py +2 -2
  40. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/pyproject.toml +1 -7
  41. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/docx_exec_lab_server.py +4 -4
  42. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/dump_wire_fixtures.py +1 -1
  43. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/round_trip_smoke.py +1 -1
  44. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/smoke_test_block_not_found.py +4 -4
  45. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/conftest.py +6 -6
  46. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/__init__.py +1 -1
  47. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/ab_probe_cases.py +2 -2
  48. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/ab_probe_runner.py +6 -6
  49. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/binary_round_trip.py +1 -1
  50. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/cases.py +1 -1
  51. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/complex_cases.py +5 -5
  52. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/extract.py +5 -5
  53. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/extreme_cases.py +2 -2
  54. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/fake_session.py +12 -12
  55. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/firm_templates/README.md +6 -6
  56. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/firm_templates/_runner.py +12 -11
  57. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/firm_templates/extractor.py +2 -2
  58. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/firm_templates/test_pw_corpus.py +13 -25
  59. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/firm_templates/test_pw_research_digest.py +10 -10
  60. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshot.py +1 -1
  61. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/ours_spec.json +7 -7
  62. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/real_world_cases.py +3 -3
  63. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/test_e2e_against_staging.py +20 -107
  64. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/intentional_deviations.json +1 -1
  65. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/snapshots/athena_latest.json +12 -12
  66. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_add_section_extract_items.py +5 -5
  67. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_batching_perf.py +1 -1
  68. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_block_not_found_error.py +12 -12
  69. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_add_paragraph_wire_shape.py +3 -3
  70. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_add_table_not_supported.py +3 -3
  71. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_inner_add_run_via_cell_insert.py +1 -1
  72. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_inner_format_stash.py +4 -4
  73. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_inner_run_guard.py +2 -2
  74. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_text_plain_fastpath.py +1 -1
  75. athena_python_docx-0.21.2/tests/test_citations.py +317 -0
  76. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_collapsed_range_format.py +3 -3
  77. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_commands.py +4 -4
  78. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_comments.py +4 -4
  79. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_document_clear.py +1 -1
  80. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_e2e_partial_failure_cascade.py +8 -8
  81. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_http_transport.py +2 -2
  82. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_hyperlink_coalescing.py +3 -3
  83. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_list_styles.py +2 -2
  84. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_merged_cell_secondary_slot.py +6 -6
  85. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_merged_cells.py +1 -1
  86. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_parity_misc.py +1 -1
  87. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_parity_round2.py +10 -10
  88. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_partial_failure_cascade.py +3 -3
  89. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_phase_a_behavior.py +1 -1
  90. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_phase_b_headers_footers.py +10 -10
  91. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_phase_c_tables.py +1 -1
  92. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_positional_cell_id.py +112 -7
  93. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_postproc_cell_format_rewrite.py +7 -7
  94. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_postproc_ref_restore.py +8 -8
  95. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_pr19766_review_fixes.py +2 -2
  96. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_python_docx_api_parity.py +2 -2
  97. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_revisions.py +13 -13
  98. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_add_paragraph_style.py +1 -1
  99. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_cell_add_paragraph.py +1 -1
  100. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_comments_add_comment.py +1 -1
  101. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_comments_get.py +1 -1
  102. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_document_audit.py +3 -3
  103. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_enum_section.py +8 -8
  104. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_header_footer.py +7 -7
  105. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_hyperlink.py +1 -1
  106. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_inline_shape.py +1 -1
  107. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_misc.py +20 -20
  108. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_paragraph_strict.py +1 -1
  109. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_paragraph_style_strict.py +1 -1
  110. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_parfmt.py +18 -18
  111. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_row_col_cell.py +1 -1
  112. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_run_style.py +1 -1
  113. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_run_style_strict.py +1 -1
  114. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_run_text.py +1 -1
  115. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_run_underline.py +1 -1
  116. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_section_audit.py +2 -2
  117. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_section_dimensions.py +6 -6
  118. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_section_onoff.py +1 -1
  119. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_settings.py +3 -3
  120. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_style.py +6 -6
  121. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_styles.py +10 -10
  122. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_table_dimensions.py +1 -1
  123. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_table_layout.py +2 -2
  124. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_style_font.py +3 -3
  125. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_style_setters_contract.py +10 -11
  126. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_table_set_cell_perf.py +1 -1
  127. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_wire_contract.py +12 -12
  128. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_zod_wire_contract.py +2 -2
  129. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/uv.lock +2 -114
  130. athena_python_docx-0.21.0/docx/_citations.py +0 -74
  131. athena_python_docx-0.21.0/tests/test_citations.py +0 -151
  132. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/.gitignore +0 -0
  133. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/DOCX_EXEC_LAB.md +0 -0
  134. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/README.md +0 -0
  135. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_athena_extension.py +0 -0
  136. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_batching.py +0 -0
  137. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_execution.py +0 -0
  138. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_http.py +0 -0
  139. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_ptc.py +0 -0
  140. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/_table_styles.py +0 -0
  141. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/api.py +0 -0
  142. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/enum/__init__.py +0 -0
  143. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/enum/shape.py +0 -0
  144. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/enum/style.py +0 -0
  145. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/exceptions.py +0 -0
  146. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/fields.py +0 -0
  147. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/opc/__init__.py +0 -0
  148. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/session.py +0 -0
  149. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/shared.py +0 -0
  150. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/styles/__init__.py +0 -0
  151. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/__init__.py +0 -0
  152. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/text/font.py +0 -0
  153. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/docx/toc.py +0 -0
  154. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/docx_exec_lab.py +0 -0
  155. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  156. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  157. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/publish.sh +0 -0
  158. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/release.sh +0 -0
  159. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/scripts/validate_find_replace_asset.py +0 -0
  160. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/__init__.py +0 -0
  161. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/METHODOLOGY.md +0 -0
  162. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/README.md +0 -0
  163. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/auto_gen_cases.py +0 -0
  164. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/coverage_report.py +0 -0
  165. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/firm_templates/__init__.py +0 -0
  166. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/local_runner.py +0 -0
  167. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/mega_cases.py +0 -0
  168. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  169. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  170. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  171. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  172. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  173. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  174. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  175. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  176. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  177. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  178. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  179. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  180. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  181. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  182. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  183. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  184. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  185. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  186. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  187. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  188. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  189. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  190. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  191. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  192. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  193. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  194. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  195. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  196. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  197. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  198. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  199. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  200. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  201. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  202. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  203. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  204. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  205. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  206. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  207. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  208. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  209. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  210. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  211. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  212. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  213. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  214. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  215. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  216. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  217. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  218. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  219. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  220. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  221. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  222. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  223. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  224. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  225. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  226. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  227. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  228. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  229. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  230. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  231. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  232. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  233. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  234. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  235. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  236. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  237. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  238. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  239. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  240. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  241. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  242. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  243. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  244. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  245. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  246. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  247. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  248. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  249. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  250. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  251. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  252. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  253. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  254. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  255. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  256. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  257. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  258. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  259. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  260. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  261. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  262. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  263. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  264. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  265. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  266. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  267. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  268. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  269. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  270. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  271. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  272. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  273. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  274. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  275. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  276. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  277. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  278. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  279. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  280. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  281. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  282. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  283. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  284. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  285. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  286. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  287. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  288. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  289. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  290. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  291. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  292. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  293. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  294. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  295. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  296. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  297. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  298. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  299. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  300. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  301. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  302. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  303. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  304. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  305. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  306. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  307. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  308. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  309. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  310. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  311. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  312. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  313. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  314. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  315. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/parity_crawl.py +0 -0
  316. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/parity_diff.json +0 -0
  317. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/round_trip_tests.py +0 -0
  318. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/fidelity/stock_spec.json +0 -0
  319. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/README.md +0 -0
  320. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/__init__.py +0 -0
  321. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/baseline_gaps.json +0 -0
  322. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/compare.py +0 -0
  323. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/introspect.py +0 -0
  324. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  325. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/reports/gap_report.json +0 -0
  326. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/run_parity.py +0 -0
  327. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  328. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/parity/test_parity_gap.py +0 -0
  329. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_athena_extensions_contract.py +0 -0
  330. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_athena_extensions_registry.py +0 -0
  331. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_buffer.py +0 -0
  332. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  333. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_inner_run_format_stash.py +0 -0
  334. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_cell_text_replace_semantics.py +0 -0
  335. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_command_dataclasses.py +0 -0
  336. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_document_asset_id_property.py +0 -0
  337. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_document_create.py +0 -0
  338. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_document_create_from_template.py +0 -0
  339. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_document_factory_validation.py +0 -0
  340. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_docx_exec_lab.py +0 -0
  341. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_docx_exec_lab_server.py +0 -0
  342. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_execution_scope.py +0 -0
  343. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_find_replace_session_open.py +0 -0
  344. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_image_url_data_uri.py +0 -0
  345. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_insert_deferred.py +0 -0
  346. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_iter_inner_content.py +0 -0
  347. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_oxml_shim.py +0 -0
  348. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_paragraph_text_len_cache.py +0 -0
  349. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  350. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_ptc.py +0 -0
  351. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_add_picture.py +0 -0
  352. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_add_run.py +0 -0
  353. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_document_element.py +0 -0
  354. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_font_audit.py +0 -0
  355. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  356. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_paragraph_style.py +0 -0
  357. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_run_add_break.py +0 -0
  358. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_run_bool_setters.py +0 -0
  359. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_shared_audit.py +0 -0
  360. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_table_audit.py +0 -0
  361. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_silent_stub_table_cell.py +0 -0
  362. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_smoke_integration.py +0 -0
  363. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_style_acceptance.py +0 -0
  364. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_table_style_id_resolution.py +0 -0
  365. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_temporarily_unavailable.py +0 -0
  366. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_validate_find_replace_asset_script.py +0 -0
  367. {athena_python_docx-0.21.0 → athena_python_docx-0.21.2}/tests/test_xml_attr_guard.py +0 -0
@@ -25,35 +25,35 @@ Before adding or modifying any API surface:
25
25
 
26
26
  Run `uv run pytest tests/test_python_docx_api_parity.py -v -s` to verify parity.
27
27
 
28
- ### Intentionally omitted (Superdoc SDK limitations)
28
+ ### Intentionally omitted (current SDK limitations)
29
29
 
30
- These standard python-docx members don't apply to a Superdoc-backed SDK:
30
+ 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
34
  - `Document.core_properties.last_modified_by` — we use Keryx attribution instead
35
- - `Document.settings` — Word app settings (not surfaced by Superdoc)
36
- - `InlineShape.chart` — charts (Phase 2+)
35
+ - `Document.settings` — Word app settings (not surfaced by DOCX Studio)
36
+ - `InlineShape.chart` — charts are not currently surfaced by the SDK.
37
37
  - `Comment.add_paragraph` / `Comment.add_table` /
38
38
  `Comment.iter_inner_content` / `Comment.paragraphs` /
39
- `Comment.tables` — SuperDoc models a comment as a single text body,
39
+ `Comment.tables` — DOCX Studio models a comment as a single text body,
40
40
  not a `BlockItemContainer`. Use `Comment.text` instead. The
41
41
  paragraph/table-bearing surface raises `CommentsNotImplementedError`.
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
45
- `NotImplementedError`) at runtime since 0.11.2. SuperDoc 1.8.1 has
46
- no anchor or content-fragment shape that places a new table inside
47
- an existing `tableCell` — `create.table` rejects cell-inner
45
+ `NotImplementedError`) at runtime since 0.11.2. The current
46
+ docx-editor command surface has no anchor or content-fragment shape
47
+ that places a new table inside an existing `tableCell` — `create.table` rejects cell-inner
48
48
  paragraph anchors with `INVALID_TARGET`, and the `doc.insert`
49
49
  workaround used by `_Cell.add_paragraph` doesn't generalize
50
50
  because the apps/api `Insert` schema doesn't yet forward
51
- `nestingPolicy: {tables: "allow"}` and the SuperDoc table-content
51
+ `nestingPolicy: {tables: "allow"}` and the DOCX editor table-content
52
52
  fragment shape isn't documented. Tracked at
53
- `docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md` § 13.
53
+ `docx-studio/DOCX_STUDIO_LIMITATIONS.md` § 13.
54
54
  - **`docx.oxml.*`** — the entire raw-OOXML module tree (``ns.qn``,
55
55
  ``OxmlElement``, ``CT_*`` classes, etc.) is unavailable because the
56
- SDK is HTTP-only against a SuperDoc Y.Doc; there is no local lxml
56
+ SDK is HTTP-only against a DOCX Studio Y.Doc; there is no local lxml
57
57
  tree to manipulate. As of 0.8.0, ``docx.oxml`` is a real stub
58
58
  package that raises a typed
59
59
  :class:`docx.oxml.OxmlNotAvailableError` (subclass of
@@ -64,21 +64,21 @@ These standard python-docx members don't apply to a Superdoc-backed SDK:
64
64
  generic ``ModuleNotFoundError: No module named 'docx.oxml'`` and
65
65
  agents had to retry to discover the gap.
66
66
 
67
- ### Phase-3b upstream-blocked surface
67
+ ### Known partially supported surface
68
68
 
69
69
  These are *shipped at the surface* but partially or fully no-op at
70
- runtime, pending DOCX Studio backend changes. See
71
- `docx-studio/PYTHON_DOCX_PARITY_GAPS.md` § *What unblocks the
72
- remaining work* for the exact wire-op shape needed to unblock each.
70
+ runtime, pending additional docx-editor command support. Behavior should be
71
+ pinned by focused tests and documented in
72
+ `docx-studio/DOCX_STUDIO_LIMITATIONS.md`.
73
73
 
74
74
  - **24 setters on `BaseStyle` / `CharacterStyle` / `ParagraphStyle`**
75
75
  (`name`, `style_id`, `hidden`, `locked`, `priority`, `quick_style`,
76
76
  `unhide_when_used`, `base_style`, `next_paragraph_style`) emit
77
77
  `PendingStyleMutationWarning` and stash on `_overrides`.
78
- SuperDoc 1.7's `doc.styles.apply` is constrained to
78
+ The current `doc.styles.apply` command surface is constrained to
79
79
  `target.scope: "docDefaults"` — no per-style metadata variant.
80
80
  Behavior pinned by `tests/test_style_setters_contract.py` (11
81
- tests); when SuperDoc lands a metadata op, those tests will need
81
+ tests); when docx-editor lands a metadata op, those tests will need
82
82
  to flip to assert real bus calls.
83
83
  - **`Styles.latent_styles`** returns an empty `_LatentStyles` —
84
84
  `DocInfoResult.styles` only surfaces `paragraphStyles[]` (a flat
@@ -119,12 +119,12 @@ not file-backed. Each is documented in the relevant docstring.
119
119
  and silently falls back to ``Normal Table`` (no borders, no
120
120
  header fill, no banding). Custom user-defined style names pass
121
121
  through unchanged. Whether Word actually renders a Word 2013+
122
- style after resolution also depends on SuperDoc's exported
122
+ style after resolution also depends on the exported
123
123
  ``styles.xml`` containing the matching ``<w:style w:type="table">``
124
- definition — at SuperDoc 1.8.1 the exported ``styles.xml`` only
125
- carries the Word 2007 set, so Word 2013+ styleIds resolve in the
126
- ``<w:tblStyle>`` element but still fall back to ``Normal Table``
127
- until SuperDoc upstream ships an expanded ``styles.xml``.
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``.
128
128
 
129
129
  - **`Document.create(name=, base_url=, api_key=, parent_folder_id=, workspace_id=, docx=, agora_base_url=)`**
130
130
  classmethod. Stock python-docx returns a blank in-memory document
@@ -164,14 +164,14 @@ not file-backed. Each is documented in the relevant docstring.
164
164
  When a path or stream IS supplied, the SDK cannot fulfill the
165
165
  implied "write bytes to this target" contract, so the call raises
166
166
  loudly rather than silently flushing — agents must use Olympus's
167
- Export DOCX (which goes through the SuperDoc session that already
167
+ Export DOCX (which goes through the DOCX Studio session that already
168
168
  has the bytes) instead of expecting a local file.
169
169
 
170
170
  - **`Document.track_revisions: bool`** — when `True`, all subsequent
171
171
  mutations are recorded as tracked revisions instead of direct edits.
172
172
  python-docx upstream has no top-level toggle (the closest is
173
173
  hand-edited `<w:trackChanges/>` on `Document.settings.element`).
174
- We expose this as a Document-level property because every SuperDoc
174
+ We expose this as a Document-level property because every DOCX Studio
175
175
  mutation accepts a per-call `changeMode` envelope field. The
176
176
  python-docx-parity alias `Document.settings.track_revisions` reads
177
177
  and writes the same flag so call sites that walk `doc.settings`
@@ -184,10 +184,10 @@ not file-backed. Each is documented in the relevant docstring.
184
184
  because the upstream package has no track-changes API at all.
185
185
 
186
186
  - **`Document.user_name: str | None` / `Document.user_email: str |
187
- None`** — author identity threaded through to SuperDoc on session-
187
+ None`** — author identity threaded through to DOCX Studio on session-
188
188
  open for tracked-change attribution. python-docx's
189
189
  `Document.core_properties.last_modified_by` is the closest upstream
190
- surface; we use the SuperDoc-native fields directly because SuperDoc
190
+ surface; we use the DOCX Studio-native fields directly because DOCX Studio
191
191
  bakes them into the change records.
192
192
 
193
193
  - **`Document.revisions: Revisions`** — collection of tracked changes
@@ -195,7 +195,7 @@ not file-backed. Each is documented in the relevant docstring.
195
195
  `accept(id)`, `reject(id)`. Per-revision `Revision.accept()` /
196
196
  `Revision.reject()` resolve a single change. python-docx upstream
197
197
  has zero track-changes API, so this entire surface is an Athena
198
- extension wired to SuperDoc's `doc.trackChanges.{list,get,decide}`.
198
+ extension wired to DOCX Studio's `doc.trackChanges.{list,get,decide}`.
199
199
 
200
200
  ### Athena extensions for most-requested upstream features (v0.11.0+)
201
201
 
@@ -213,7 +213,7 @@ Issue numbers reference `python-openxml/python-docx`.
213
213
  tooltip=None) -> Hyperlink`** — appends a hyperlinked run.
214
214
  python-docx surfaces `Hyperlink` as read-only; PR #74 has been open
215
215
  since 2014 and is the single most-requested missing feature. Routes
216
- through `CreateHyperlink` (SuperDoc `doc.hyperlinks.create`). Returns
216
+ through `CreateHyperlink` (DOCX Studio `doc.hyperlinks.create`). Returns
217
217
  the same `Hyperlink` class the read path already exposes. Also
218
218
  available as `Run.add_hyperlink` for convenience.
219
219
 
@@ -293,7 +293,7 @@ Issue numbers reference `python-openxml/python-docx`.
293
293
  metadata. python-docx PR #1530 is in flight but unreleased; the
294
294
  feature has been requested for years. Routes through
295
295
  `SetImageAltText` / `SetImageDecorative` (already wired in
296
- SuperDoc).
296
+ DOCX Studio).
297
297
 
298
298
  - **`InlineShape.anchor(*, wrap="square", position_x_pt=,
299
299
  position_y_pt=, relative_from_x=, relative_from_y=,
@@ -370,13 +370,13 @@ Issue numbers reference `python-openxml/python-docx`.
370
370
  include_revisions=False) -> bytes`** — render to PDF via the
371
371
  Daytona-hosted LibreOffice. python-docx issue #113 was closed as
372
372
  wontfix upstream but the request keeps recurring. Routes through
373
- `ExportPDF` (SuperDoc handles the actual conversion).
373
+ `ExportPDF` (DOCX Studio handles the actual conversion).
374
374
 
375
375
  - **`Document.clear()`** (0.14.0+) — empty the document body so subsequent
376
376
  writes start from a clean slate. python-docx has no equivalent (it
377
377
  operates on local files where the caller can simply construct a new
378
378
  ``Document``). Iterates every top-level paragraph and table cell and
379
- empties their text content. Block structure is preserved (SuperDoc has
379
+ empties their text content. Block structure is preserved (DOCX Studio has
380
380
  no wire op to delete blocks today), so post-clear the doc holds N
381
381
  empty paragraphs rather than collapsing to a single one — for a truly
382
382
  empty body, call ``Document.create()`` to mint a fresh asset instead.
@@ -395,6 +395,27 @@ Issue numbers reference `python-openxml/python-docx`.
395
395
  the citation-blue highlight to the destination paragraph/range. It is
396
396
  not a live link and does not overwrite destination text.
397
397
 
398
+ Use citations as evidence, not as generic source mentions.
399
+ ``Paragraph.add_citation(...)`` highlights the whole paragraph in Athena, so
400
+ make the destination unit match the evidence: a metric cell/table row for a
401
+ number, one short sentence for a claim, or one short paragraph only when the
402
+ same source supports the full paragraph. If only a few words or numbers in a
403
+ long paragraph are supported, split that claim into its own sentence,
404
+ paragraph, or table row before citing it. Do not add duplicate citations to
405
+ every rendered line when one citation on the semantic claim/table row is
406
+ sufficient.
407
+ Use a mention/reference instead when you only need to point at a related
408
+ source without claiming evidentiary support. For PDFs, prefer a tight page
409
+ text anchor or a page anchor with an ``excerpt`` containing the exact
410
+ phrase/number being supported, not just a broad section title.
411
+
412
+ Prefer a canonical citation string when the source/anchor is already known
413
+ as a Spaces URL, or when the source type is not modeled by the DOCX SDK
414
+ (video/audio time ranges, browser sessions, external URLs, etc.). Typed
415
+ ``AssetReference`` + anchor objects are still useful convenience helpers for
416
+ common Athena assets such as spreadsheets and PDFs, but they are not the only
417
+ valid source form.
418
+
398
419
  Common agent pattern after writing a supported claim:
399
420
 
400
421
  ```python
@@ -403,6 +424,16 @@ Issue numbers reference `python-openxml/python-docx`.
403
424
 
404
425
  doc = Document("asset_word")
405
426
  p = doc.add_paragraph("The combined assessment identified 20,049 total vulnerabilities.")
427
+
428
+ # Preferred generic path: pass a canonical Spaces URL or https URL.
429
+ citation_id = p.add_citation(
430
+ "/dashboard/spaces/?asset_ids=asset_spreadsheet&type=spreadsheet"
431
+ "&anchor=sheet_range&sheet_id=0&range=B2%3AB8",
432
+ excerpt="20,049 total vulnerabilities",
433
+ display_value="Vulnerability total",
434
+ )
435
+
436
+ # Typed helper path: still fine when the SDK has the source/anchor dataclasses.
406
437
  citation_id = p.add_citation(
407
438
  AssetReference(id="asset_spreadsheet"),
408
439
  anchor=SheetRangeAnchor(sheet_id=0, range="B2:B8"),
@@ -444,7 +475,7 @@ Issue numbers reference `python-openxml/python-docx`.
444
475
  Format ops on cell-inner paragraphs (`paragraph.alignment`,
445
476
  `paragraph.style`, every `paragraph_format` setter, and
446
477
  `paragraph.add_hyperlink`) used to cascade-fail the entire HTTP
447
- batch. SuperDoc 1.8.1's
478
+ batch. The current docx-editor applier's
448
479
  ``SetParagraphAlignment``/``SetParagraphStyle``/``SetParagraphIndentation``/``SetParagraphSpacing``/``CreateHyperlink``
449
480
  reject cell-inner block targets with ``BlockNotFoundError``, and the
450
481
  applier's all-or-nothing batch model meant one cell-paragraph
@@ -458,7 +489,7 @@ instead of forwarding the broken command. The format op is dropped,
458
489
  the surrounding batch survives, and the workaround pointer (
459
490
  ``cell.text = 'value'`` to materialize, then ``cell.paragraphs[0]``
460
491
  for the addressable proxy) is in the warning text. Tracked at
461
- ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md`` § 13.
492
+ ``docx-studio/DOCX_STUDIO_LIMITATIONS.md`` § 13.
462
493
 
463
494
  **0.11.5 follow-up: post-export OOXML rewrite.** When the parent
464
495
  table was created via ``Document.add_table`` in this session
@@ -468,7 +499,7 @@ OOXML-shaped props (``alignment``, ``style``, ``left_twips``,
468
499
  :class:`docx._postproc.PostExportOps` collector). ``Document.export_docx``
469
500
  applies them via an OOXML rewrite of ``word/document.xml`` before
470
501
  returning bytes — so the **exported ``.docx`` carries the formatting
471
- the agent asked for** even though SuperDoc never accepted the wire
502
+ the agent asked for** even though DOCX Studio never accepted the wire
472
503
  op. Live-session state is unchanged (Olympus collaborators don't
473
504
  see the formatting until export). Template-seeded tables where
474
505
  ``_doc_index`` is ``None`` still warn-and-skip (no stable OOXML
@@ -487,7 +518,7 @@ helper pattern —
487
518
 
488
519
  — used to silently drop both the ``Hello world`` text AND the bold
489
520
  format because ``Paragraph.add_run`` on a cell-inner paragraph
490
- returned a stub Run with collapsed range, and SuperDoc 1.8.1
521
+ returned a stub Run with collapsed range, and the docx-editor applier
491
522
  rejected the wire-level ``doc.insert`` against the cell-inner
492
523
  paragraph's blockId with ``Block <id> not found``. The 0.13.0 fix
493
524
  adds a ``_cell`` back-reference to every cell-inner Paragraph proxy
@@ -497,7 +528,7 @@ called on a cell-inner paragraph with non-empty text AND the
497
528
  back-ref is set, the SDK ships ``doc.insert(target=cell,
498
529
  placement="insideEnd", content=paragraph-fragment-with-text)``
499
530
  instead — the SAME wire path ``_Cell.add_paragraph(text)`` already
500
- uses. SuperDoc collapses the new paragraph into the cell's single
531
+ uses. DOCX Studio collapses the new paragraph into the cell's single
501
532
  template paragraph as an inline run; the exported DOCX expands each
502
533
  non-empty inline run into its own ``<w:p>``. The returned Run is
503
534
  real (non-collapsed range) and carries the new exported-paragraph
@@ -524,10 +555,10 @@ of dropping it silently at the wire layer. The post-export rewrite
524
555
  walks every ``<w:r>`` in the targeted cell paragraph and injects
525
556
  ``<w:rPr>`` carrying the props — so ``cell.text = "Total"; cell.
526
557
  paragraphs[0].runs[0].bold = True`` produces a bold ``Total`` in
527
- the exported ``.docx`` even though SuperDoc never committed the
558
+ the exported ``.docx`` even though DOCX Studio never committed the
528
559
  format wire op. Apply-to-all-runs semantics: the rewrite targets
529
560
  every ``<w:r>`` in the cell paragraph, because run-level addressing
530
- inside a cell isn't recoverable after SuperDoc collapses cell-
561
+ inside a cell isn't recoverable after DOCX Studio collapses cell-
531
562
  inner inserts. Multi-run cell paragraphs with partial-run
532
563
  formatting are a documented limitation — agents should use one
533
564
  run per format intent.
@@ -550,7 +581,7 @@ rels entry so the rels file doesn't grow unboundedly. Behavior
550
581
  pinned by ``tests/test_postproc_cell_run_format_rewrite.py``.
551
582
 
552
583
  Live Olympus rendering still won't show cell-inner formatting or
553
- hyperlinks until SuperDoc lands the corresponding wire ops —
584
+ hyperlinks until DOCX Studio lands the corresponding wire ops —
554
585
  ``Document.export_docx`` is the source of truth for the
555
586
  deliverable until then.
556
587
 
@@ -565,7 +596,7 @@ deliverable until then.
565
596
  workaround pointer and avoids re-issuing the slow query.
566
597
  - **`Table._fresh_node_info` rotation tracking.** Each ``Table``
567
598
  created via ``Document.add_table`` records its document-order
568
- position as ``_doc_index``. When SuperDoc rotates the table's
599
+ position as ``_doc_index``. When DOCX Studio rotates the table's
569
600
  nodeId between saves, the fallback resolves the rotated address
570
601
  by position instead of always picking the last ``doc.find`` item.
571
602
  Pre-0.11.4 the "take the last" heuristic silently mapped N
@@ -584,18 +615,18 @@ deliverable until then.
584
615
  every other field kind) now emits ``at.segments`` with
585
616
  ``[{blockId, start, end}]`` instead of the ``{kind: "selection",
586
617
  start, end}`` cursor envelope used by other create-ops.
587
- SuperDoc's ``doc.fields.insert`` rejects the cursor form with
588
- ``SuperDocCliError: fields insert:at.segments is required``;
618
+ DOCX Studio's ``doc.fields.insert`` rejects the cursor form with
619
+ ``DocxStudioCommandError: fields insert:at.segments is required``;
589
620
  pre-0.11.4 the call took down the whole batch on every flush.
590
621
 
591
622
  ### 0.11.5 — `REF` field round-trip preservation (post-export rewrite)
592
623
 
593
- SuperDoc 1.23.1 / SDK 1.8.1 strips ``REF`` field codes
624
+ The DOCX editor import/export path can strip ``REF`` field codes
594
625
  (``<w:fldChar>`` / ``<w:instrText REF …>`` / result-runs / end
595
626
  ``<w:fldChar>``) on import. On the Paul Weiss Purchase Agreement
596
627
  this loses all 301 cross-references — readers see chains of empty
597
628
  commas instead of "Section 3.02(b)" cross-refs. Tracked at
598
- ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md`` § 18.
629
+ ``docx-studio/DOCX_STUDIO_LIMITATIONS.md`` § 18.
599
630
 
600
631
  As of 0.11.5, ``Document.create(docx=template.docx)`` scans the
601
632
  local template bytes with a stdlib zipfile + xml.etree parser and
@@ -614,7 +645,7 @@ same Python process that called ``Document.create(docx=...)`` also
614
645
  calls ``export_docx``. Cross-process flows (agent A creates, agent
615
646
  B exports) need agora-side persistence (separate follow-up). (2)
616
647
  Paragraph-wholesale replacement preserves the source paragraph but
617
- overwrites any SuperDoc in-paragraph edits — for round-trip
648
+ overwrites any DOCX Studio in-paragraph edits — for round-trip
618
649
  preservation (the primary use case) this is exactly right. (3) Only
619
650
  top-level body paragraphs are scanned; cell-inner REFs aren't
620
651
  captured (rare for legal cross-references).
@@ -643,9 +674,9 @@ routing, `add_picture` native size + aspect ratio, `WD_BUILTIN_STYLE`
643
674
  and `CoreProperties` validation. These are not deviations — they close
644
675
  gaps. The items below are the **residual intentional deviations** that
645
676
  remain because matching upstream would break the asset-backed/HTTP
646
- architecture or a SuperDoc constraint:
677
+ architecture or a DOCX Studio constraint:
647
678
 
648
- - **`WD_*` enum `.value` is the SuperDoc wire string, not the MS Word
679
+ - **`WD_*` enum `.value` is the DOCX Studio wire string, not the MS Word
649
680
  integer constant.** `WD_ALIGN_PARAGRAPH.CENTER.value == "center"`
650
681
  (upstream: `1`); `int(member)` / `member == 1` / `WD_*(1)` therefore
651
682
  differ. The string value is load-bearing — every command serializes
@@ -661,7 +692,7 @@ architecture or a SuperDoc constraint:
661
692
  stripped before the (otherwise byte-identical) upstream slice parse.
662
693
  A strict superset — every value upstream accepts parses identically.
663
694
 
664
- - **`_Cell.vertical_alignment` setter accepts the four SuperDoc wire
695
+ - **`_Cell.vertical_alignment` setter accepts the four DOCX Studio wire
665
696
  tokens** (`"top"`/`"center"`/`"bottom"`/`"both"`) in addition to
666
697
  `WD_ALIGN_VERTICAL` members. Upstream rejects all plain strings; this
667
698
  is an ergonomic superset (typos like `"middle"` still raise
@@ -685,19 +716,19 @@ architecture or a SuperDoc constraint:
685
716
 
686
717
  - **`Document.add_table(rows, cols)` requires `rows >= 1` and
687
718
  `cols >= 1`.** Upstream allows a 0-row/0-col grid you later populate,
688
- but SuperDoc's ProseMirror table node can't represent one; the SDK
719
+ but DOCX Studio's ProseMirror table node can't represent one; the SDK
689
720
  raises eagerly rather than failing opaquely on the wire.
690
721
 
691
- - **`Comment.comment_id` returns `str`, not `int`.** SuperDoc uses
722
+ - **`Comment.comment_id` returns `str`, not `int`.** DOCX Studio uses
692
723
  non-numeric entity ids (`"c-42"`), so the upstream `int` contract
693
- can't be honored. Tracked in `SUPERDOC_UPSTREAM_REQUESTS.md`.
724
+ can't be honored. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
694
725
 
695
726
  - **`Section` dimension setters and `ParagraphFormat.line_spacing_rule
696
727
  = None` warn-and-preserve on a clear** rather than raising (upstream
697
- accepts `None` to clear, but SuperDoc's merging mutation ops have no
728
+ accepts `None` to clear, but DOCX Studio's merging mutation ops have no
698
729
  single-attribute clear). They emit a `Pending…ClearWarning` and leave
699
730
  the value intact instead of destructively clearing the whole block.
700
- Tracked in `SUPERDOC_UPSTREAM_REQUESTS.md`.
731
+ Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
701
732
 
702
733
  ### If you need a deviation
703
734
 
@@ -723,13 +754,13 @@ This is a **thin HTTP client** that mimics the sync python-docx API.
723
754
  (a `SessionError`) carrying `http_status` and an optional
724
755
  `retry_after_seconds` parsed from the server's `Retry-After` header.
725
756
  Agent code can catch this typed error to back off at the agent level
726
- vs. treating it as a script bug. The legacy `transport="direct"`
727
- (embedded Superdoc CLI + y-websocket from Python) was removed in
728
- 0.5.0; agent pods no longer embed Superdoc.
757
+ vs. treating it as a script bug. The former `transport="direct"`
758
+ (embedded DOCX Studio CLI + y-websocket from Python) was removed in
759
+ 0.5.0; agent pods no longer embed DOCX Studio.
729
760
  - **Transparent batching (0.7.0+):** Create* commands
730
761
  (`CreateParagraph`, `CreateHeading`, `CreateTable`, `CreateImage`)
731
762
  ALWAYS pre-mint a client-side UUID (`client_node_id`) and defer
732
- through the buffer. The applier resolves UUIDs to real SuperDoc
763
+ through the buffer. The applier resolves UUIDs to real DOCX Studio
733
764
  ids via per-batch `clientIdMap` on flush, and the buffer rewrites
734
765
  each proxy's `_node_id` in-place. Net result: 30 `add_paragraph`
735
766
  calls = 1 HTTP request, with no explicit `batch()` context manager
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: athena-python-docx
3
- Version: 0.21.0
3
+ Version: 0.21.2
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>
@@ -21,9 +21,6 @@ Requires-Dist: pytest>=8.0; extra == 'dev'
21
21
  Requires-Dist: python-docx>=1.1; extra == 'dev'
22
22
  Requires-Dist: responses>=0.24; extra == 'dev'
23
23
  Requires-Dist: ruff>=0.3; extra == 'dev'
24
- Provides-Extra: fidelity
25
- Requires-Dist: httpx>=0.27; extra == 'fidelity'
26
- Requires-Dist: superdoc-sdk>=1.8.0; extra == 'fidelity'
27
24
  Description-Content-Type: text/markdown
28
25
 
29
26
  # athena-python-docx
@@ -1,12 +1,12 @@
1
1
  """athena-python-docx — drop-in replacement for python-docx.
2
2
 
3
- Calls translate into Superdoc SDK operations against a Keryx Y.Doc.
3
+ Calls translate into DOCX Studio SDK operations against a Keryx Y.Doc.
4
4
  See CLAUDE.md for the API parity contract.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.21.0"
9
+ __version__ = "0.21.2"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import flush_all
@@ -8,7 +8,7 @@ ships as one HTTP request instead of N.
8
8
  Create* commands are deferred because the SDK pre-mints a client-side
9
9
  UUID for every new node (see ``Document._mint_client_node_id``). The
10
10
  proxy returned to the caller is stamped with that UUID; the applier
11
- resolves UUIDs to real SuperDoc ids via ``clientIdMap`` and echoes the
11
+ resolves UUIDs to real DOCX Studio ids via ``clientIdMap`` and echoes the
12
12
  mapping back, at which point the buffer rewrites each proxy's
13
13
  ``_node_id``. This makes batching invisible at the call site — user
14
14
  code looks like python-docx, runs at python-docx-batched speed.
@@ -49,7 +49,7 @@ def _apply_proxy_id_rewrites(
49
49
  proxy_id_refs: "dict[str, list[tuple[object, str]]]",
50
50
  ) -> None:
51
51
  """Walk ``results`` and rewrite registered proxy ids from client UUIDs
52
- to the real SuperDoc ids the applier echoed back.
52
+ to the real DOCX Studio ids the applier echoed back.
53
53
 
54
54
  Shared by the success path in :meth:`CommandBuffer.flush` /
55
55
  :meth:`_eager_flush_with` AND by the **partial-failure recovery
@@ -287,7 +287,7 @@ class CommandBuffer:
287
287
 
288
288
  Create* commands defer because the SDK pre-mints a client-side UUID
289
289
  (``client_node_id`` / ``client_entity_id``); the applier translates
290
- the UUID to a real SuperDoc id in a per-batch ``clientIdMap`` and
290
+ the UUID to a real DOCX Studio id in a per-batch ``clientIdMap`` and
291
291
  echoes the mapping back so the SDK can rewrite each proxy's
292
292
  ``_node_id`` on flush.
293
293
  """
@@ -385,7 +385,7 @@ class CommandBuffer:
385
385
  def set_user(self, name: str | None, email: str | None = None) -> None:
386
386
  """Set the batch-level user identity.
387
387
 
388
- Sent on every commands request envelope. SuperDoc honors the
388
+ Sent on every commands request envelope. DOCX Studio honors the
389
389
  identity at session-open time only — subsequent batches against
390
390
  a pooled session ignore the value, but the payload is still
391
391
  included so a fresh session picks it up.
@@ -415,7 +415,7 @@ class CommandBuffer:
415
415
  ``client_entity_id`` — appends to the queue, resets the idle
416
416
  timer, and returns ``None``. Caller MUST NOT rely on the return
417
417
  value of a buffered mutation. For deferred Creates, the
418
- applier resolves the client UUID to a real SuperDoc id via
418
+ applier resolves the client UUID to a real DOCX Studio id via
419
419
  ``clientIdMap`` on flush and the buffer rewrites each registered
420
420
  proxy's ``_node_id`` in-place.
421
421
  """
@@ -0,0 +1,154 @@
1
+ """Helpers for SDK-native Athena citations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import uuid
6
+ from typing import Any
7
+ from urllib.parse import parse_qs, urlparse
8
+
9
+ from docx._references import AssetReference
10
+ from docx.commands import AddCitation
11
+
12
+
13
+ _ATHENA_SPACES_HOST_SUFFIXES: tuple[str, ...] = (
14
+ "athenaintel.com",
15
+ "athenaintelligence.ai",
16
+ )
17
+
18
+
19
+ def new_citation_id() -> str:
20
+ return f"citation_{uuid.uuid4().hex[:12]}"
21
+
22
+
23
+ def _is_athena_spaces_host(hostname: str | None) -> bool:
24
+ host = (hostname or "").lower()
25
+ return any(
26
+ host == suffix or host.endswith(f".{suffix}")
27
+ for suffix in _ATHENA_SPACES_HOST_SUFFIXES
28
+ )
29
+
30
+
31
+ def source_ref_to_dict(source: AssetReference) -> dict[str, Any]:
32
+ if not isinstance(source, AssetReference):
33
+ raise TypeError(f"source must be an AssetReference; got {type(source).__name__}")
34
+ return source.to_dict()
35
+
36
+
37
+ def normalize_citation_string(citation_string: str) -> str:
38
+ value = citation_string.strip()
39
+ if not value:
40
+ raise ValueError("citation_string must not be empty")
41
+
42
+ parsed = urlparse(value)
43
+ if parsed.scheme in ("http", "https") and parsed.netloc:
44
+ if parsed.path.rstrip("/") == "/dashboard/spaces":
45
+ if not _is_athena_spaces_host(parsed.hostname):
46
+ raise ValueError(
47
+ "absolute Athena Spaces citation URLs must use an Athena host"
48
+ )
49
+ asset_ids = parse_qs(parsed.query).get("asset_ids")
50
+ if not asset_ids or not asset_ids[0]:
51
+ raise ValueError("Athena Spaces citation URLs must include asset_ids")
52
+ return value
53
+
54
+ if not parsed.scheme and value.startswith("/"):
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
+ )
61
+ if relative.path.rstrip("/") == "/dashboard/spaces":
62
+ asset_ids = parse_qs(relative.query).get("asset_ids")
63
+ if asset_ids and asset_ids[0]:
64
+ return value
65
+ raise ValueError("Athena Spaces citation URLs must include asset_ids")
66
+
67
+ raise ValueError(
68
+ "citation_string must be a serialized citation URL, such as "
69
+ "'/dashboard/spaces/?asset_ids=...' or an 'https://...' URL"
70
+ )
71
+
72
+
73
+ def anchor_to_dict(anchor: object | None) -> dict[str, Any] | None:
74
+ if anchor is None:
75
+ return None
76
+ if not hasattr(anchor, "to_dict"):
77
+ raise TypeError(
78
+ "anchor must be an Anchor dataclass (SheetRangeAnchor, "
79
+ f"PmNodeAnchor, etc.) — got {type(anchor).__name__}"
80
+ )
81
+ value = anchor.to_dict()
82
+ if not isinstance(value, dict) or not value.get("type"):
83
+ raise TypeError("anchor.to_dict() must return a dict with a 'type' field")
84
+ return value
85
+
86
+
87
+ def destination_anchor_to_dict(destination_anchor: object) -> dict[str, Any]:
88
+ if hasattr(destination_anchor, "to_dict"):
89
+ destination_anchor = destination_anchor.to_dict()
90
+ if not isinstance(destination_anchor, dict):
91
+ raise TypeError(
92
+ "destination_anchor must be a PmNodeAnchor, PmNodeRangeAnchor, or wire dict"
93
+ )
94
+ anchor_type = destination_anchor.get("type")
95
+ if anchor_type == "pm_node" and destination_anchor.get("nodeId"):
96
+ return dict(destination_anchor)
97
+ if (
98
+ anchor_type == "pm_node_range"
99
+ and destination_anchor.get("startNodeId")
100
+ and destination_anchor.get("endNodeId")
101
+ ):
102
+ return dict(destination_anchor)
103
+ raise ValueError(
104
+ "destination_anchor must be {'type':'pm_node','nodeId':...} or "
105
+ "{'type':'pm_node_range','startNodeId':...,'endNodeId':...}"
106
+ )
107
+
108
+
109
+ def build_add_citation_command(
110
+ *,
111
+ destination_anchor: object,
112
+ source: AssetReference | str | None,
113
+ anchor: object | None,
114
+ citation_string: str | None,
115
+ excerpt: str | None,
116
+ display_value: str | None,
117
+ ) -> tuple[str, AddCitation]:
118
+ source_ref: dict[str, Any] | None
119
+ if isinstance(source, str):
120
+ if (
121
+ citation_string is not None
122
+ and normalize_citation_string(citation_string)
123
+ != normalize_citation_string(source)
124
+ ):
125
+ raise ValueError("Pass citation_string either positionally or by keyword, not both")
126
+ citation_string = source
127
+ source_ref = None
128
+ elif source is None:
129
+ source_ref = None
130
+ else:
131
+ if citation_string is not None:
132
+ raise ValueError("Pass either an AssetReference source or citation_string, not both")
133
+ source_ref = source_ref_to_dict(source)
134
+
135
+ normalized_citation_string = (
136
+ normalize_citation_string(citation_string)
137
+ if citation_string is not None
138
+ else None
139
+ )
140
+ if source_ref is None and normalized_citation_string is None:
141
+ raise ValueError("source or citation_string is required")
142
+ if source_ref is None and anchor is not None:
143
+ raise ValueError("anchor requires an AssetReference source; encode the anchor in citation_string instead")
144
+
145
+ citation_id = new_citation_id()
146
+ return citation_id, AddCitation(
147
+ destination_anchor=destination_anchor_to_dict(destination_anchor),
148
+ source_ref=source_ref,
149
+ source_anchor=anchor_to_dict(anchor),
150
+ citation_string=normalized_citation_string,
151
+ citation_id=citation_id,
152
+ excerpt=excerpt,
153
+ display_value=display_value,
154
+ )