athena-python-docx 0.17.0__tar.gz → 0.18.1__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 (360) hide show
  1. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/PKG-INFO +1 -1
  2. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/__init__.py +1 -1
  3. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/document.py +33 -4
  4. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/run.py +29 -5
  5. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/pyproject.toml +1 -1
  6. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/fake_session.py +9 -0
  7. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_inner_run_format_stash.py +79 -0
  8. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_commands.py +10 -0
  9. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_iter_inner_content.py +62 -0
  10. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/.gitignore +0 -0
  11. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/CLAUDE.md +0 -0
  12. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/DOCX_EXEC_LAB.md +0 -0
  13. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/README.md +0 -0
  14. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_athena_extension.py +0 -0
  15. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_batching.py +0 -0
  16. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_buffer.py +0 -0
  17. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_execution.py +0 -0
  18. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_http.py +0 -0
  19. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_http_doc.py +0 -0
  20. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_image_utils.py +0 -0
  21. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_postproc.py +0 -0
  22. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_ptc.py +0 -0
  23. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_table_styles.py +0 -0
  24. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/_timeouts.py +0 -0
  25. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/api.py +0 -0
  26. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/bookmarks.py +0 -0
  27. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/charts.py +0 -0
  28. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/client.py +0 -0
  29. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/commands.py +0 -0
  30. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/comments.py +0 -0
  31. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/enum/__init__.py +0 -0
  32. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/enum/section.py +0 -0
  33. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/enum/style.py +0 -0
  34. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/enum/table.py +0 -0
  35. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/enum/text.py +0 -0
  36. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/errors.py +0 -0
  37. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/exceptions.py +0 -0
  38. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/fields.py +0 -0
  39. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/footnotes.py +0 -0
  40. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/math.py +0 -0
  41. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/opc/__init__.py +0 -0
  42. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/opc/coreprops.py +0 -0
  43. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/oxml/__init__.py +0 -0
  44. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/revisions.py +0 -0
  45. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/sdt.py +0 -0
  46. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/section.py +0 -0
  47. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/session.py +0 -0
  48. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/settings.py +0 -0
  49. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/shape.py +0 -0
  50. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/shared.py +0 -0
  51. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/styles/__init__.py +0 -0
  52. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/styles/style.py +0 -0
  53. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/styles/styles.py +0 -0
  54. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/table.py +0 -0
  55. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/__init__.py +0 -0
  56. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/font.py +0 -0
  57. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/hyperlink.py +0 -0
  58. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/pagebreak.py +0 -0
  59. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/paragraph.py +0 -0
  60. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/parfmt.py +0 -0
  61. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/text/tabstops.py +0 -0
  62. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/toc.py +0 -0
  63. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/docx/typing.py +0 -0
  64. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/docx_exec_lab.py +0 -0
  65. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  66. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  67. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/docx_exec_lab_server.py +0 -0
  68. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/publish.sh +0 -0
  69. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/release.sh +0 -0
  70. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/round_trip_smoke.py +0 -0
  71. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/smoke_test_block_not_found.py +0 -0
  72. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/scripts/validate_find_replace_asset.py +0 -0
  73. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/__init__.py +0 -0
  74. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/conftest.py +0 -0
  75. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/METHODOLOGY.md +0 -0
  76. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/README.md +0 -0
  77. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/__init__.py +0 -0
  78. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/ab_probe_cases.py +0 -0
  79. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/ab_probe_runner.py +0 -0
  80. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/auto_gen_cases.py +0 -0
  81. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/binary_round_trip.py +0 -0
  82. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/cases.py +0 -0
  83. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/complex_cases.py +0 -0
  84. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/coverage_report.py +0 -0
  85. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/extract.py +0 -0
  86. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/extreme_cases.py +0 -0
  87. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/firm_templates/README.md +0 -0
  88. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/firm_templates/__init__.py +0 -0
  89. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/firm_templates/_runner.py +0 -0
  90. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/firm_templates/extractor.py +0 -0
  91. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  92. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  93. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/local_runner.py +0 -0
  94. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/mega_cases.py +0 -0
  95. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshot.py +0 -0
  96. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  97. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  98. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  99. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  100. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  101. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  102. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  103. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  104. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  105. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  106. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  107. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  108. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  109. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  110. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  111. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  112. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  113. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  114. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  115. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  116. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  117. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  118. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  119. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  120. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  121. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  122. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  123. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  124. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  125. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  126. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  127. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  128. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  129. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  130. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  131. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  132. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  133. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  134. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  135. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  136. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  137. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  138. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  139. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  140. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  141. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  142. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  143. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  144. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  145. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  146. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  147. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  148. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  149. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  150. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  151. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  152. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  153. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  154. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  155. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  156. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  157. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  158. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  159. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  160. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  161. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  162. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  163. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  164. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  165. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  166. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  167. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  168. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  169. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  170. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  171. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  172. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  173. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  174. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  175. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  176. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  177. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  178. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  179. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  180. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  181. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  182. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  183. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  184. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  185. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  186. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  187. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  188. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  189. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  190. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  191. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  192. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  193. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  194. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  195. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  196. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  197. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  198. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  199. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  200. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  201. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  202. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  203. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  204. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  205. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  206. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  207. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  208. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  209. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  210. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  211. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  212. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  213. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  214. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  215. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  216. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  217. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  218. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  219. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  220. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  221. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  222. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  223. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  224. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  225. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  226. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  227. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  228. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  229. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  230. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  231. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  232. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  233. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  234. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  235. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  236. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  237. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  238. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  239. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  240. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  241. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  242. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  243. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/ours_spec.json +0 -0
  244. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/parity_crawl.py +0 -0
  245. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/parity_diff.json +0 -0
  246. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/real_world_cases.py +0 -0
  247. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/round_trip_tests.py +0 -0
  248. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/runner.py +0 -0
  249. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/stock_spec.json +0 -0
  250. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/fidelity/test_e2e_against_staging.py +0 -0
  251. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/README.md +0 -0
  252. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/__init__.py +0 -0
  253. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/baseline_gaps.json +0 -0
  254. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/compare.py +0 -0
  255. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/intentional_deviations.json +0 -0
  256. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/introspect.py +0 -0
  257. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  258. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/reports/gap_report.json +0 -0
  259. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/run_parity.py +0 -0
  260. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/snapshots/athena_latest.json +0 -0
  261. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  262. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/parity/test_parity_gap.py +0 -0
  263. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_add_section_extract_items.py +0 -0
  264. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_athena_extensions_contract.py +0 -0
  265. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_athena_extensions_registry.py +0 -0
  266. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_batching_perf.py +0 -0
  267. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_block_not_found_error.py +0 -0
  268. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_buffer.py +0 -0
  269. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  270. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_add_table_not_supported.py +0 -0
  271. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  272. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  273. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_inner_format_stash.py +0 -0
  274. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_inner_run_guard.py +0 -0
  275. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_text_plain_fastpath.py +0 -0
  276. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_cell_text_replace_semantics.py +0 -0
  277. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_collapsed_range_format.py +0 -0
  278. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_command_dataclasses.py +0 -0
  279. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_comments.py +0 -0
  280. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_document_asset_id_property.py +0 -0
  281. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_document_clear.py +0 -0
  282. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_document_create.py +0 -0
  283. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_document_create_from_template.py +0 -0
  284. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_document_factory_validation.py +0 -0
  285. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_docx_exec_lab.py +0 -0
  286. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_docx_exec_lab_server.py +0 -0
  287. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_e2e_partial_failure_cascade.py +0 -0
  288. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_execution_scope.py +0 -0
  289. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_find_replace_session_open.py +0 -0
  290. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_http_transport.py +0 -0
  291. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_hyperlink_coalescing.py +0 -0
  292. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_image_url_data_uri.py +0 -0
  293. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_insert_deferred.py +0 -0
  294. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_list_styles.py +0 -0
  295. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_merged_cell_secondary_slot.py +0 -0
  296. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_merged_cells.py +0 -0
  297. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_oxml_shim.py +0 -0
  298. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_paragraph_text_len_cache.py +0 -0
  299. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_parity_misc.py +0 -0
  300. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_parity_round2.py +0 -0
  301. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_partial_failure_cascade.py +0 -0
  302. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_phase_a_behavior.py +0 -0
  303. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_phase_b_headers_footers.py +0 -0
  304. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_phase_c_tables.py +0 -0
  305. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_postproc_cell_format_rewrite.py +0 -0
  306. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  307. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_postproc_ref_restore.py +0 -0
  308. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_pr19766_review_fixes.py +0 -0
  309. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_ptc.py +0 -0
  310. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_python_docx_api_parity.py +0 -0
  311. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_revisions.py +0 -0
  312. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  313. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_add_picture.py +0 -0
  314. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_add_run.py +0 -0
  315. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  316. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_comments_add_comment.py +0 -0
  317. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_comments_get.py +0 -0
  318. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_document_audit.py +0 -0
  319. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_document_element.py +0 -0
  320. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_enum_section.py +0 -0
  321. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_font_audit.py +0 -0
  322. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_header_footer.py +0 -0
  323. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_hyperlink.py +0 -0
  324. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_inline_shape.py +0 -0
  325. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  326. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_misc.py +0 -0
  327. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_paragraph_strict.py +0 -0
  328. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_paragraph_style.py +0 -0
  329. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  330. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_parfmt.py +0 -0
  331. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_row_col_cell.py +0 -0
  332. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_run_add_break.py +0 -0
  333. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_run_bool_setters.py +0 -0
  334. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_run_style.py +0 -0
  335. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_run_style_strict.py +0 -0
  336. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_run_text.py +0 -0
  337. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_run_underline.py +0 -0
  338. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_section_audit.py +0 -0
  339. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_section_dimensions.py +0 -0
  340. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_section_onoff.py +0 -0
  341. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_settings.py +0 -0
  342. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_shared_audit.py +0 -0
  343. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_style.py +0 -0
  344. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_styles.py +0 -0
  345. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_table_audit.py +0 -0
  346. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_table_cell.py +0 -0
  347. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_table_dimensions.py +0 -0
  348. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_silent_stub_table_layout.py +0 -0
  349. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_smoke_integration.py +0 -0
  350. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_style_acceptance.py +0 -0
  351. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_style_font.py +0 -0
  352. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_style_setters_contract.py +0 -0
  353. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_table_set_cell_perf.py +0 -0
  354. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_table_style_id_resolution.py +0 -0
  355. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_temporarily_unavailable.py +0 -0
  356. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_validate_find_replace_asset_script.py +0 -0
  357. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_wire_contract.py +0 -0
  358. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_xml_attr_guard.py +0 -0
  359. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/tests/test_zod_wire_contract.py +0 -0
  360. {athena_python_docx-0.17.0 → athena_python_docx-0.18.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: athena-python-docx
3
- Version: 0.17.0
3
+ Version: 0.18.1
4
4
  Summary: Drop-in replacement for python-docx that connects to Athena's Superdoc/Keryx 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.17.0"
9
+ __version__ = "0.18.1"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import flush_all
@@ -386,10 +386,18 @@ class Document:
386
386
  for b in blocks:
387
387
  if not isinstance(b, dict):
388
388
  continue
389
+ nt_raw = b.get("nodeType")
390
+ nt: str = nt_raw if isinstance(nt_raw, str) and nt_raw else "paragraph"
391
+ # Tables belong to ``Document.tables``, never ``Document.paragraphs``
392
+ # (python-docx parity). The server honors the ``nodeTypes`` filter,
393
+ # but defend against an unfiltered response too: skip table blocks so
394
+ # they never surface here as Paragraph proxies (each would otherwise
395
+ # cost 3 live reads in a paragraph loop). Denylist, not allowlist, so
396
+ # we don't drop paragraph-like types we don't explicitly know.
397
+ if nt == "table":
398
+ continue
389
399
  node_id: str = str(b.get("nodeId", ""))
390
400
  if node_id:
391
- nt_raw = b.get("nodeType")
392
- nt: str = nt_raw if isinstance(nt_raw, str) and nt_raw else "paragraph"
393
401
  # Seed the read cache when the server inlined this block's runs.
394
402
  # The snapshot is ``get_node_by_id``-shaped so
395
403
  # ``Paragraph._node_info`` and the text/runs/style getters consume
@@ -455,11 +463,17 @@ class Document:
455
463
  from docx.text.paragraph import Paragraph
456
464
 
457
465
  self._ensure_open()
466
+ # Request the inlined run breakdown so each yielded Paragraph serves
467
+ # ``.text`` / ``.runs`` / ``.style`` from the one ``blocks.list`` instead
468
+ # of a ``get_node_by_id`` per item — without this, iterating and reading
469
+ # N blocks is N round-trips (each a full Y.Doc reload on docx-editor).
470
+ # Same prefetch as ``Document.paragraphs``; see PERFORMANCE_BATCHING_ANALYSIS.md.
458
471
  raw: object = run_sync(
459
472
  self._session.doc.blocks.list(
460
473
  {
461
474
  "nodeTypes": ["paragraph", "heading", "table"],
462
- "includeText": False,
475
+ "includeText": True,
476
+ "includeRuns": True,
463
477
  },
464
478
  ),
465
479
  )
@@ -480,10 +494,18 @@ class Document:
480
494
  if nt == "table":
481
495
  yield Table(session=self._session, node_id=node_id)
482
496
  else:
497
+ # Seed the read cache when the server inlined this block's runs
498
+ # (get_node_by_id-shaped snapshot, consumed unchanged by
499
+ # Paragraph._node_info). Tables / un-inlined blocks fall back to
500
+ # live queries.
501
+ snapshot: dict | None = (
502
+ {"node": b} if isinstance(b.get("paragraph"), dict) else None
503
+ )
483
504
  yield Paragraph(
484
505
  session=self._session,
485
506
  node_id=node_id,
486
507
  node_type=nt if isinstance(nt, str) else "paragraph",
508
+ node_info_snapshot=snapshot,
487
509
  )
488
510
 
489
511
  @property
@@ -2202,10 +2224,17 @@ def _extract_inserted_node_id(result: dict, *, expected_type: str) -> str:
2202
2224
  if block_id:
2203
2225
  return block_id
2204
2226
 
2205
- # Shape 3 — top-level blockId or target.blockId.
2227
+ # Shape 3 — top-level blockId / nodeId, or target.blockId. The docx-editor
2228
+ # engine returns a flat ``{"changed": True, "nodeId": "<paraId>"}`` for
2229
+ # create ops (no SuperDoc-style nesting), so accept a top-level ``nodeId``
2230
+ # too — otherwise response-bearing creates (insert_paragraph_before,
2231
+ # add_caption) raise "did not return nodeId" even though the block was made.
2206
2232
  top_block: object = result.get("blockId")
2207
2233
  if isinstance(top_block, str) and top_block:
2208
2234
  return top_block
2235
+ top_node: object = result.get("nodeId")
2236
+ if isinstance(top_node, str) and top_node:
2237
+ return top_node
2209
2238
  top_target: object = result.get("target")
2210
2239
  if isinstance(top_target, dict):
2211
2240
  tb: str = str(top_target.get("blockId", ""))
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import re
5
6
  from typing import TYPE_CHECKING, Any, BinaryIO
6
7
 
7
8
  from docx._athena_extension import athena_extension
@@ -9,6 +10,14 @@ from docx._batching import run_sync
9
10
  from docx.enum.text import WD_BREAK
10
11
  from docx.shared import Length, Pt, RGBColor # noqa: F401
11
12
 
13
+ # docx-editor addresses cell-inner paragraphs by the cell's synthetic id
14
+ # (``tc:tableIndex:row:col``) because cell paragraphs carry no paraId. Its
15
+ # applier routes a ``FormatApply`` against such an id to a positional
16
+ # whole-cell mark, so cell-inner run formatting can apply live. SuperDoc cell
17
+ # ids are not ``tc:``-shaped, so this discriminator leaves the SuperDoc
18
+ # warn-and-skip path (post-export OOXML rewrite only) untouched.
19
+ _DOCX_EDITOR_CELL_ID_RE = re.compile(r"^tc:\d+:\d+:\d+$")
20
+
12
21
 
13
22
  class PendingBreakDegradationWarning(UserWarning):
14
23
  """Emitted when ``Run.add_break`` is called with a break type that
@@ -970,12 +979,27 @@ class Run:
970
979
  # has text — see ``_pending_inline`` in ``__init__`` for the
971
980
  # python-docx parity rationale.
972
981
  if getattr(self, "_in_cell", False):
973
- # Cell-inner runs cannot apply formatting at the live wire
974
- # layer (SuperDoc 1.8.1 rejects ``doc.format.apply`` for
975
- # paragraphs nested inside ``tableCell``). Stash for the
976
- # post-export OOXML rewrite BEFORE we emit the warning so
977
- # the formatting still lands in the exported ``.docx``.
982
+ # Stash for the post-export OOXML rewrite FIRST so the formatting
983
+ # lands in the exported ``.docx`` regardless of engine (and is the
984
+ # only path on the legacy SuperDoc engine, which rejects
985
+ # ``doc.format.apply`` for paragraphs nested inside ``tableCell``).
978
986
  self._stash_cell_inner_run_format(kwargs)
987
+ # docx-editor CAN apply cell-inner formatting live: it addresses
988
+ # the cell paragraph by the cell's synthetic id and routes a
989
+ # ``FormatApply`` against that id to a positional whole-cell mark.
990
+ # Ship it so collaborators see the change immediately instead of
991
+ # only at export. The ``tc:``-shape discriminator keeps the
992
+ # SuperDoc warn-and-skip path intact (its cell ids differ).
993
+ block_id = getattr(self, "_block_id", "")
994
+ if isinstance(block_id, str) and _DOCX_EDITOR_CELL_ID_RE.match(
995
+ block_id,
996
+ ):
997
+ run_sync(
998
+ self._session.doc.format.apply(
999
+ {"target": self._text_range, "inline": kwargs},
1000
+ ),
1001
+ )
1002
+ return
979
1003
  self._check_cell_inner(
980
1004
  "font/format (bold/italic/font.size/etc.)",
981
1005
  )
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-docx"
7
- version = "0.17.0"
7
+ version = "0.18.1"
8
8
  description = "Drop-in replacement for python-docx that connects to Athena's Superdoc/Keryx collaborative document stack"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -121,6 +121,11 @@ class FakeDocState:
121
121
  self.sections: list[_Section] = [_Section("sec_1")]
122
122
  self.images: list[dict] = []
123
123
  self.calls: list[tuple[str, dict]] = []
124
+ # When True, ``blocks.list`` ignores the requested ``nodeTypes`` and
125
+ # returns every block (tables included), simulating the docx-editor
126
+ # server before it honored the filter. Lets tests verify the SDK's own
127
+ # table denylist in ``Document.paragraphs``.
128
+ self.blocks_list_ignore_node_types: bool = False
124
129
 
125
130
  def _new_id(self, prefix: str) -> str:
126
131
  return f"{prefix}_{next(self._ids)}"
@@ -296,6 +301,10 @@ class FakeDocState:
296
301
 
297
302
  if op == "blocks.list":
298
303
  types = params.get("nodeTypes") or None
304
+ # Simulate the pre-fix docx-editor server that ignored the filter and
305
+ # returned every block (tables included), to exercise the SDK denylist.
306
+ if self.blocks_list_ignore_node_types:
307
+ types = None
299
308
  include_runs = bool(params.get("includeRuns"))
300
309
  out_blocks: list[dict] = []
301
310
  for b in self.blocks:
@@ -281,3 +281,82 @@ def test_paragraph_add_run_returns_run_carrying_cell_ooxml_address(
281
281
  r = p.add_run("hello")
282
282
  assert r._in_cell is True
283
283
  assert r._cell_ooxml_address == (None, 5, 2, 1, 0)
284
+
285
+
286
+ # ---- docx-editor live-ship path (block_id is a `tc:` synthetic cell id) ----
287
+
288
+
289
+ def _make_docx_editor_cell_run(
290
+ mock_session: Any,
291
+ *,
292
+ cell_ooxml_address: tuple[int | None, int, int, int, int] | None = None,
293
+ ) -> Any:
294
+ """A cell-inner Run whose ``block_id`` is the docx-editor synthetic cell
295
+ id (``tc:table:row:col``) — the shape ``cell.paragraphs[].runs`` produce
296
+ on the docx-editor engine, where cell paragraphs have no paraId."""
297
+ from docx.text.run import Run
298
+
299
+ return Run(
300
+ session=mock_session,
301
+ block_id="tc:0:1:2",
302
+ range_=(0, 5),
303
+ in_cell=True,
304
+ cell_ooxml_address=cell_ooxml_address,
305
+ )
306
+
307
+
308
+ def test_docx_editor_cell_run_font_size_ships_format_apply_live(
309
+ mock_session: Any, fake_sd_methods: Any
310
+ ) -> None:
311
+ """On docx-editor, setting ``run.font.size`` on a cell-inner run ships a
312
+ live ``format.apply`` targeting the cell's synthetic id — no warn-and-skip.
313
+ The applier routes that target to a positional whole-cell mark."""
314
+ from docx.shared import Pt
315
+
316
+ with warnings.catch_warnings(record=True) as w:
317
+ warnings.simplefilter("always", CellInnerFormatNotSupportedWarning)
318
+ r = _make_docx_editor_cell_run(mock_session)
319
+ r.font.size = Pt(9)
320
+ warned = [
321
+ x for x in w if issubclass(x.category, CellInnerFormatNotSupportedWarning)
322
+ ]
323
+ # No warn-and-skip on docx-editor — it applies live.
324
+ assert warned == []
325
+ format_apply_ops = [c for c in fake_sd_methods.calls if c[0] == "format.apply"]
326
+ assert len(format_apply_ops) == 1
327
+ _, params = format_apply_ops[0]
328
+ assert params["target"]["blockId"] == "tc:0:1:2"
329
+ assert params["target"]["range"] == {"start": 0, "end": 5}
330
+ assert params["inline"] == {"fontSize": 9.0}
331
+
332
+
333
+ def test_docx_editor_cell_run_bold_ships_format_apply_live(
334
+ mock_session: Any, fake_sd_methods: Any
335
+ ) -> None:
336
+ r = _make_docx_editor_cell_run(mock_session)
337
+ with warnings.catch_warnings():
338
+ warnings.simplefilter("ignore", CellInnerFormatNotSupportedWarning)
339
+ r.bold = True
340
+ format_apply_ops = [c for c in fake_sd_methods.calls if c[0] == "format.apply"]
341
+ assert len(format_apply_ops) == 1
342
+ assert format_apply_ops[0][1]["inline"] == {"bold": True}
343
+
344
+
345
+ def test_docx_editor_cell_run_still_stashes_for_export_when_addressable(
346
+ mock_session: Any, fake_sd_methods: Any
347
+ ) -> None:
348
+ """When the parent table was created in-session (cell_ooxml_address set),
349
+ the run both ships live AND stashes for the post-export OOXML rewrite, so
350
+ ``export_docx`` carries the formatting too."""
351
+ from docx.shared import Pt
352
+
353
+ ops = _attach_real_post_export_ops(mock_session)
354
+ r = _make_docx_editor_cell_run(mock_session, cell_ooxml_address=(None, 0, 1, 2, 0))
355
+ with warnings.catch_warnings():
356
+ warnings.simplefilter("ignore", CellInnerFormatNotSupportedWarning)
357
+ r.font.size = Pt(9)
358
+ # Live wire call shipped.
359
+ assert any(c[0] == "format.apply" for c in fake_sd_methods.calls)
360
+ # AND stashed for export fidelity.
361
+ addr = CellAddress(table_doc_index=0, row=1, col=2, paragraph_index=0)
362
+ assert ops._cell_run_format_ops[addr]["font_size_pt"] == 9.0
@@ -268,6 +268,16 @@ def test_extract_inserted_node_id_shapes() -> None:
268
268
  }
269
269
  assert _extract_inserted_node_id(r3, expected_type="paragraph") == "nX"
270
270
 
271
+ # docx-editor engine shape — flat top-level ``nodeId`` (no SuperDoc nesting).
272
+ # This is what ``CreateParagraph`` returns on docx-editor; before the fix it
273
+ # fell through to "" and ``insert_paragraph_before`` raised on success.
274
+ r4 = {"changed": True, "nodeId": "87753FA6"}
275
+ assert _extract_inserted_node_id(r4, expected_type="paragraph") == "87753FA6"
276
+
277
+ # docx-editor also (post server-fix) emits the nested type-keyed shape.
278
+ r5 = {"changed": True, "nodeId": "AB12CD34", "paragraph": {"nodeId": "AB12CD34"}}
279
+ assert _extract_inserted_node_id(r5, expected_type="paragraph") == "AB12CD34"
280
+
271
281
  # Unparseable — returns empty string
272
282
  assert _extract_inserted_node_id({}, expected_type="paragraph") == ""
273
283
  assert _extract_inserted_node_id("not a dict", expected_type="paragraph") == "" # type: ignore[arg-type]
@@ -35,6 +35,43 @@ def test_document_iter_inner_content_yields_paragraphs_then_table() -> None:
35
35
  assert all(isinstance(i, (Paragraph, Table)) for i in items)
36
36
 
37
37
 
38
+ def test_iter_inner_content_prefetches_runs_no_per_item_reads() -> None:
39
+ """``iter_inner_content`` requests ``includeRuns`` and seeds each yielded
40
+ Paragraph's snapshot, so reading ``.text`` / ``.runs`` / ``.style`` per item
41
+ costs no extra ``getNodeById`` — the slow path was one query per block (each a
42
+ full Y.Doc reload on docx-editor). Mirrors ``Document.paragraphs``."""
43
+ install_fake_session()
44
+ from docx import Document
45
+ from docx.text.paragraph import Paragraph
46
+
47
+ doc = Document("asset_fake")
48
+ doc.add_paragraph("Intro")
49
+ doc.add_heading("Section A", level=1)
50
+ doc.add_paragraph("Body")
51
+
52
+ items = list(doc.iter_inner_content())
53
+
54
+ # The listing asked the server to inline runs.
55
+ block_list_calls = [
56
+ params
57
+ for op, params in doc._session.calls()
58
+ if op == "blocks.list" and params.get("includeRuns") is True
59
+ ]
60
+ assert block_list_calls
61
+
62
+ # Reading text/style/runs off the iterated paragraphs issues NO per-item reads.
63
+ calls_before: int = len(doc._session.calls())
64
+ for item in items:
65
+ if isinstance(item, Paragraph):
66
+ _ = item.text
67
+ _ = item.style
68
+ _ = list(item.runs)
69
+ extra_node_reads = [
70
+ op for op, _ in doc._session.calls()[calls_before:] if op == "getNodeById"
71
+ ]
72
+ assert extra_node_reads == []
73
+
74
+
38
75
  def test_document_paragraphs_prefetches_runs_in_one_listing() -> None:
39
76
  """``Document.paragraphs`` issues ONE rich ``blocks.list(includeRuns=True)``
40
77
  and hydrates every proxy's text/style/runs from it — so iterating and reading
@@ -133,6 +170,31 @@ def test_document_tables_uses_lightweight_block_listing() -> None:
133
170
  assert not any(op == "find" and params == {"type": "table"} for op, params in calls)
134
171
 
135
172
 
173
+ def test_document_paragraphs_excludes_tables_even_if_server_unfiltered() -> None:
174
+ """``Document.paragraphs`` must never return tables (python-docx parity).
175
+ The docx-editor server now honors the ``nodeTypes`` filter, but the SDK also
176
+ denylists table blocks defensively — verified here by simulating the pre-fix
177
+ server that returned every block regardless of the requested ``nodeTypes``."""
178
+ install_fake_session()
179
+ from docx import Document
180
+ from docx.text.paragraph import Paragraph
181
+
182
+ doc = Document("asset_fake")
183
+ doc.add_paragraph("Body one")
184
+ doc.add_paragraph("Body two")
185
+ doc.add_table(rows=2, cols=2)
186
+
187
+ # Simulate the unfiltered docx-editor server (tables leak into the response).
188
+ doc._session.state().blocks_list_ignore_node_types = True
189
+
190
+ paras = doc.paragraphs
191
+ # Every returned item is a Paragraph and NONE is a table block.
192
+ assert all(isinstance(p, Paragraph) for p in paras)
193
+ assert all(p._node_type != "table" for p in paras)
194
+ # Exactly the two body paragraphs — the table is excluded.
195
+ assert len(paras) == 2
196
+
197
+
136
198
  def test_paragraph_iter_inner_content_yields_runs() -> None:
137
199
  install_fake_session()
138
200
  from docx import Document