athena-python-docx 0.33.0__tar.gz → 0.35.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 (488) hide show
  1. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/AGENTS.md +135 -29
  2. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/PKG-INFO +1 -1
  3. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/__init__.py +1 -1
  4. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_buffer.py +6 -0
  5. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_capabilities.py +10 -0
  6. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_http_doc.py +8 -2
  7. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_postproc.py +10 -1
  8. athena_python_docx-0.35.0/docx/_proxy.py +85 -0
  9. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_run_order.py +31 -0
  10. athena_python_docx-0.35.0/docx/_xml_text.py +46 -0
  11. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/blkcntnr.py +3 -0
  12. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/commands.py +66 -2
  13. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/document.py +4 -0
  14. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/base.py +28 -1
  15. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/section.py +12 -24
  16. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/settings.py +15 -1
  17. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/styles/_table.py +6 -4
  18. athena_python_docx-0.35.0/docx/styles/latent.py +337 -0
  19. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/styles/style.py +319 -69
  20. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/styles/styles.py +15 -1
  21. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/table.py +158 -26
  22. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/paragraph.py +74 -9
  23. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/parfmt.py +86 -45
  24. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/run.py +163 -27
  25. athena_python_docx-0.35.0/docx/text/tabstops.py +461 -0
  26. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/pyproject.toml +1 -1
  27. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/METHODOLOGY.md +9 -1
  28. athena_python_docx-0.35.0/tests/fidelity/ab_probe/__init__.py +15 -0
  29. athena_python_docx-0.35.0/tests/fidelity/ab_probe/default_style_run_formatting.py +25 -0
  30. athena_python_docx-0.35.0/tests/fidelity/ab_probe/header_footer_pictures.py +28 -0
  31. athena_python_docx-0.35.0/tests/fidelity/ab_probe/less_used_writes.py +219 -0
  32. athena_python_docx-0.35.0/tests/fidelity/ab_probe/merged_cell_identity.py +31 -0
  33. athena_python_docx-0.35.0/tests/fidelity/ab_probe/paragraph_text_setter.py +57 -0
  34. athena_python_docx-0.35.0/tests/fidelity/ab_probe/proxy_equality.py +41 -0
  35. athena_python_docx-0.35.0/tests/fidelity/ab_probe/xml_incompatible_text.py +24 -0
  36. athena_python_docx-0.35.0/tests/fidelity/ab_probe/zero_and_negative_indents.py +26 -0
  37. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/ab_probe_cases.py +284 -0
  38. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/fake_session.py +4 -1
  39. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -1
  40. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +1 -0
  41. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +1 -0
  42. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +1 -0
  43. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +1 -0
  44. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +1 -0
  45. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/baseline.json +17 -0
  46. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/fixture_scripts.py +67 -0
  47. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/runner.py +25 -16
  48. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/test_live_runner.py +24 -0
  49. athena_python_docx-0.35.0/tests/test_alignment_values.py +90 -0
  50. athena_python_docx-0.35.0/tests/test_battery_cases.py +54 -0
  51. athena_python_docx-0.35.0/tests/test_document_settings_session_open.py +63 -0
  52. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_field_runs.py +159 -3
  53. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_http_transport.py +1 -1
  54. athena_python_docx-0.35.0/tests/test_latent_style_writes.py +166 -0
  55. athena_python_docx-0.35.0/tests/test_line_clear_break.py +83 -0
  56. athena_python_docx-0.35.0/tests/test_merged_cell_identity.py +104 -0
  57. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_paragraph_delete.py +1 -0
  58. athena_python_docx-0.35.0/tests/test_paragraph_indent_reads.py +60 -0
  59. athena_python_docx-0.35.0/tests/test_paragraph_text_empty_run.py +44 -0
  60. athena_python_docx-0.35.0/tests/test_parfmt_clears.py +168 -0
  61. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_parity_misc.py +15 -2
  62. athena_python_docx-0.35.0/tests/test_proxy_equality.py +179 -0
  63. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_rendered_page_breaks.py +33 -0
  64. athena_python_docx-0.35.0/tests/test_run_page_number_blocks.py +157 -0
  65. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_parfmt.py +10 -8
  66. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_row_col_cell.py +3 -11
  67. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_section_onoff.py +11 -23
  68. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_layout.py +8 -6
  69. athena_python_docx-0.35.0/tests/test_style_delete.py +150 -0
  70. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_formatting_writes.py +25 -2
  71. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_metadata_writes.py +138 -1
  72. athena_python_docx-0.35.0/tests/test_style_tab_stops.py +249 -0
  73. athena_python_docx-0.35.0/tests/test_tab_stop_writes.py +324 -0
  74. athena_python_docx-0.35.0/tests/test_table_clears.py +128 -0
  75. athena_python_docx-0.35.0/tests/test_unmapped_alignment_reads.py +95 -0
  76. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_wire_contract.py +8 -0
  77. athena_python_docx-0.35.0/tests/test_xml_incompatible_text.py +103 -0
  78. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/uv.lock +1 -1
  79. athena_python_docx-0.33.0/docx/styles/latent.py +0 -220
  80. athena_python_docx-0.33.0/docx/text/tabstops.py +0 -232
  81. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/.gitignore +0 -0
  82. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/CLAUDE.md +0 -0
  83. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/DOCX_EXEC_LAB.md +0 -0
  84. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/README.md +0 -0
  85. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_athena_extension.py +0 -0
  86. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_batching.py +0 -0
  87. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_citations.py +0 -0
  88. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_execution.py +0 -0
  89. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_http.py +0 -0
  90. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_image_utils.py +0 -0
  91. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_ptc.py +0 -0
  92. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_references.py +0 -0
  93. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_table_styles.py +0 -0
  94. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_timeouts.py +0 -0
  95. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/_tracked.py +0 -0
  96. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/api.py +0 -0
  97. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/bookmarks.py +0 -0
  98. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/charts.py +0 -0
  99. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/client.py +0 -0
  100. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/comments.py +0 -0
  101. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/drawing/__init__.py +0 -0
  102. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/__init__.py +0 -0
  103. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/dml.py +0 -0
  104. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/section.py +0 -0
  105. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/shape.py +0 -0
  106. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/style.py +0 -0
  107. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/table.py +0 -0
  108. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/enum/text.py +0 -0
  109. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/errors.py +0 -0
  110. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/exceptions.py +0 -0
  111. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/fields.py +0 -0
  112. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/footnotes.py +0 -0
  113. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/image/__init__.py +0 -0
  114. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/image/exceptions.py +0 -0
  115. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/image/image.py +0 -0
  116. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/math.py +0 -0
  117. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/opc/__init__.py +0 -0
  118. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/opc/coreprops.py +0 -0
  119. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/oxml/__init__.py +0 -0
  120. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/revisions.py +0 -0
  121. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/sdt.py +0 -0
  122. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/session.py +0 -0
  123. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/shape.py +0 -0
  124. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/shared.py +0 -0
  125. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/styles/__init__.py +0 -0
  126. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/__init__.py +0 -0
  127. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/font.py +0 -0
  128. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/hyperlink.py +0 -0
  129. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/text/pagebreak.py +0 -0
  130. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/toc.py +0 -0
  131. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/docx/typing.py +0 -0
  132. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab.py +0 -0
  133. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  134. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  135. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab_server.py +0 -0
  136. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/dump_wire_fixtures.py +0 -0
  137. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/release.sh +0 -0
  138. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/round_trip_smoke.py +0 -0
  139. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/smoke_test_block_not_found.py +0 -0
  140. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/scripts/validate_find_replace_asset.py +0 -0
  141. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/__init__.py +0 -0
  142. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/conftest.py +0 -0
  143. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/README.md +0 -0
  144. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/__init__.py +0 -0
  145. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/ab_probe_runner.py +0 -0
  146. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/auto_gen_cases.py +0 -0
  147. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/binary_round_trip.py +0 -0
  148. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/cases.py +0 -0
  149. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/complex_cases.py +0 -0
  150. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/coverage_report.py +0 -0
  151. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/extract.py +0 -0
  152. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/extreme_cases.py +0 -0
  153. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/README.md +0 -0
  154. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/__init__.py +0 -0
  155. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/_runner.py +0 -0
  156. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/extractor.py +0 -0
  157. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  158. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  159. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/local_runner.py +0 -0
  160. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/mega_cases.py +0 -0
  161. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshot.py +0 -0
  162. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  163. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  164. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  165. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  166. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  167. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  168. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  169. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  170. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  171. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  172. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  173. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  174. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  175. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  176. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  177. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  178. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  179. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  180. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  181. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  182. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  183. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  184. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  185. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  186. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  187. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  188. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  189. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  190. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  191. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  192. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  193. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  194. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  195. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  196. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  197. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  198. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  199. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  200. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  201. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  202. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  203. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  204. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  205. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  206. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  207. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  208. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  209. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  210. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  211. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  212. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  213. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  214. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  215. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  216. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  217. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  218. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  219. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  220. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  221. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  222. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  223. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  224. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  225. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  226. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  227. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  228. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  229. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  230. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  231. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  232. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  233. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  234. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  235. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  236. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  237. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  238. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  239. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  240. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  241. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  242. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  243. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  244. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  245. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  246. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  247. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  248. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  249. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  250. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  251. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  252. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  253. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  254. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  255. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  256. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  257. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  258. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  259. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  260. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  261. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  262. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  263. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  264. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  265. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  266. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  267. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  268. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  269. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  270. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  271. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  272. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  273. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  274. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  275. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  276. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  277. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  278. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  279. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  280. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  281. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  282. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  283. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  284. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  285. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  286. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  287. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  288. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  289. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  290. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  291. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  292. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  293. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  294. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  295. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  296. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  297. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  298. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  299. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  300. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  301. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  302. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  303. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  304. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
  305. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
  306. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
  307. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
  308. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/ours_spec.json +0 -0
  309. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/parity_crawl.py +0 -0
  310. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/parity_diff.json +0 -0
  311. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/real_world_cases.py +0 -0
  312. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/round_trip_tests.py +0 -0
  313. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/stock_spec.json +0 -0
  314. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
  315. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fixtures/field_reads.json +0 -0
  316. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fixtures/note_reference_reads.json +0 -0
  317. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fixtures/ruby_reads.json +0 -0
  318. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/fixtures/symbol_reads.json +0 -0
  319. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/__init__.py +0 -0
  320. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/reader.py +0 -0
  321. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/sdk_driver.py +0 -0
  322. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/live/stock_driver.py +0 -0
  323. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/README.md +0 -0
  324. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/__init__.py +0 -0
  325. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/baseline_gaps.json +0 -0
  326. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/compare.py +0 -0
  327. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/intentional_deviations.json +0 -0
  328. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/introspect.py +0 -0
  329. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  330. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/reports/gap_report.json +0 -0
  331. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/run_parity.py +0 -0
  332. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/snapshots/athena_latest.json +0 -0
  333. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  334. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/parity/test_parity_gap.py +0 -0
  335. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_add_section.py +0 -0
  336. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_add_section_extract_items.py +0 -0
  337. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_athena_extension_creates_session_open.py +0 -0
  338. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_athena_extensions_contract.py +0 -0
  339. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_athena_extensions_registry.py +0 -0
  340. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_batch_chunking.py +0 -0
  341. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_batching_perf.py +0 -0
  342. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_block_not_found_error.py +0 -0
  343. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_buffer.py +0 -0
  344. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  345. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_add_table_not_supported.py +0 -0
  346. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_borders_spec.py +0 -0
  347. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_fastpath_runs.py +0 -0
  348. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  349. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  350. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_format_stash.py +0 -0
  351. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_run_format_stash.py +0 -0
  352. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_run_guard.py +0 -0
  353. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_merge.py +0 -0
  354. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_nested_tables.py +0 -0
  355. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_paragraphs_listed.py +0 -0
  356. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_text_plain_fastpath.py +0 -0
  357. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_cell_text_replace_semantics.py +0 -0
  358. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_citations.py +0 -0
  359. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_collapsed_range_format.py +0 -0
  360. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_color_format_theme.py +0 -0
  361. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_command_dataclasses.py +0 -0
  362. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_commands.py +0 -0
  363. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_comment_paragraphs.py +0 -0
  364. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_comments.py +0 -0
  365. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_comments_first_read.py +0 -0
  366. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_content_control_value.py +0 -0
  367. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_core_properties.py +0 -0
  368. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_document_asset_id_property.py +0 -0
  369. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_document_clear.py +0 -0
  370. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_document_create.py +0 -0
  371. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_document_create_from_template.py +0 -0
  372. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_document_factory_validation.py +0 -0
  373. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_docx_exec_lab.py +0 -0
  374. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_docx_exec_lab_server.py +0 -0
  375. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_drawing_image.py +0 -0
  376. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
  377. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_empty_hyperlinks.py +0 -0
  378. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_enum_parity.py +0 -0
  379. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_execution_scope.py +0 -0
  380. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_export_docx_clean.py +0 -0
  381. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_export_rescue_anchors.py +0 -0
  382. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_field_reads_python_docx_parity.py +0 -0
  383. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_field_refresh.py +0 -0
  384. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_find_replace_session_open.py +0 -0
  385. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_flushed_write_failures.py +0 -0
  386. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_hyperlink_coalescing.py +0 -0
  387. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_image_url_data_uri.py +0 -0
  388. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_inline_page_break.py +0 -0
  389. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_inline_shape_alt_text.py +0 -0
  390. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_inline_shape_size.py +0 -0
  391. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_inline_shape_type.py +0 -0
  392. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_inline_shapes_floating.py +0 -0
  393. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_insert_deferred.py +0 -0
  394. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_iter_inner_content.py +0 -0
  395. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_list_styles.py +0 -0
  396. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_merged_cell_secondary_slot.py +0 -0
  397. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_merged_cells.py +0 -0
  398. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_missing_modules.py +0 -0
  399. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_nested_table_refused.py +0 -0
  400. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
  401. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_oxml_shim.py +0 -0
  402. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_page_break.py +0 -0
  403. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_paragraph_runs_hyperlinks.py +0 -0
  404. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_paragraph_text_len_cache.py +0 -0
  405. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_parity_round2.py +0 -0
  406. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_partial_failure_cascade.py +0 -0
  407. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_pdf_export_and_page_renders.py +0 -0
  408. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_phase_a_behavior.py +0 -0
  409. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_phase_b_headers_footers.py +0 -0
  410. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_phase_c_tables.py +0 -0
  411. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_positional_cell_id.py +0 -0
  412. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_postproc_cell_format_rewrite.py +0 -0
  413. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  414. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_postproc_ref_restore.py +0 -0
  415. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_pr19766_review_fixes.py +0 -0
  416. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_ptc.py +0 -0
  417. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_python_docx_api_parity.py +0 -0
  418. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_read_run_ranges.py +0 -0
  419. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_repeated_node_read.py +0 -0
  420. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_restart_numbering.py +0 -0
  421. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_revisions.py +0 -0
  422. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_round_trip_smoke_script.py +0 -0
  423. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_ruby_reads_python_docx_parity.py +0 -0
  424. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_add_picture_anchor.py +0 -0
  425. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_break_inner_content.py +0 -0
  426. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_edges.py +0 -0
  427. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_formatting_wire.py +0 -0
  428. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_identity.py +0 -0
  429. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_later_runs.py +0 -0
  430. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_mark_inheritance.py +0 -0
  431. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_table_style_objects.py +0 -0
  432. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_text_python_docx.py +0 -0
  433. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_text_refreshes_paragraph.py +0 -0
  434. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_run_unmodeled_toggles.py +0 -0
  435. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_sdk_reads_served.py +0 -0
  436. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_section_read_lengths.py +0 -0
  437. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  438. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_add_picture.py +0 -0
  439. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_add_run.py +0 -0
  440. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  441. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
  442. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_comments_get.py +0 -0
  443. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_document_audit.py +0 -0
  444. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_document_element.py +0 -0
  445. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_enum_section.py +0 -0
  446. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_font_audit.py +0 -0
  447. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_header_footer.py +0 -0
  448. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_hyperlink.py +0 -0
  449. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_inline_shape.py +0 -0
  450. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  451. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_misc.py +0 -0
  452. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
  453. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_paragraph_style.py +0 -0
  454. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  455. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_add_break.py +0 -0
  456. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
  457. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_style.py +0 -0
  458. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_style_strict.py +0 -0
  459. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_text.py +0 -0
  460. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_underline.py +0 -0
  461. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_section_audit.py +0 -0
  462. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_section_dimensions.py +0 -0
  463. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_settings.py +0 -0
  464. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_shared_audit.py +0 -0
  465. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_style.py +0 -0
  466. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_styles.py +0 -0
  467. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_audit.py +0 -0
  468. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_cell.py +0 -0
  469. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_dimensions.py +0 -0
  470. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_smoke_integration.py +0 -0
  471. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_acceptance.py +0 -0
  472. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_font.py +0 -0
  473. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_names.py +0 -0
  474. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_setters_contract.py +0 -0
  475. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_style_tab_stops_read.py +0 -0
  476. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_symbol_reads_python_docx_parity.py +0 -0
  477. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_table_anchors.py +0 -0
  478. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_table_direction.py +0 -0
  479. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_table_read_reuse.py +0 -0
  480. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_table_set_cell_perf.py +0 -0
  481. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_table_style_id_resolution.py +0 -0
  482. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_temporarily_unavailable.py +0 -0
  483. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_text_control_characters.py +0 -0
  484. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_tracked_revisions_offsets.py +0 -0
  485. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_uv_lock_version.py +0 -0
  486. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_validate_find_replace_asset_script.py +0 -0
  487. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_xml_attr_guard.py +0 -0
  488. {athena_python_docx-0.33.0 → athena_python_docx-0.35.0}/tests/test_zod_wire_contract.py +0 -0
@@ -85,16 +85,30 @@ pinned by focused tests and documented in
85
85
  `quick_style`, `unhide_when_used`, `base_style`,
86
86
  `next_paragraph_style`) write the style's definition
87
87
  (`SetStyleMetadata`), `Styles.add_style` adds one (`CreateStyle`), and
88
- a paragraph or character style's formatting (`style.font.*`,
89
- `style.paragraph_format.*`) is written too (`SetStyleFormatting`); each
88
+ a paragraph, character or table style's formatting (`style.font.*`,
89
+ `style.paragraph_format.*`; a table style's on a docx-studio that reports
90
+ `tableStyleFormatting`, which a room imported before its cells resolved
91
+ table styles does not) is written too (`SetStyleFormatting`); each
90
92
  reads back from the style table, whose `metadata` / `font` /
91
93
  `paragraphFormat` entries are the capability signal
92
94
  (`tests/test_style_metadata_writes.py`,
93
- `tests/test_style_formatting_writes.py`). `style_id`, `delete()`, a
94
- table style's formatting and base, a style's tab stops, and every style write on
95
- a docx-studio without that signal emit `PendingStyleMutationWarning`
96
- (or its paragraph-format / registry variant) and stash on
97
- `_overrides` (`tests/test_style_setters_contract.py`).
95
+ `tests/test_style_formatting_writes.py`), a paragraph style's
96
+ `tab_stops` (each mutation sends the style's whole `w:tabs` as python-docx's
97
+ `TabStops` leaves it, on a docx-studio that reports `styleTabStops`; each
98
+ tab stop object is its place in that list, which a write to another moves,
99
+ so of two equal stops each writes itself, and one removed writes nothing;
100
+ `tests/test_style_tab_stops.py`). `delete()` removes a paragraph
101
+ or character style's definition (`DeleteStyle`, on a docx-studio that
102
+ reports `deleteStyle`; `tests/test_style_delete.py`): its content keeps the
103
+ style's name and shows the default style, as in Word. A table style's
104
+ `delete()`, `base_style` and `style_id` are sent where docx-studio also
105
+ reports `tableStyleRestyles` (it draws the style's tables again), and its
106
+ font and paragraph format where it reports `tableStyleFormatting`; a room
107
+ imported before its cells resolved table styles reports neither. A
108
+ numbering style's `style_id` and deletion, and every style write on a
109
+ docx-studio without that signal emit
110
+ `PendingStyleMutationWarning` (or its delete / paragraph-format / registry
111
+ variant) and stash on `_overrides` (`tests/test_style_setters_contract.py`).
98
112
  - **A picture is a run, and `Run.iter_inner_content()` yields its
99
113
  `docx.drawing.Drawing`.** As python-docx reads a `w:r` holding a
100
114
  `w:drawing`, `Paragraph.runs` and `iter_inner_content()` hold a run with
@@ -116,10 +130,15 @@ pinned by focused tests and documented in
116
130
  - **`Styles.latent_styles`** (`docx.styles.latent.LatentStyles`) reads
117
131
  the document's `<w:latentStyles>` (defaults and each `w:lsdException`)
118
132
  from docx-studio's `Info` (`includeStyles` → `latentStyles`), as python-docx
119
- reads them. Writing them is not supported: a setter, `add_latent_style`
120
- and `_LatentStyle.delete` emit `PendingLatentStylesWriteWarning` and
121
- change nothing. A docx-studio that predates the read (or a document
122
- without a source copy) reads as empty, with
133
+ reads them, and writes them as python-docx does: each setter,
134
+ `add_latent_style` and `_LatentStyle.delete` sends one `EditLatentStyles`
135
+ to a docx-studio that reports `latentStyleWrites`
136
+ (`tests/test_latent_style_writes.py`); an older one keeps the value, with
137
+ `PendingLatentStylesWriteWarning`. A `_LatentStyle` addresses its exception
138
+ by name and `occurrence` (which of that name's exceptions it is), moved
139
+ when an earlier one is deleted, so one `add_latent_style` returns beside an
140
+ exception of the same name writes to itself, as python-docx's element does. A docx-studio that predates the read (or
141
+ a document without a source copy) reads as empty, with
123
142
  `PendingLatentStylesReadWarning`.
124
143
 
125
144
  ### Intentional deviations (additions / different semantics)
@@ -169,6 +188,22 @@ not file-backed. Each is documented in the relevant docstring.
169
188
  cells stay. ``table.style = None`` removes an existing table's style as
170
189
  python-docx does (``DOCX_STUDIO_LIMITATIONS.md`` § 25).
171
190
 
191
+ - **Table, row and cell properties set to None, and row height parts**, as
192
+ python-docx 1.2.0 writes them on a docx-studio that reports
193
+ ``tableClears`` (``tests/test_table_clears.py``): ``Table.alignment =
194
+ None`` removes ``w:jc`` (a header or footer table's too),
195
+ ``_Cell.vertical_alignment = None`` removes
196
+ ``w:vAlign``, and ``_Row.height`` / ``_Row.height_rule`` each write their
197
+ own part of ``w:trHeight``, None removing it (``<w:trHeight
198
+ w:hRule="exact"/>``); a height set without a rule is the value alone.
199
+ ``_Cell.width = None`` raises ``TypeError`` and ``Table.autofit = None``
200
+ changes nothing, as in python-docx. An older docx-studio keeps the
201
+ ``PendingTableClearWarning`` and sends a rule (at least) with each height.
202
+ ``_Column.width = None`` still warns: a ``w:gridCol`` without a width
203
+ needs the layout to size the column from its cells. An invalid height or
204
+ rule is refused before the capability read, whose ``Info`` would send the
205
+ edits still buffered.
206
+
172
207
  - **`Document.create(name=, base_url=, api_key=, parent_folder_id=, workspace_id=, docx=, agora_base_url=)`**
173
208
  classmethod. Stock python-docx returns a blank in-memory document
174
209
  for `Document(None)`; we can't fabricate a Word document asset
@@ -921,10 +956,26 @@ architecture or a DOCX Studio constraint:
921
956
  string DOCX Studio's commands carry for a member (`"center"`, `"wavy"`,
922
957
  the `w:` XML value, …) where upstream rejects strings. The SDK sends
923
958
  `member.to_docx_studio()` and reads with `from_docx_studio()`, never
924
- `.value`. Members DOCX Studio can't apply are sent as their closest
925
- value with `PendingEnumCoercionWarning` (distributed / kashida / Thai
926
- justification → `"justify"`; `LIST`/`CLEAR`/`END`/`NUM`/`START` tabs →
927
- `"left"`); `WD_ALIGN_VERTICAL.BOTH` goes as `"center"`. `INHERITED`
959
+ `.value`. A paragraph's alignment and tab stops go as python-docx writes
960
+ them (distributed / kashida / Thai justification, `LIST`/`CLEAR`/`END`/
961
+ `NUM`/`START` tabs) to a DOCX Studio that reports `alignmentValues`
962
+ (`tests/test_alignment_values.py`); to an older one, as their closest
963
+ value (`"justify"`, `"left"`) with `PendingEnumCoercionWarning`.
964
+ `TabStops.add_tab_stop` keeps a stop already at its position and goes in
965
+ after it, as python-docx's `insert_tab_in_order` puts it
966
+ (`SetParagraphTabStop` with `insert`, sent to a DOCX Studio that reports
967
+ `tabStopInserts`; an older one replaces that stop). A stop's `alignment`
968
+ and `leader` change it in place, and its `position` moves it where
969
+ python-docx moves its `w:tab` (`tests/test_tab_stop_writes.py`). A
970
+ `TabStop` is its place in the paragraph's list, which a write through any
971
+ other moves (the live stops of each paragraph are held weakly per
972
+ session), as python-docx's proxy holds its `w:tab`: two stops at one
973
+ position are each their own, and two objects of one stop both write it.
974
+ One the paragraph no longer holds takes a value and writes nothing; its
975
+ `position` raises `AttributeError`, except for one `clear_all` took out,
976
+ as python-docx's do. An add reads nothing unless a stop of the paragraph
977
+ holds a place: the next read finds where it went.
978
+ `WD_ALIGN_VERTICAL.BOTH` goes as `"center"`. `INHERITED`
928
979
  raises `ValueError` ("has no XML representation") as upstream's
929
980
  `to_xml` does, and a bool is its int value (`True` is the member valued
930
981
  1), as upstream reads it. `Table.alignment`
@@ -1009,7 +1060,10 @@ architecture or a DOCX Studio constraint:
1009
1060
  docx-studio finds the table by those paragraphs, so a table an edit moved (a
1010
1061
  row added above a table nested in a cell, a table added before it, a merge
1011
1062
  moving a nested table into the merged cell) is still the one read and
1012
- written, as python-docx's proxies follow the elements they hold. When no
1063
+ written, as python-docx's proxies follow the elements they hold. A write
1064
+ that replaces one of those paragraphs (`cell.text = …` on the first or last
1065
+ cell) leaves its paraId on the table as an alias (`anchorAliases`), so the
1066
+ proxy reaches the table in later batches on any docx-studio replica. When no
1013
1067
  table holds them (the table was deleted, or the cell holding it had its
1014
1068
  text replaced, which removes the tables it held), docx-studio refuses the
1015
1069
  batch and the SDK raises `StaleTableError`: "the table this proxy named is
@@ -1069,11 +1123,16 @@ architecture or a DOCX Studio constraint:
1069
1123
  exported paragraph as `annotation text`. Owner decision, 2026-10-12.
1070
1124
  Recorded in `tests/parity/intentional_deviations.json` (`live_deviations`).
1071
1125
 
1072
- - **`ParagraphFormat.line_spacing_rule = None` warns-and-preserves on a
1073
- clear** rather than raising (upstream accepts `None` to clear, but DOCX
1074
- Studio's merging mutation ops have no single-attribute clear). It emits a
1075
- `Pending…ClearWarning` and leaves the value intact instead of
1076
- destructively clearing the whole block. The `Section` dimension setters
1126
+ - **A `ParagraphFormat` setter given `None` clears that property alone**, as
1127
+ upstream does, on a docx-studio that reports `paragraphFormatClears`:
1128
+ `space_before`, `space_after`, `line_spacing` (the line with its rule) and
1129
+ `line_spacing_rule` (the rule alone) send `ClearParagraphSpacing.only`;
1130
+ `left_indent`, `right_indent` and `first_line_indent` send
1131
+ `ClearParagraphIndentation.only`; `keep_with_next`, `keep_together` and
1132
+ `widow_control` send `SetParagraphKeepOptions.clear…`. On an older one a
1133
+ spacing or indent `None` clears all of the paragraph's spacing or indents,
1134
+ as before, and the keep options and `line_spacing_rule` warn
1135
+ (`PendingParfmtClearWarning`) and keep the value. The `Section` dimension setters
1077
1136
  remove the attribute for `None`, as upstream does (`null` on the wire),
1078
1137
  on a docx-studio whose section read reports `clearsDimensions`; on an
1079
1138
  older one they warn (`PendingSectionDimensionClearWarning`) and keep the
@@ -1156,18 +1215,37 @@ architecture or a DOCX Studio constraint:
1156
1215
  field's result changed (through another read's run, or by a
1157
1216
  collaborator) raises `FieldRunWriteError` rather than write over that
1158
1217
  change, where python-docx's run is live;
1159
- - formatting a result run formats the field's whole result (`FormatApply`
1160
- with a `field` target), from its source formatting, where python-docx
1161
- formats that run alone;
1218
+ - formatting a field's one result run formats the field's whole result
1219
+ (`FormatApply` with a `field` target), from its source formatting, as
1220
+ python-docx formats that run, and in a body paragraph docx-studio writes
1221
+ the run's own `w:rPr` with it (a caption's number keeps its `w:noProof`
1222
+ and takes nothing of the Caption style); of a result of several runs, it formats that
1223
+ run alone, as python-docx does, against a docx-studio that reports
1224
+ `capabilities.fieldRunFormats` (an older one formats the whole result).
1225
+ The SDK names that run by its place among the result's runs and the text
1226
+ it was read with, and renumbers the result runs a read holds when a write
1227
+ through one of them empties it (docx-studio writes no emptied result
1228
+ run): a run that no longer has a place, or holds other text, is not
1229
+ formatted alone. The SDK warns (`PendingFieldRunFormatWarning`), or
1230
+ docx-studio refuses the format, so it never lands on another run;
1162
1231
  - `.text` (and `clear()`) on a field character or field code run raises
1163
1232
  `docx.errors.FieldRunWriteError` naming the field: python-docx replaces
1164
1233
  the run's `w:fldChar` or `w:instrText` with the text, which breaks the
1165
1234
  field;
1166
- - formatting set on a field character or field code run is not applied and
1167
- emits `PendingFieldRunFormatWarning` (those runs show nothing; docx-studio
1168
- has no command that writes their own `w:rPr`), where python-docx writes
1169
- it, so `for run in p.runs: run.bold = True` formats the text and the
1170
- field's result and warns for the rest;
1235
+ - formatting set on a field character or field code run, a table of
1236
+ contents' own runs among them, is written to that run's `w:rPr` as
1237
+ python-docx writes it, so `for run in p.runs: run.bold = True` formats
1238
+ every run, against a docx-studio that reports
1239
+ `capabilities.fieldRunFormats` (the SDK names the run: its `part`, with its
1240
+ field's index and which run of that part it is, or which of the
1241
+ paragraph's field runs no field node stands for it is). It is refused and
1242
+ warns (`DocxUnsupportedCommandWarning`) for a run of a field `add_field`
1243
+ added since the import, whose runs docx-studio writes from its node, and
1244
+ of a paragraph a field was added to or taken out of since; a tracked
1245
+ format raises naming `TrackedChangesUnsupported`. An older docx-studio has
1246
+ no command that writes those runs' `w:rPr`: there the setter changes
1247
+ nothing and emits `PendingFieldRunFormatWarning`
1248
+ (`tests/test_field_runs.py`, `DOCX_STUDIO_LIMITATIONS.md` § 27);
1171
1249
  - `add_text`, `add_tab`, `add_break`, `add_picture`, `add_field`,
1172
1250
  `add_footnote`, `add_endnote`, `add_math` and `add_cross_reference` on
1173
1251
  any of a field's runs raise `FieldRunWriteError`; python-docx appends to
@@ -1177,6 +1255,34 @@ architecture or a DOCX Studio constraint:
1177
1255
  exported file. Against a docx-studio that predates `fieldRun` reads, a
1178
1256
  field reads as no runs and no text, as before (`tests/test_field_runs.py`).
1179
1257
 
1258
+ - **A run that holds a page number block refuses a tracked whole-run format
1259
+ and two text writes.** A page number block (`w:pgNum`) reads as a run with
1260
+ no text, and a run that holds text and blocks (or two blocks) reads as
1261
+ python-docx's one run. A whole-run format (`run.bold = True`, `run.font.*`,
1262
+ a format of a block's run) formats every piece of it, as python-docx formats
1263
+ its `w:rPr`, the on/off properties no editor mark holds included
1264
+ (`font.no_proof`, `snap_to_grid`, `web_hidden`, `spec_vanish`, `math`,
1265
+ `complex_script`, `cs_bold`, `cs_italic`). A tracked format
1266
+ (`track_revisions`) is refused while a block of the run has a node, and
1267
+ raises `DocxError` naming `TrackedChangesUnsupported`, because docx-studio
1268
+ records no tracked change on a block. A link's block has none, and takes it
1269
+ as the run's text does. In a document imported before docx-studio gave a
1270
+ block's node its run's properties (in October 2026, between the release that
1271
+ first read `w:pgNum` and the next), and in a comment, the on/off properties
1272
+ are refused too, in any format that reaches a block, and warn
1273
+ (`DocxUnsupportedCommandWarning`), because there a block keeps its source
1274
+ run's. python-docx writes both into the run's `w:rPr`. Made on the run's
1275
+ text alone, either would leave the run half formatted and split it in two
1276
+ (`DOCX_STUDIO_LIMITATIONS.md` § 27). `run.text = …` and `clear()` replace
1277
+ all of such a run, its blocks too, as upstream does: the SDK declares
1278
+ `wholeRunPieces`, and renumbers the field runs it holds of the paragraph,
1279
+ since each field after the blocks is numbered one lower for each
1280
+ (`tests/test_run_page_number_blocks.py`). Two text writes are refused and
1281
+ warn (`DocxUnsupportedCommandWarning`), where upstream replaces the blocks:
1282
+ text written to a block's run (a run of blocks alone, or a lone block),
1283
+ which would move the text offsets the SDK keeps, and the text of a link's
1284
+ run that holds a block, which has no node to take out.
1285
+
1180
1286
  - **`Font.name = "…"` also clears the theme fonts of the two slots it
1181
1287
  sets.** python-docx writes the name to `w:rFonts`' `w:ascii` and `w:hAnsi`
1182
1288
  and leaves a `w:asciiTheme` / `w:hAnsiTheme` beside them; Word reads a
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: athena-python-docx
3
- Version: 0.33.0
3
+ Version: 0.35.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.33.0"
9
+ __version__ = "0.35.0"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import discard_all, flush_all
@@ -43,6 +43,7 @@ from docx._execution import (
43
43
  is_stale_execution,
44
44
  )
45
45
  from docx._timeouts import timeout_for_commands
46
+ from docx._xml_text import check_command_text
46
47
  from docx.commands import (
47
48
  Command,
48
49
  GetNodeById,
@@ -596,6 +597,11 @@ class CommandBuffer:
596
597
  proxy's ``_node_id`` in-place.
597
598
  """
598
599
  self.ensure_usable()
600
+ # A write whose text holds a character XML does not allow raises
601
+ # python-docx's ValueError here, before anything is sent: every command
602
+ # comes through, a path-proxy op's and a direct ``send_command``'s.
603
+ if not is_query(cmd):
604
+ check_command_text(cmd.to_dict())
599
605
 
600
606
  # A read of the node the last command read, with nothing sent or
601
607
  # buffered since and within READ_REUSE_SECONDS of it, answers from
@@ -22,6 +22,16 @@ from docx._batching import run_sync
22
22
  # An older docx-studio gives none, so the SDK needs no check.
23
23
  TABLE_ANCHORS_CLIENT_CAPABILITY = "tableAnchors"
24
24
 
25
+ # What this SDK declares in ``client.capabilities``: it renumbers the field
26
+ # runs it holds once a whole run's text write (``run.text = …``, ``clear()``)
27
+ # took out the page number blocks (``w:pgNum``) of a run docx-studio cut at
28
+ # them, whose read lists their field indices (``pageNumberBlocks``). Such a
29
+ # write then replaces all of the run, its blocks too, as python-docx replaces
30
+ # its ``w:r``'s content, and each field after the blocks is numbered one lower
31
+ # for each. An older docx-studio lists no blocks and keeps them, so the SDK
32
+ # renumbers nothing.
33
+ WHOLE_RUN_PIECES_CLIENT_CAPABILITY = "wholeRunPieces"
34
+
25
35
  # Session -> the capabilities its server reported, read once.
26
36
  _capabilities: "weakref.WeakKeyDictionary[Any, dict[str, Any]]" = weakref.WeakKeyDictionary()
27
37
 
@@ -44,7 +44,7 @@ from urllib3.util.retry import Retry
44
44
  from docx._batching import call_abandoned, note_progress
45
45
  from docx._buffer import CommandBuffer, keep_reported_message
46
46
  from docx._tracked import TRACKED_AUTHORING_CAPABILITY, TRACKED_MINIMAL_PARAGRAPH_TEXT_CAPABILITY
47
- from docx._capabilities import TABLE_ANCHORS_CLIENT_CAPABILITY
47
+ from docx._capabilities import TABLE_ANCHORS_CLIENT_CAPABILITY, WHOLE_RUN_PIECES_CLIENT_CAPABILITY
48
48
  from docx._timeouts import (
49
49
  DEFAULT_OP_TIMEOUT_SECONDS,
50
50
  LONG_RUNNING_COMMAND_TIMEOUT_SECONDS,
@@ -87,6 +87,8 @@ from docx.commands import (
87
87
  CreateParagraph,
88
88
  CreateSectionBreak,
89
89
  CreateStyle,
90
+ EditLatentStyles,
91
+ DeleteStyle,
90
92
  CreateTable,
91
93
  CreateTOC,
92
94
  CreateWatermark,
@@ -1209,11 +1211,13 @@ class HttpClient:
1209
1211
  "version": _sdk_version(),
1210
1212
  # Keeps its offsets as a tracked edit moves them, and reads a
1211
1213
  # paragraph's length back after a tracked ``paragraph.text``
1212
- # (``docx._tracked``); holds anchored table ids (``docx.table``).
1214
+ # (``docx._tracked``); holds anchored table ids (``docx.table``);
1215
+ # renumbers its field runs after a cut run's whole write (``docx._run_order``).
1213
1216
  "capabilities": [
1214
1217
  TRACKED_AUTHORING_CAPABILITY,
1215
1218
  TRACKED_MINIMAL_PARAGRAPH_TEXT_CAPABILITY,
1216
1219
  TABLE_ANCHORS_CLIENT_CAPABILITY,
1220
+ WHOLE_RUN_PIECES_CLIENT_CAPABILITY,
1217
1221
  ],
1218
1222
  },
1219
1223
  "commands": [
@@ -1374,6 +1378,8 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
1374
1378
  "styles.set_formatting": SetStyleFormatting,
1375
1379
  "styles.set_metadata": SetStyleMetadata,
1376
1380
  "styles.create": CreateStyle,
1381
+ "styles.edit_latent": EditLatentStyles,
1382
+ "styles.delete": DeleteStyle,
1377
1383
  "core_properties.set": SetCoreProperties,
1378
1384
  # Sections
1379
1385
  "sections.set_page_margins": SetSectionPageMargins,
@@ -2897,6 +2897,15 @@ def _replace_flag(
2897
2897
  elem.set(f"{W_NS}val", "0")
2898
2898
 
2899
2899
 
2900
+ # The other ``w:jc`` justifications python-docx writes, by their lower case.
2901
+ _JUSTIFICATIONS_BY_LOWER = {
2902
+ "mediumkashida": "mediumKashida",
2903
+ "highkashida": "highKashida",
2904
+ "lowkashida": "lowKashida",
2905
+ "thaidistribute": "thaiDistribute",
2906
+ }
2907
+
2908
+
2900
2909
  def normalize_alignment(value: Any) -> str | None:
2901
2910
  """Convert a python-docx ``WD_ALIGN_PARAGRAPH`` value (or string) to
2902
2911
  the OOXML ``w:jc`` value (``left`` / ``center`` / ``right`` /
@@ -2919,7 +2928,7 @@ def normalize_alignment(value: Any) -> str | None:
2919
2928
  return "both"
2920
2929
  if s in {"distribute"}:
2921
2930
  return "distribute"
2922
- return None
2931
+ return _JUSTIFICATIONS_BY_LOWER.get(s)
2923
2932
 
2924
2933
  # WD_ALIGN_PARAGRAPH enum values (int-like).
2925
2934
  name = getattr(value, "name", None)
@@ -0,0 +1,85 @@
1
+ """python-docx's ``ElementProxy`` equality, for the SDK's proxies of the
2
+ objects python-docx wraps in one: styles, the styles part, settings, a
3
+ paragraph's or a style's paragraph format, a run's or a style's font."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import weakref
8
+ from typing import Any
9
+
10
+
11
+ class ElementProxyEquality:
12
+ """python-docx's ``docx.shared.ElementProxy`` equality: two proxies of the
13
+ same element are equal (``paragraph.style == doc.styles["Heading 1"]``),
14
+ a proxy of another element or anything else is not, and, as python-docx
15
+ defines ``__eq__`` there, a proxy is not hashable.
16
+
17
+ The element is :meth:`_proxy_element`: the docx-studio object it stands
18
+ for, named as the XML element python-docx's proxy wraps (a style's
19
+ ``w:style``, so a style, its font and its paragraph format are equal, as
20
+ they are in python-docx).
21
+ """
22
+
23
+ __slots__ = ()
24
+
25
+ def _proxy_element(self) -> tuple[object, ...]:
26
+ raise NotImplementedError
27
+
28
+ def __eq__(self, other: object) -> bool:
29
+ if not isinstance(other, ElementProxyEquality):
30
+ return False
31
+ return self._proxy_element() == other._proxy_element()
32
+
33
+ def __ne__(self, other: object) -> bool:
34
+ return not self.__eq__(other)
35
+
36
+ __hash__ = None # type: ignore[assignment]
37
+
38
+
39
+ # Session -> style id -> the style definition that id names in the session's
40
+ # document now (:func:`style_definition`). Held weakly by session, as the
41
+ # run order is (``docx._run_order``); the document stores none of it.
42
+ _STYLE_DEFINITIONS: "weakref.WeakKeyDictionary[Any, dict[str, object]]" = weakref.WeakKeyDictionary()
43
+
44
+
45
+ def _definitions(session: object) -> "dict[str, object] | None":
46
+ if session is None:
47
+ return None
48
+ try:
49
+ return _STYLE_DEFINITIONS.setdefault(session, {})
50
+ except TypeError: # a session that takes no weak reference
51
+ return None
52
+
53
+
54
+ def style_definition(session: object, style_id: str) -> object:
55
+ """The style definition (its ``w:style`` element) that ``style_id`` names in
56
+ ``session``'s document now, which a style proxy holds from its first read:
57
+ the same one after a rename (:func:`style_renamed`), another for a style
58
+ made after one of that id was deleted (:func:`style_deleted`)."""
59
+ definitions = _definitions(session)
60
+ if definitions is None:
61
+ return ("w:styleId", style_id)
62
+ return definitions.setdefault(style_id, object())
63
+
64
+
65
+ def style_renamed(session: object, old: str, new: str) -> None:
66
+ """``style_id`` renamed the definition ``old`` named to ``new``."""
67
+ definitions = _definitions(session)
68
+ if definitions is not None:
69
+ definitions[new] = definitions.pop(old, None) or object()
70
+
71
+
72
+ def style_deleted(session: object, style_id: str) -> None:
73
+ """``delete`` removed the definition ``style_id`` named."""
74
+ definitions = _definitions(session)
75
+ if definitions is not None:
76
+ definitions.pop(style_id, None)
77
+
78
+
79
+ def style_element(style: object) -> tuple[object, ...]:
80
+ """The ``w:style`` element of ``style`` (a ``BaseStyle``): its document and
81
+ its definition (:func:`style_definition`), which a rename keeps."""
82
+ definition = getattr(style, "_definition", None)
83
+ if definition is None:
84
+ definition = ("w:styleId", getattr(style, "_style_id", None))
85
+ return ("w:style", getattr(style, "_session", None), definition)
@@ -29,6 +29,7 @@ document stores none of it.
29
29
 
30
30
  from __future__ import annotations
31
31
 
32
+ import bisect
32
33
  import itertools
33
34
  import weakref
34
35
  from dataclasses import dataclass, field
@@ -105,6 +106,36 @@ def _live_runs(run: "Run") -> list["Run"]:
105
106
  return [proxy for block_id in ids for proxy in list(blocks.get(block_id, ()))]
106
107
 
107
108
 
109
+ def page_number_blocks_gone(run: "Run", gone: list[int], *, taken_out: bool) -> None:
110
+ """The page number blocks ``gone`` (their field indices) are no run's of
111
+ ``run``'s paragraph now: a whole run's text write took them out
112
+ (``taken_out``), or, with tracking on, deleted them, where they keep
113
+ their place and their numbers.
114
+
115
+ No live run proxy of the paragraph, read or created, lists them
116
+ (``pageNumberBlocks``). Taken out, each field after them is numbered one
117
+ lower for each, as docx-studio numbers them, so every proxy names its
118
+ field (``fieldIndex``) and the blocks it holds by the new numbers.
119
+ """
120
+ removed = sorted(set(gone))
121
+
122
+ def renumbered(index: int) -> int:
123
+ return index - bisect.bisect_left(removed, index) if taken_out else index
124
+
125
+ for proxy in _live_runs(run):
126
+ snapshot: object = getattr(proxy, "_inline_snapshot", None)
127
+ if not isinstance(snapshot, dict):
128
+ continue
129
+ index: object = snapshot.get("fieldIndex")
130
+ if isinstance(index, int) and not isinstance(index, bool):
131
+ snapshot["fieldIndex"] = renumbered(index)
132
+ blocks: object = snapshot.get("pageNumberBlocks")
133
+ if isinstance(blocks, list):
134
+ snapshot["pageNumberBlocks"] = [
135
+ renumbered(block) for block in blocks if isinstance(block, int) and block not in removed
136
+ ]
137
+
138
+
108
139
  def _move_live_runs(
109
140
  run: "Run",
110
141
  old_span: tuple[int, int],
@@ -0,0 +1,46 @@
1
+ """What lxml refuses in XML text and attribute values, where python-docx meets it.
2
+
3
+ python-docx writes every string it is given into an lxml element, and lxml
4
+ raises ``ValueError`` for a character XML does not allow: C0 controls other
5
+ than tab, LF and CR, the noncharacters U+FFFE / U+FFFF, and lone surrogates.
6
+ So ``run.text = "a\\x0bb"`` (a vertical tab, Word's line break in its object
7
+ model) raises there, before anything is written. docx-studio would take the
8
+ text, and a part holding it is one Word refuses to open.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import re
14
+ from typing import Any
15
+
16
+ XML_INCOMPATIBLE_CHARACTER = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\ud800-\udfff￾￿]")
17
+ XML_INCOMPATIBLE_MESSAGE = (
18
+ "All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters"
19
+ )
20
+
21
+
22
+ def check_xml_compatible(value: Any) -> None:
23
+ """Raise python-docx's ``ValueError`` (lxml's) when a string in ``value``,
24
+ a command's params (strings, lists, dicts), holds a character XML does
25
+ not allow."""
26
+ if isinstance(value, str):
27
+ if XML_INCOMPATIBLE_CHARACTER.search(value):
28
+ raise ValueError(XML_INCOMPATIBLE_MESSAGE)
29
+ elif isinstance(value, dict):
30
+ for item in value.values():
31
+ check_xml_compatible(item)
32
+ elif isinstance(value, (list, tuple)):
33
+ for item in value:
34
+ check_xml_compatible(item)
35
+
36
+
37
+ #: Fields of a write that name text to find, not text to write
38
+ #: (``FindReplace.pattern``): a pattern may match what a document already holds.
39
+ _SEARCH_FIELDS: frozenset[str] = frozenset({"pattern"})
40
+
41
+
42
+ def check_command_text(command: dict[str, Any]) -> None:
43
+ """:func:`check_xml_compatible` over a write's wire fields (a command's
44
+ ``to_dict()``), but for the text it searches for (``_SEARCH_FIELDS``)."""
45
+ check_xml_compatible({key: value for key, value in command.items() if key not in _SEARCH_FIELDS})
46
+
@@ -9,6 +9,8 @@ docx-studio; ``isinstance(cell, BlockItemContainer)`` holds as in python-docx.
9
9
 
10
10
  from __future__ import annotations
11
11
 
12
+ from docx._xml_text import check_xml_compatible
13
+
12
14
  from typing import TYPE_CHECKING, Iterator
13
15
 
14
16
  if TYPE_CHECKING:
@@ -30,6 +32,7 @@ class BlockItemContainer:
30
32
  self, text: str = "", style: "str | ParagraphStyle | None" = None
31
33
  ) -> "Paragraph":
32
34
  """Return paragraph newly added to the end of the content in this container."""
35
+ check_xml_compatible(text)
33
36
  raise NotImplementedError(f"{type(self).__name__} holds no paragraphs")
34
37
 
35
38
  def add_table(self, rows: int, cols: int, width: "Length") -> "Table":