athena-python-docx 0.16.0__tar.gz → 0.16.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 (359) hide show
  1. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/PKG-INFO +1 -1
  2. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/__init__.py +1 -1
  3. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_buffer.py +16 -1
  4. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/commands.py +5 -0
  5. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/document.py +22 -2
  6. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/paragraph.py +49 -7
  7. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/pyproject.toml +1 -1
  8. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/fake_session.py +7 -0
  9. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_iter_inner_content.py +65 -3
  10. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_ptc.py +40 -0
  11. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/.gitignore +0 -0
  12. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/CLAUDE.md +0 -0
  13. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/DOCX_EXEC_LAB.md +0 -0
  14. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/README.md +0 -0
  15. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_athena_extension.py +0 -0
  16. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_batching.py +0 -0
  17. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_execution.py +0 -0
  18. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_http.py +0 -0
  19. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_http_doc.py +0 -0
  20. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_image_utils.py +0 -0
  21. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_postproc.py +0 -0
  22. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_ptc.py +0 -0
  23. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_table_styles.py +0 -0
  24. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/_timeouts.py +0 -0
  25. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/api.py +0 -0
  26. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/bookmarks.py +0 -0
  27. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/charts.py +0 -0
  28. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/client.py +0 -0
  29. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/comments.py +0 -0
  30. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/enum/__init__.py +0 -0
  31. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/enum/section.py +0 -0
  32. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/enum/style.py +0 -0
  33. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/enum/table.py +0 -0
  34. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/enum/text.py +0 -0
  35. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/errors.py +0 -0
  36. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/exceptions.py +0 -0
  37. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/fields.py +0 -0
  38. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/footnotes.py +0 -0
  39. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/math.py +0 -0
  40. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/opc/__init__.py +0 -0
  41. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/opc/coreprops.py +0 -0
  42. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/oxml/__init__.py +0 -0
  43. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/revisions.py +0 -0
  44. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/sdt.py +0 -0
  45. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/section.py +0 -0
  46. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/session.py +0 -0
  47. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/settings.py +0 -0
  48. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/shape.py +0 -0
  49. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/shared.py +0 -0
  50. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/styles/__init__.py +0 -0
  51. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/styles/style.py +0 -0
  52. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/styles/styles.py +0 -0
  53. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/table.py +0 -0
  54. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/__init__.py +0 -0
  55. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/font.py +0 -0
  56. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/hyperlink.py +0 -0
  57. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/pagebreak.py +0 -0
  58. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/parfmt.py +0 -0
  59. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/run.py +0 -0
  60. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/text/tabstops.py +0 -0
  61. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/toc.py +0 -0
  62. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/docx/typing.py +0 -0
  63. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/docx_exec_lab.py +0 -0
  64. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  65. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  66. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/docx_exec_lab_server.py +0 -0
  67. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/publish.sh +0 -0
  68. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/release.sh +0 -0
  69. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/round_trip_smoke.py +0 -0
  70. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/smoke_test_block_not_found.py +0 -0
  71. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/scripts/validate_find_replace_asset.py +0 -0
  72. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/__init__.py +0 -0
  73. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/conftest.py +0 -0
  74. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/METHODOLOGY.md +0 -0
  75. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/README.md +0 -0
  76. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/__init__.py +0 -0
  77. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/ab_probe_cases.py +0 -0
  78. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/ab_probe_runner.py +0 -0
  79. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/auto_gen_cases.py +0 -0
  80. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/binary_round_trip.py +0 -0
  81. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/cases.py +0 -0
  82. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/complex_cases.py +0 -0
  83. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/coverage_report.py +0 -0
  84. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/extract.py +0 -0
  85. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/extreme_cases.py +0 -0
  86. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/firm_templates/README.md +0 -0
  87. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/firm_templates/__init__.py +0 -0
  88. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/firm_templates/_runner.py +0 -0
  89. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/firm_templates/extractor.py +0 -0
  90. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  91. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  92. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/local_runner.py +0 -0
  93. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/mega_cases.py +0 -0
  94. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshot.py +0 -0
  95. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  96. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  97. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  98. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  99. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  100. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  101. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  102. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  103. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  104. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  105. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  106. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  107. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  108. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  109. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  110. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  111. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  112. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  113. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  114. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  115. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  116. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  117. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  118. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  119. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  120. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  121. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  122. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  123. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  124. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  125. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  126. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  127. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  128. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  129. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  130. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  131. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  132. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  133. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  134. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  135. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  136. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  137. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  138. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  139. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  140. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  141. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  142. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  143. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  144. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  145. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  146. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  147. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  148. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  149. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  150. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  151. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  152. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  153. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  154. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  155. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  156. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  157. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  158. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  159. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  160. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  161. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  162. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  163. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  164. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  165. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  166. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  167. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  168. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  169. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  170. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  171. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  172. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  173. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  174. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  175. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  176. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  177. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  178. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  179. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  180. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  181. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  182. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  183. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  184. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  185. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  186. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  187. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  188. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  189. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  190. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  191. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  192. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  193. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  194. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  195. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  196. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  197. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  198. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  199. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  200. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  201. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  202. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  203. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  204. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  205. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  206. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  207. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  208. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  209. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  210. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  211. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  212. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  213. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  214. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  215. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  216. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  217. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  218. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  219. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  220. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  221. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  222. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  223. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  224. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  225. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  226. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  227. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  228. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  229. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  230. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  231. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  232. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  233. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  234. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  235. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  236. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  237. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  238. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  239. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  240. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  241. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  242. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/ours_spec.json +0 -0
  243. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/parity_crawl.py +0 -0
  244. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/parity_diff.json +0 -0
  245. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/real_world_cases.py +0 -0
  246. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/round_trip_tests.py +0 -0
  247. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/runner.py +0 -0
  248. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/stock_spec.json +0 -0
  249. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/fidelity/test_e2e_against_staging.py +0 -0
  250. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/README.md +0 -0
  251. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/__init__.py +0 -0
  252. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/baseline_gaps.json +0 -0
  253. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/compare.py +0 -0
  254. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/intentional_deviations.json +0 -0
  255. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/introspect.py +0 -0
  256. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  257. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/reports/gap_report.json +0 -0
  258. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/run_parity.py +0 -0
  259. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/snapshots/athena_latest.json +0 -0
  260. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  261. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/parity/test_parity_gap.py +0 -0
  262. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_add_section_extract_items.py +0 -0
  263. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_athena_extensions_contract.py +0 -0
  264. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_athena_extensions_registry.py +0 -0
  265. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_batching_perf.py +0 -0
  266. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_block_not_found_error.py +0 -0
  267. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_buffer.py +0 -0
  268. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  269. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_add_table_not_supported.py +0 -0
  270. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  271. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  272. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_inner_format_stash.py +0 -0
  273. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_inner_run_format_stash.py +0 -0
  274. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_inner_run_guard.py +0 -0
  275. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_text_plain_fastpath.py +0 -0
  276. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_cell_text_replace_semantics.py +0 -0
  277. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_collapsed_range_format.py +0 -0
  278. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_command_dataclasses.py +0 -0
  279. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_commands.py +0 -0
  280. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_comments.py +0 -0
  281. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_document_asset_id_property.py +0 -0
  282. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_document_clear.py +0 -0
  283. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_document_create.py +0 -0
  284. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_document_create_from_template.py +0 -0
  285. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_document_factory_validation.py +0 -0
  286. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_docx_exec_lab.py +0 -0
  287. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_docx_exec_lab_server.py +0 -0
  288. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_e2e_partial_failure_cascade.py +0 -0
  289. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_execution_scope.py +0 -0
  290. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_find_replace_session_open.py +0 -0
  291. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_http_transport.py +0 -0
  292. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_hyperlink_coalescing.py +0 -0
  293. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_insert_deferred.py +0 -0
  294. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_list_styles.py +0 -0
  295. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_merged_cell_secondary_slot.py +0 -0
  296. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_merged_cells.py +0 -0
  297. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_oxml_shim.py +0 -0
  298. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_paragraph_text_len_cache.py +0 -0
  299. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_parity_misc.py +0 -0
  300. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_parity_round2.py +0 -0
  301. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_partial_failure_cascade.py +0 -0
  302. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_phase_a_behavior.py +0 -0
  303. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_phase_b_headers_footers.py +0 -0
  304. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_phase_c_tables.py +0 -0
  305. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_postproc_cell_format_rewrite.py +0 -0
  306. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  307. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_postproc_ref_restore.py +0 -0
  308. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_pr19766_review_fixes.py +0 -0
  309. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_python_docx_api_parity.py +0 -0
  310. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_revisions.py +0 -0
  311. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  312. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_add_picture.py +0 -0
  313. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_add_run.py +0 -0
  314. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  315. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_comments_add_comment.py +0 -0
  316. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_comments_get.py +0 -0
  317. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_document_audit.py +0 -0
  318. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_document_element.py +0 -0
  319. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_enum_section.py +0 -0
  320. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_font_audit.py +0 -0
  321. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_header_footer.py +0 -0
  322. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_hyperlink.py +0 -0
  323. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_inline_shape.py +0 -0
  324. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  325. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_misc.py +0 -0
  326. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_paragraph_strict.py +0 -0
  327. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_paragraph_style.py +0 -0
  328. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  329. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_parfmt.py +0 -0
  330. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_row_col_cell.py +0 -0
  331. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_run_add_break.py +0 -0
  332. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_run_bool_setters.py +0 -0
  333. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_run_style.py +0 -0
  334. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_run_style_strict.py +0 -0
  335. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_run_text.py +0 -0
  336. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_run_underline.py +0 -0
  337. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_section_audit.py +0 -0
  338. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_section_dimensions.py +0 -0
  339. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_section_onoff.py +0 -0
  340. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_settings.py +0 -0
  341. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_shared_audit.py +0 -0
  342. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_style.py +0 -0
  343. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_styles.py +0 -0
  344. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_table_audit.py +0 -0
  345. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_table_cell.py +0 -0
  346. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_table_dimensions.py +0 -0
  347. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_silent_stub_table_layout.py +0 -0
  348. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_smoke_integration.py +0 -0
  349. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_style_acceptance.py +0 -0
  350. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_style_font.py +0 -0
  351. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_style_setters_contract.py +0 -0
  352. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_table_set_cell_perf.py +0 -0
  353. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_table_style_id_resolution.py +0 -0
  354. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_temporarily_unavailable.py +0 -0
  355. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_validate_find_replace_asset_script.py +0 -0
  356. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_wire_contract.py +0 -0
  357. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_xml_attr_guard.py +0 -0
  358. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/tests/test_zod_wire_contract.py +0 -0
  359. {athena_python_docx-0.16.0 → athena_python_docx-0.16.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: athena-python-docx
3
- Version: 0.16.0
3
+ Version: 0.16.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.16.0"
9
+ __version__ = "0.16.1"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import flush_all
@@ -130,6 +130,21 @@ if TYPE_CHECKING:
130
130
  _PTC_EMIT_TOOLS: frozenset[str] = frozenset({"CreateParagraph", "CreateHeading", "CreateTable"})
131
131
 
132
132
 
133
+ def _should_emit_ptc(cmd: Command) -> bool:
134
+ """Whether ``cmd`` should produce a PTC sub-tool-card.
135
+
136
+ Only allow-listed block creates emit, and only when they target the
137
+ **body** story. Creates carrying an ``in_`` story locator (header,
138
+ footer, footnote, …) are skipped: the frontend locate affordance
139
+ scans the body editor only, so a header/footer card would highlight
140
+ an unrelated body block or nothing at all. Skip until the frontend
141
+ can route by ``args.in``.
142
+ """
143
+ if type(cmd).__name__ not in _PTC_EMIT_TOOLS:
144
+ return False
145
+ return getattr(cmd, "in_", None) is None
146
+
147
+
133
148
  def _ptc_emit_end_batch(cmds: list[Command], *, is_error: bool) -> None:
134
149
  """Emit a PTC ``end`` event for every cmd that received a ``begin``.
135
150
 
@@ -414,7 +429,7 @@ class CommandBuffer:
414
429
  # commands still flow through the buffer (and through the batched
415
430
  # HTTP POST), they just don't produce a sub-tool-card. ``emit_end``
416
431
  # is automatically skipped because no ``_ptc_call_id`` was set.
417
- if type(cmd).__name__ in _PTC_EMIT_TOOLS:
432
+ if _should_emit_ptc(cmd):
418
433
  try:
419
434
  cmd._ptc_call_id = _ptc.emit_begin( # type: ignore[attr-defined]
420
435
  type(cmd).__name__,
@@ -519,6 +519,11 @@ class ImagesGet(Command):
519
519
  class BlocksList(Command):
520
520
  node_types: list[str] | None = None
521
521
  include_text: bool | None = None
522
+ # Ask the server to inline each paragraph/heading block's run breakdown
523
+ # (``paragraph.inlines``) so ``Document.paragraphs`` can hydrate
524
+ # ``Paragraph.text``/``.runs``/``.style`` from one list instead of a
525
+ # ``get_node_by_id`` per paragraph. Serialized to ``includeRuns`` on the wire.
526
+ include_runs: bool | None = None
522
527
 
523
528
 
524
529
  @dataclass
@@ -359,12 +359,23 @@ class Document:
359
359
  # Include "heading" too so iterating over paragraphs covers both —
360
360
  # python-docx does not distinguish headings from paragraphs at the
361
361
  # Document.paragraphs level either (they're all Paragraph instances).
362
+ # ``includeRuns`` asks the server to inline each block's run breakdown
363
+ # (``paragraph.inlines``) so we can hydrate every returned proxy's
364
+ # ``.text`` / ``.runs`` / ``.style`` from this single list — instead of
365
+ # one ``get_node_by_id`` round-trip per paragraph per property. A
366
+ # read-heavy restyle loop over a large doc drops from ~N×3 round-trips
367
+ # to 1. See ``docx-studio/PERFORMANCE_BATCHING_ANALYSIS.md``.
362
368
  raw: object = run_sync(
363
369
  self._session.doc.blocks.list(
364
- {"nodeTypes": ["paragraph", "heading"], "includeText": False},
370
+ {
371
+ "nodeTypes": ["paragraph", "heading"],
372
+ "includeText": True,
373
+ "includeRuns": True,
374
+ },
365
375
  ),
366
376
  )
367
- # Real shape: {"blocks": [{"kind":"block","nodeType":..,"nodeId":..}], ...}
377
+ # Real shape: {"blocks": [{"kind":"block","nodeType":..,"nodeId":..,
378
+ # "styleId":..,"text":..,"paragraph":{"inlines":[..]}}], ...}
368
379
  if isinstance(raw, dict):
369
380
  blocks_obj: object = raw.get("blocks", [])
370
381
  blocks: list = blocks_obj if isinstance(blocks_obj, list) else []
@@ -380,11 +391,20 @@ class Document:
380
391
  if node_id:
381
392
  nt_raw = b.get("nodeType")
382
393
  nt: str = nt_raw if isinstance(nt_raw, str) and nt_raw else "paragraph"
394
+ # Seed the read cache when the server inlined this block's runs.
395
+ # The snapshot is ``get_node_by_id``-shaped so
396
+ # ``Paragraph._node_info`` and the text/runs/style getters consume
397
+ # it unchanged. Blocks without an ``inlines`` payload (e.g.
398
+ # tables) fall back to live queries.
399
+ snapshot: dict | None = (
400
+ {"node": b} if isinstance(b.get("paragraph"), dict) else None
401
+ )
383
402
  out.append(
384
403
  Paragraph(
385
404
  session=self._session,
386
405
  node_id=node_id,
387
406
  node_type=nt,
407
+ node_info_snapshot=snapshot,
388
408
  ),
389
409
  )
390
410
  return out
@@ -226,6 +226,7 @@ class Paragraph:
226
226
  in_cell: bool = False,
227
227
  cell_ooxml_address: "tuple[str | None, int, int, int, int] | None" = None,
228
228
  cell: "object | None" = None,
229
+ node_info_snapshot: dict | None = None,
229
230
  ) -> None:
230
231
  self._session: "Session" = session
231
232
  self._node_id: str = node_id
@@ -272,6 +273,36 @@ class Paragraph:
272
273
  # — defensive for paragraph proxies built outside the _Cell
273
274
  # construction paths.
274
275
  self._cell: object | None = cell
276
+ # Prefetched ``get_node_by_id``-shaped snapshot
277
+ # (``{"node": {..., "paragraph": {"inlines": [...]}}}``) seeded by
278
+ # ``Document.paragraphs`` via the bulk ``blocks.list(includeRuns=True)``
279
+ # read. When present, ``text`` / ``runs`` / ``style`` read it instead of
280
+ # issuing a per-property ``get_node_by_id`` round-trip. It is a
281
+ # point-in-time snapshot (consistent with ``Document.paragraphs`` already
282
+ # returning a snapshot list) and is dropped by ``_invalidate_node_info``
283
+ # the moment this proxy mutates its own content.
284
+ self._node_info_snapshot: dict | None = node_info_snapshot
285
+
286
+ def _node_info(self) -> object:
287
+ """Return this paragraph's ``get_node_by_id``-shaped node info.
288
+
289
+ Served from the prefetch snapshot when one was seeded (one bulk
290
+ ``blocks.list`` for the whole document instead of one
291
+ ``get_node_by_id`` per ``.text`` / ``.runs`` / ``.style`` access);
292
+ otherwise a live query. ``_invalidate_node_info`` clears the snapshot
293
+ after a content mutation so the next read re-queries.
294
+ """
295
+ snapshot = self._node_info_snapshot
296
+ if snapshot is not None:
297
+ return snapshot
298
+ return run_sync(
299
+ self._session.doc.get_node_by_id({"id": self._node_id}),
300
+ )
301
+
302
+ def _invalidate_node_info(self) -> None:
303
+ """Drop the prefetched node snapshot after a content mutation, so the
304
+ next ``text`` / ``runs`` / ``style`` read reflects the new state."""
305
+ self._node_info_snapshot = None
275
306
 
276
307
  def _check_cell_inner(self, op: str, **format_props: Any) -> bool:
277
308
  """Return ``True`` if this paragraph is inside a table cell and
@@ -356,7 +387,7 @@ class Paragraph:
356
387
  @property
357
388
  def text(self) -> str:
358
389
  """Return the plain-text content of this paragraph."""
359
- return _node_text(self._session, self._node_id)
390
+ return _extract_text(self._node_info())
360
391
 
361
392
  @text.setter
362
393
  def text(self, value: str) -> None:
@@ -399,6 +430,9 @@ class Paragraph:
399
430
  # We just replaced the entire paragraph contents with ``value``;
400
431
  # the new text-address length is simply ``len(value)``.
401
432
  self._text_len = len(value)
433
+ # Content changed — drop the prefetched snapshot so a follow-up
434
+ # ``.text`` / ``.runs`` read reflects the replacement.
435
+ self._invalidate_node_info()
402
436
 
403
437
  @property
404
438
  def runs(self) -> list["Run"]:
@@ -413,9 +447,7 @@ class Paragraph:
413
447
  """
414
448
  from docx.text.run import Run
415
449
 
416
- info: object = run_sync(
417
- self._session.doc.get_node_by_id({"id": self._node_id}),
418
- )
450
+ info: object = self._node_info()
419
451
  inlines: list[dict] = _walk_inlines(info)
420
452
  runs: list["Run"] = []
421
453
  offset: int = 0
@@ -479,9 +511,7 @@ class Paragraph:
479
511
  from docx.styles.style import ParagraphStyle
480
512
  from docx.enum.style import WD_STYLE_TYPE
481
513
 
482
- info: object = run_sync(
483
- self._session.doc.get_node_by_id({"id": self._node_id}),
484
- )
514
+ info: object = self._node_info()
485
515
  if not isinstance(info, dict):
486
516
  return None
487
517
  node: object = info.get("node")
@@ -537,6 +567,10 @@ class Paragraph:
537
567
  },
538
568
  ),
539
569
  )
570
+ # Style changed — drop the prefetched snapshot so a follow-up ``.style``
571
+ # read reflects the new style instead of the stale prefetched value
572
+ # (the restyle-loop read-after-write this PR's prefetch targets).
573
+ self._invalidate_node_info()
540
574
 
541
575
  @property
542
576
  def alignment(self) -> "WD_ALIGN_PARAGRAPH | None":
@@ -1227,6 +1261,9 @@ class Paragraph:
1227
1261
  )
1228
1262
  offset += 1
1229
1263
  i = j + 1
1264
+ # Inserted content — drop the prefetched node snapshot so a follow-up
1265
+ # ``.text`` / ``.runs`` read on this proxy reflects the new runs.
1266
+ self._invalidate_node_info()
1230
1267
 
1231
1268
  @athena_extension(
1232
1269
  issue=74,
@@ -1397,6 +1434,11 @@ class Paragraph:
1397
1434
  )
1398
1435
  run_sync(self._session.send_command(cmd))
1399
1436
  self._text_len = end_offset
1437
+ # Appended a hyperlink run — drop the prefetched snapshot so a follow-up
1438
+ # ``.text`` / ``.runs`` read reflects the new content. This path fires
1439
+ # ``CreateHyperlink`` directly via ``send_command`` (it bypasses
1440
+ # ``_insert_run_text_segments``), so it needs its own invalidation.
1441
+ self._invalidate_node_info()
1400
1442
 
1401
1443
  run_dict = {"text": text, "hyperlink": {"url": url, "target": url}}
1402
1444
  return Hyperlink(
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-docx"
7
- version = "0.16.0"
7
+ version = "0.16.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"
@@ -296,6 +296,7 @@ class FakeDocState:
296
296
 
297
297
  if op == "blocks.list":
298
298
  types = params.get("nodeTypes") or None
299
+ include_runs = bool(params.get("includeRuns"))
299
300
  out_blocks: list[dict] = []
300
301
  for b in self.blocks:
301
302
  if types and b.node_type not in types:
@@ -307,6 +308,12 @@ class FakeDocState:
307
308
  "styleId": b.style_id,
308
309
  "alignment": b.alignment,
309
310
  }
311
+ # Mirror the real server: when runs are requested, inline each
312
+ # paragraph/heading block's run breakdown so the SDK hydrates
313
+ # Paragraph.text/.runs/.style from this one list (no per-node read).
314
+ if include_runs and b.node_type in ("paragraph", "heading"):
315
+ entry["text"] = b.text
316
+ entry["paragraph"] = {"inlines": list(b.inlines)}
310
317
  out_blocks.append(entry)
311
318
  # Mirror real SuperDoc: when "table" is in the requested
312
319
  # nodeTypes, top-level tables come back too. The fake doesn't
@@ -35,15 +35,22 @@ 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_document_paragraphs_uses_lightweight_block_listing() -> None:
38
+ def test_document_paragraphs_prefetches_runs_in_one_listing() -> None:
39
+ """``Document.paragraphs`` issues ONE rich ``blocks.list(includeRuns=True)``
40
+ and hydrates every proxy's text/style/runs from it — so iterating and reading
41
+ per-paragraph properties costs no extra ``getNodeById`` round-trips (the old
42
+ hot path was one query per property per paragraph). See
43
+ ``docx-studio/PERFORMANCE_BATCHING_ANALYSIS.md``."""
39
44
  install_fake_session()
40
45
  from docx import Document
41
46
 
42
47
  doc = Document("asset_fake")
43
48
  doc.add_paragraph("Intro")
49
+ doc.add_heading("Section A", level=1)
44
50
 
45
- _ = doc.paragraphs
51
+ paras = doc.paragraphs
46
52
 
53
+ # paragraphs() asked the server to inline the run breakdown.
47
54
  block_list_calls = [
48
55
  params
49
56
  for op, params in doc._session.calls()
@@ -51,7 +58,62 @@ def test_document_paragraphs_uses_lightweight_block_listing() -> None:
51
58
  and params.get("nodeTypes") == ["paragraph", "heading"]
52
59
  ]
53
60
  assert block_list_calls
54
- assert block_list_calls[-1]["includeText"] is False
61
+ assert block_list_calls[-1]["includeRuns"] is True
62
+
63
+ # Reading text/style/runs off the prefetched proxies issues NO per-paragraph
64
+ # getNodeById round-trips.
65
+ calls_before: int = len(doc._session.calls())
66
+ for p in paras:
67
+ _ = p.text
68
+ _ = p.style
69
+ _ = list(p.runs)
70
+ extra_node_reads = [
71
+ op for op, _ in doc._session.calls()[calls_before:] if op == "getNodeById"
72
+ ]
73
+ assert extra_node_reads == []
74
+
75
+
76
+ def test_paragraph_text_mutation_invalidates_prefetch_snapshot() -> None:
77
+ """A content mutation on a prefetched paragraph drops its snapshot, so the
78
+ next read reflects the new state instead of the stale prefetched value."""
79
+ install_fake_session()
80
+ from docx import Document
81
+
82
+ doc = Document("asset_fake")
83
+ doc.add_paragraph("Original")
84
+
85
+ p = doc.paragraphs[0]
86
+ assert p.text == "Original" # served from the prefetch snapshot
87
+
88
+ p.text = "Replaced" # content mutation → snapshot invalidated
89
+
90
+ calls_before: int = len(doc._session.calls())
91
+ assert p.text == "Replaced" # re-read reflects the mutation
92
+ # The fresh read went back to the server (the stale snapshot was dropped).
93
+ assert any(
94
+ op == "getNodeById" for op, _ in doc._session.calls()[calls_before:]
95
+ )
96
+
97
+
98
+ def test_paragraph_style_set_invalidates_prefetch_snapshot() -> None:
99
+ """Setting ``.style`` on a prefetched paragraph drops its snapshot, so the
100
+ next ``.style`` read returns the new style — the restyle-loop read-after-write
101
+ (``for p in doc.paragraphs: p.style = ...``) the prefetch optimizes for."""
102
+ install_fake_session()
103
+ from docx import Document
104
+
105
+ doc = Document("asset_fake")
106
+ doc.add_paragraph("Body")
107
+
108
+ p = doc.paragraphs[0]
109
+ _ = p.style # prime the prefetch snapshot
110
+
111
+ p.style = "Heading1" # style mutation → snapshot must be invalidated
112
+
113
+ style_after = p.style
114
+ assert style_after is not None
115
+ # Re-read reflects the new style instead of the stale prefetched value.
116
+ assert style_after.name == "Heading1"
55
117
 
56
118
 
57
119
  def test_document_tables_uses_lightweight_block_listing() -> None:
@@ -524,6 +524,46 @@ def test_buffer_emits_for_create_table(monkeypatch: Any) -> None:
524
524
  assert calls["end"][0]["is_error"] is False
525
525
 
526
526
 
527
+ def test_buffer_skips_ptc_for_non_body_creates(monkeypatch: Any) -> None:
528
+ """Allow-listed creates that target a non-body story (header/footer/
529
+ footnote via ``in_``) do NOT emit a PTC card: the frontend locate
530
+ affordance scans the body editor only, so a header/footer card would
531
+ highlight an unrelated body block or nothing. Body creates still emit."""
532
+ from docx._buffer import CommandBuffer
533
+ from docx.commands import CreateTable
534
+
535
+ calls = _stub_ptc(monkeypatch)
536
+ client = _FakeHttpClient()
537
+ buf = CommandBuffer(client, asset_id="asset-1", auto_flush_seconds=0)
538
+
539
+ # Header/footer table → carries an ``in_`` story locator → no card.
540
+ buf.call(
541
+ CreateTable(
542
+ rows=2,
543
+ columns=2,
544
+ at={"kind": "documentEnd"},
545
+ in_={"kind": "story", "storyType": "headerFooterPart", "refId": "r1"},
546
+ client_node_id="t_header",
547
+ )
548
+ )
549
+ assert len(calls["begin"]) == 0
550
+
551
+ # Body table (no ``in_``) → still emits.
552
+ buf.call(
553
+ CreateTable(
554
+ rows=2,
555
+ columns=2,
556
+ at={"kind": "documentEnd"},
557
+ client_node_id="t_body",
558
+ )
559
+ )
560
+ assert len(calls["begin"]) == 1
561
+
562
+ buf.flush()
563
+ # Only the body create that received a begin gets an end.
564
+ assert len(calls["end"]) == 1
565
+
566
+
527
567
  def test_buffer_emits_end_with_error_on_flush_failure(monkeypatch: Any) -> None:
528
568
  """End events fire with ``is_error=True`` when the batch raises.
529
569