athena-python-docx 0.38.0__tar.gz → 0.39.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/AGENTS.md +47 -18
  2. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/PKG-INFO +1 -1
  3. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/__init__.py +1 -1
  4. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/commands.py +5 -0
  5. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/comments.py +19 -7
  6. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/opc/coreprops.py +27 -8
  7. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/section.py +28 -4
  8. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/shape.py +23 -8
  9. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/styles/_table.py +97 -46
  10. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/styles/style.py +40 -14
  11. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/styles/styles.py +22 -12
  12. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/table.py +17 -4
  13. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/paragraph.py +7 -3
  14. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/parfmt.py +12 -3
  15. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/run.py +16 -4
  16. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/pyproject.toml +1 -1
  17. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/fake_session.py +5 -0
  18. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/baseline.json +47 -5
  19. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_comments.py +28 -0
  20. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_comments_first_read.py +5 -3
  21. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_core_properties.py +26 -0
  22. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_inline_shape_type.py +31 -0
  23. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_inline_shapes_floating.py +22 -0
  24. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_parfmt_clears.py +13 -7
  25. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_phase_b_headers_footers.py +38 -1
  26. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_break_inner_content.py +36 -0
  27. athena_python_docx-0.39.0/tests/test_style_resolution.py +173 -0
  28. athena_python_docx-0.39.0/tests/test_table_length_reads.py +49 -0
  29. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_wire_contract.py +1 -1
  30. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/uv.lock +1 -1
  31. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/.gitignore +0 -0
  32. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/CLAUDE.md +0 -0
  33. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/DOCX_EXEC_LAB.md +0 -0
  34. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/README.md +0 -0
  35. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_athena_extension.py +0 -0
  36. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_batching.py +0 -0
  37. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_buffer.py +0 -0
  38. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_capabilities.py +0 -0
  39. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_citations.py +0 -0
  40. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_execution.py +0 -0
  41. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_http.py +0 -0
  42. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_http_doc.py +0 -0
  43. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_image_utils.py +0 -0
  44. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_postproc.py +0 -0
  45. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_proxy.py +0 -0
  46. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_ptc.py +0 -0
  47. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_references.py +0 -0
  48. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_run_order.py +0 -0
  49. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_table_styles.py +0 -0
  50. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_timeouts.py +0 -0
  51. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_tracked.py +0 -0
  52. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/_xml_text.py +0 -0
  53. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/api.py +0 -0
  54. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/blkcntnr.py +0 -0
  55. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/bookmarks.py +0 -0
  56. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/charts.py +0 -0
  57. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/client.py +0 -0
  58. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/document.py +0 -0
  59. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/drawing/__init__.py +0 -0
  60. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/__init__.py +0 -0
  61. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/base.py +0 -0
  62. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/dml.py +0 -0
  63. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/section.py +0 -0
  64. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/shape.py +0 -0
  65. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/style.py +0 -0
  66. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/table.py +0 -0
  67. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/enum/text.py +0 -0
  68. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/errors.py +0 -0
  69. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/exceptions.py +0 -0
  70. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/fields.py +0 -0
  71. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/footnotes.py +0 -0
  72. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/image/__init__.py +0 -0
  73. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/image/exceptions.py +0 -0
  74. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/image/image.py +0 -0
  75. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/math.py +0 -0
  76. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/opc/__init__.py +0 -0
  77. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/oxml/__init__.py +0 -0
  78. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/revisions.py +0 -0
  79. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/sdt.py +0 -0
  80. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/session.py +0 -0
  81. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/settings.py +0 -0
  82. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/shared.py +0 -0
  83. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/styles/__init__.py +0 -0
  84. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/styles/latent.py +0 -0
  85. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/__init__.py +0 -0
  86. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/font.py +0 -0
  87. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/hyperlink.py +0 -0
  88. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/pagebreak.py +0 -0
  89. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/text/tabstops.py +0 -0
  90. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/toc.py +0 -0
  91. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/docx/typing.py +0 -0
  92. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/docx_exec_lab.py +0 -0
  93. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  94. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  95. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/docx_exec_lab_server.py +0 -0
  96. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/dump_wire_fixtures.py +0 -0
  97. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/release.sh +0 -0
  98. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/round_trip_smoke.py +0 -0
  99. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/smoke_test_block_not_found.py +0 -0
  100. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/scripts/validate_find_replace_asset.py +0 -0
  101. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/__init__.py +0 -0
  102. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/conftest.py +0 -0
  103. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/METHODOLOGY.md +0 -0
  104. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/README.md +0 -0
  105. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/__init__.py +0 -0
  106. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/__init__.py +0 -0
  107. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/agent_documents.py +0 -0
  108. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/default_style_run_formatting.py +0 -0
  109. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/header_footer_pictures.py +0 -0
  110. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/less_used_writes.py +0 -0
  111. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/merged_cell_identity.py +0 -0
  112. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/paragraph_text_setter.py +0 -0
  113. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/picture_runs.py +0 -0
  114. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/proxy_equality.py +0 -0
  115. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/return_types.py +0 -0
  116. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/xml_incompatible_text.py +0 -0
  117. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe/zero_and_negative_indents.py +0 -0
  118. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe_cases.py +0 -0
  119. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ab_probe_runner.py +0 -0
  120. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/auto_gen_cases.py +0 -0
  121. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/binary_round_trip.py +0 -0
  122. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/cases.py +0 -0
  123. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/complex_cases.py +0 -0
  124. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/coverage_report.py +0 -0
  125. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/extract.py +0 -0
  126. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/extreme_cases.py +0 -0
  127. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/firm_templates/README.md +0 -0
  128. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/firm_templates/__init__.py +0 -0
  129. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/firm_templates/_runner.py +0 -0
  130. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/firm_templates/extractor.py +0 -0
  131. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  132. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  133. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/local_runner.py +0 -0
  134. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/mega_cases.py +0 -0
  135. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshot.py +0 -0
  136. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  137. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  138. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  139. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  140. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  141. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  142. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  143. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  144. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  145. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  146. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  147. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  148. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  149. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  150. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  151. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  152. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  153. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  154. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  155. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  156. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  157. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  158. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  159. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  160. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  161. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  162. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  163. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  164. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  165. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  166. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  167. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  168. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  169. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  170. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  171. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  172. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  173. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  174. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  175. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  176. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  177. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  178. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  179. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  180. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  181. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  182. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  183. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  184. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  185. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  186. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  187. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  188. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  189. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  190. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  191. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  192. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  193. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  194. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  195. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  196. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  197. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  198. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  199. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  200. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  201. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  202. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  203. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  204. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  205. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  206. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  207. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  208. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  209. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  210. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  211. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  212. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  213. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  214. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  215. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  216. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  217. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  218. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  219. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  220. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  221. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  222. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  223. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  224. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  225. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  226. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  227. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  228. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  229. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  230. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  231. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  232. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  233. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  234. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  235. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  236. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  237. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  238. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  239. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  240. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  241. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  242. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  243. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  244. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  245. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  246. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  247. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  248. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  249. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  250. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  251. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  252. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  253. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  254. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  255. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  256. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  257. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  258. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  259. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  260. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  261. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  262. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  263. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  264. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  265. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  266. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  267. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  268. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  269. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  270. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  271. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  272. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  273. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  274. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  275. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  276. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  277. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  278. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  279. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  280. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  281. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  282. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  283. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
  284. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
  285. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +0 -0
  286. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
  287. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
  288. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/ours_spec.json +0 -0
  289. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/parity_crawl.py +0 -0
  290. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/parity_diff.json +0 -0
  291. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/real_world_cases.py +0 -0
  292. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/round_trip_tests.py +0 -0
  293. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/stock_spec.json +0 -0
  294. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
  295. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fixtures/field_reads.json +0 -0
  296. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fixtures/note_reference_reads.json +0 -0
  297. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fixtures/ruby_reads.json +0 -0
  298. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/fixtures/symbol_reads.json +0 -0
  299. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/__init__.py +0 -0
  300. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/fixture_scripts.py +0 -0
  301. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/reader.py +0 -0
  302. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/runner.py +0 -0
  303. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/sdk_driver.py +0 -0
  304. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/stock_driver.py +0 -0
  305. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/live/test_live_runner.py +0 -0
  306. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/README.md +0 -0
  307. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/__init__.py +0 -0
  308. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/baseline_gaps.json +0 -0
  309. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/compare.py +0 -0
  310. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/intentional_deviations.json +0 -0
  311. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/introspect.py +0 -0
  312. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  313. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/reports/gap_report.json +0 -0
  314. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/run_parity.py +0 -0
  315. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/snapshots/athena_latest.json +0 -0
  316. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  317. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/parity/test_parity_gap.py +0 -0
  318. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_add_section.py +0 -0
  319. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_add_section_extract_items.py +0 -0
  320. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_alignment_values.py +0 -0
  321. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_athena_extension_creates_session_open.py +0 -0
  322. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_athena_extensions_contract.py +0 -0
  323. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_athena_extensions_registry.py +0 -0
  324. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_batch_chunking.py +0 -0
  325. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_batching_perf.py +0 -0
  326. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_battery_cases.py +0 -0
  327. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_block_not_found_error.py +0 -0
  328. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_buffer.py +0 -0
  329. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  330. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_add_table_not_supported.py +0 -0
  331. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_borders_spec.py +0 -0
  332. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_fastpath_runs.py +0 -0
  333. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  334. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  335. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_inner_format_stash.py +0 -0
  336. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_inner_run_format_stash.py +0 -0
  337. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_inner_run_guard.py +0 -0
  338. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_merge.py +0 -0
  339. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_nested_tables.py +0 -0
  340. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_paragraphs_listed.py +0 -0
  341. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_text_plain_fastpath.py +0 -0
  342. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_cell_text_replace_semantics.py +0 -0
  343. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_citations.py +0 -0
  344. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_collapsed_range_format.py +0 -0
  345. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_color_format_theme.py +0 -0
  346. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_command_dataclasses.py +0 -0
  347. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_commands.py +0 -0
  348. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_comment_paragraphs.py +0 -0
  349. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_content_control_value.py +0 -0
  350. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_document_asset_id_property.py +0 -0
  351. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_document_clear.py +0 -0
  352. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_document_create.py +0 -0
  353. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_document_create_from_template.py +0 -0
  354. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_document_factory_validation.py +0 -0
  355. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_document_settings_session_open.py +0 -0
  356. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_docx_exec_lab.py +0 -0
  357. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_docx_exec_lab_server.py +0 -0
  358. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_drawing_image.py +0 -0
  359. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
  360. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_empty_hyperlinks.py +0 -0
  361. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_enum_parity.py +0 -0
  362. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_execution_scope.py +0 -0
  363. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_export_docx_clean.py +0 -0
  364. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_export_rescue_anchors.py +0 -0
  365. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_field_reads_python_docx_parity.py +0 -0
  366. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_field_refresh.py +0 -0
  367. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_field_runs.py +0 -0
  368. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_find_replace_session_open.py +0 -0
  369. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_flushed_write_failures.py +0 -0
  370. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_http_transport.py +0 -0
  371. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_hyperlink_coalescing.py +0 -0
  372. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_image_url_data_uri.py +0 -0
  373. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_inline_page_break.py +0 -0
  374. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_inline_shape_alt_text.py +0 -0
  375. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_inline_shape_size.py +0 -0
  376. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_insert_deferred.py +0 -0
  377. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_iter_inner_content.py +0 -0
  378. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_latent_style_writes.py +0 -0
  379. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_line_clear_break.py +0 -0
  380. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_list_styles.py +0 -0
  381. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_merged_cell_identity.py +0 -0
  382. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_merged_cell_secondary_slot.py +0 -0
  383. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_merged_cells.py +0 -0
  384. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_missing_modules.py +0 -0
  385. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_nested_table_refused.py +0 -0
  386. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
  387. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_oxml_shim.py +0 -0
  388. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_page_break.py +0 -0
  389. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_paragraph_delete.py +0 -0
  390. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_paragraph_indent_reads.py +0 -0
  391. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_paragraph_runs_hyperlinks.py +0 -0
  392. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_paragraph_text_empty_run.py +0 -0
  393. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_paragraph_text_len_cache.py +0 -0
  394. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_parity_misc.py +0 -0
  395. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_parity_round2.py +0 -0
  396. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_partial_failure_cascade.py +0 -0
  397. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_pdf_export_and_page_renders.py +0 -0
  398. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_phase_a_behavior.py +0 -0
  399. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_phase_c_tables.py +0 -0
  400. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_positional_cell_id.py +0 -0
  401. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_postproc_cell_format_rewrite.py +0 -0
  402. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  403. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_postproc_ref_restore.py +0 -0
  404. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_pr19766_review_fixes.py +0 -0
  405. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_proxy_equality.py +0 -0
  406. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_ptc.py +0 -0
  407. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_python_docx_api_parity.py +0 -0
  408. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_read_run_ranges.py +0 -0
  409. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_rendered_page_breaks.py +0 -0
  410. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_repeated_node_read.py +0 -0
  411. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_restart_numbering.py +0 -0
  412. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_revisions.py +0 -0
  413. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_round_trip_smoke_script.py +0 -0
  414. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_ruby_reads_python_docx_parity.py +0 -0
  415. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_add_picture_anchor.py +0 -0
  416. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_edges.py +0 -0
  417. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_formatting_wire.py +0 -0
  418. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_identity.py +0 -0
  419. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_later_runs.py +0 -0
  420. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_mark_inheritance.py +0 -0
  421. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_page_number_blocks.py +0 -0
  422. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_table_style_objects.py +0 -0
  423. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_text_python_docx.py +0 -0
  424. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_text_refreshes_paragraph.py +0 -0
  425. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_run_unmodeled_toggles.py +0 -0
  426. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_sdk_reads_served.py +0 -0
  427. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_section_read_lengths.py +0 -0
  428. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  429. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_add_picture.py +0 -0
  430. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_add_run.py +0 -0
  431. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  432. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
  433. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_comments_get.py +0 -0
  434. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_document_audit.py +0 -0
  435. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_document_element.py +0 -0
  436. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_enum_section.py +0 -0
  437. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_font_audit.py +0 -0
  438. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_header_footer.py +0 -0
  439. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_hyperlink.py +0 -0
  440. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_inline_shape.py +0 -0
  441. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  442. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_misc.py +0 -0
  443. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
  444. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_paragraph_style.py +0 -0
  445. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  446. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_parfmt.py +0 -0
  447. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_row_col_cell.py +0 -0
  448. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_run_add_break.py +0 -0
  449. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
  450. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_run_style.py +0 -0
  451. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_run_style_strict.py +0 -0
  452. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_run_text.py +0 -0
  453. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_run_underline.py +0 -0
  454. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_section_audit.py +0 -0
  455. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_section_dimensions.py +0 -0
  456. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_section_onoff.py +0 -0
  457. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_settings.py +0 -0
  458. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_shared_audit.py +0 -0
  459. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_style.py +0 -0
  460. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_styles.py +0 -0
  461. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_table_audit.py +0 -0
  462. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_table_cell.py +0 -0
  463. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_table_dimensions.py +0 -0
  464. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_silent_stub_table_layout.py +0 -0
  465. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_smoke_integration.py +0 -0
  466. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_acceptance.py +0 -0
  467. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_delete.py +0 -0
  468. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_font.py +0 -0
  469. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_formatting_writes.py +0 -0
  470. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_metadata_writes.py +0 -0
  471. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_names.py +0 -0
  472. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_setters_contract.py +0 -0
  473. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_tab_stops.py +0 -0
  474. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_style_tab_stops_read.py +0 -0
  475. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_symbol_reads_python_docx_parity.py +0 -0
  476. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_tab_stop_writes.py +0 -0
  477. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_add_row_grid_row.py +0 -0
  478. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_anchors.py +0 -0
  479. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_clears.py +0 -0
  480. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_direction.py +0 -0
  481. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_read_reuse.py +0 -0
  482. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_set_cell_perf.py +0 -0
  483. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_table_style_id_resolution.py +0 -0
  484. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_temporarily_unavailable.py +0 -0
  485. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_text_control_characters.py +0 -0
  486. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_tracked_revisions_offsets.py +0 -0
  487. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_unmapped_alignment_reads.py +0 -0
  488. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_uv_lock_version.py +0 -0
  489. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_validate_find_replace_asset_script.py +0 -0
  490. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_xml_attr_guard.py +0 -0
  491. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_xml_incompatible_text.py +0 -0
  492. {athena_python_docx-0.38.0 → athena_python_docx-0.39.0}/tests/test_zod_wire_contract.py +0 -0
@@ -136,12 +136,24 @@ pinned by focused tests and documented in
136
136
  r.add_picture(img)` writes the bold `w:rPr` beside the `w:drawing`. An older
137
137
  docx-studio puts the picture in a run of its own (`tests/test_drawing_image.py`,
138
138
  battery `ab_probe/picture_runs.py`).
139
- - **A run holding only a page or column break yields `""` from
140
- `Run.iter_inner_content()`,** as python-docx reads a `w:br` of type `page`
141
- or `column` as empty text; an empty run (a comment reference's) yields
142
- nothing. docx-studio's read marks such a run with `break`, and
143
- `Run.add_break` marks the run it adds one to. Against an older docx-studio,
144
- which sends no `break`, a re-read run yields nothing.
139
+ - **A run holding only a page or column break, or an empty text element
140
+ (`<w:t/>`), yields `""` from `Run.iter_inner_content()`,** as python-docx
141
+ reads a `w:br` of type `page` or `column`, and a `w:t` with no text, as
142
+ empty text; an empty run (a comment reference's) yields nothing.
143
+ docx-studio's read marks such a run with `break` (or `emptyText`), and
144
+ `Run.add_break` marks the run it adds one to; a text write to the run
145
+ drops `emptyText`. Against an older docx-studio, which sends neither, a
146
+ re-read run yields nothing.
147
+ - **`doc.inline_shapes` lists a picture in a text box twice, as python-docx
148
+ does.** Word writes a text box in `mc:AlternateContent` as a DrawingML
149
+ shape and as its VML copy, each with the box's text, and python-docx's
150
+ `//w:p/w:r/w:drawing/wp:inline` finds the picture in both. The SDK asks
151
+ `ImagesList` for the second (`fallbackCopies`): a row under no id
152
+ (`fallbackCopy`) that reads its size, type and alt text as the export
153
+ writes the copy. A change of its size, alt text, title or decorative flag
154
+ warns (`DocxUnsupportedCommandWarning`) and sends nothing, as docx-studio
155
+ writes the copy from the box (`tests/test_inline_shape_type.py`). An older
156
+ docx-studio lists the picture once.
145
157
  - **`Styles.latent_styles`** (`docx.styles.latent.LatentStyles`) reads
146
158
  the document's `<w:latentStyles>` (defaults and each `w:lsdException`)
147
159
  from docx-studio's `Info` (`includeStyles` → `latentStyles`), as python-docx
@@ -1019,8 +1031,17 @@ architecture or a DOCX Studio constraint:
1019
1031
  the UI name (`"Heading 1"`), `.style_id` the id (`"Heading1"`), read from
1020
1032
  the document's style table (docx-studio `Info` with `includeStyles`,
1021
1033
  fetched once per session in `docx/styles/_table.py`). A style set by name
1022
- or id is sent as the document's id, and an unstyled paragraph reads as the
1023
- default paragraph style. `paragraph.style = …` raises `KeyError` for a
1034
+ or id is sent as the document's id. A style read resolves as python-docx's
1035
+ `Styles.get_by_id`: the document's first style of the stored id when it is
1036
+ of the type read; else, for an unstyled paragraph, run or table or one
1037
+ naming a style of another type, the type's default style (the last the
1038
+ document flags `w:default`), and None in a document that flags none, as
1039
+ generated documents often do (`styles.default(...)` is None there too).
1040
+ Each `w:style` is a style of its own, a second definition of an id (and
1041
+ one with no `w:name`, whose name is None) included, reading its own name,
1042
+ flags and formatting; a write to it changes the first definition of its id,
1043
+ which docx-studio addresses by the id, where python-docx changes the one it
1044
+ wraps. `paragraph.style = …` raises `KeyError` for a
1024
1045
  name the document defines no style for, like python-docx — except the
1025
1046
  Word built-ins docx-studio holds a definition of
1026
1047
  (`BUILTIN_PARAGRAPH_STYLE_NAMES`: `"Heading 4"`, `"List Bullet"`,
@@ -1028,7 +1049,12 @@ architecture or a DOCX Studio constraint:
1028
1049
  `styles.xml` until used. Those are sent by their Word id; the paragraph
1029
1050
  holds `w:pStyle` alone, the editor paints it from that definition and
1030
1051
  the export adds the definition (with a list of the document's own for a
1031
- numbered list style), as Word does when the style is applied. Heading 1–9,
1052
+ numbered list style), as Word does when the style is applied, so the
1053
+ paragraph reads back as that built-in. A header or footer part a read adds
1054
+ (python-docx's `default-header.xml`) names `Header` (`Footer`) only where
1055
+ the document defines it: elsewhere python-docx's reference resolves to the
1056
+ default paragraph style and adds no definition, so the SDK's paragraph
1057
+ names no style and the export adds none. Heading 1–9,
1032
1058
  Title, Subtitle, Quote, Intense Quote, List Paragraph, No Spacing and
1033
1059
  Caption are defined by hand to current Word's definitions
1034
1060
  (`packages/core/src/prosemirror/styles/latentBuiltInStyles.ts`); the
@@ -1104,13 +1130,12 @@ architecture or a DOCX Studio constraint:
1104
1130
  wins in the save that writes it (a later save in the same batch stamps
1105
1131
  again). Every read asks docx-studio, which saves the batch's edits before it
1106
1132
  answers, so a read sees the stamp, and a collaborator's save. A package
1107
- without `docProps/core.xml` reads
1108
- every property as missing, where python-docx adds its own default part
1109
- (title "Word Document", last modified by "python-docx").
1110
-
1111
- - **`Comment.comment_id` returns `str`, not `int`.** DOCX Studio uses
1112
- non-numeric entity ids (`"c-42"`), so the upstream `int` contract
1113
- can't be honored. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
1133
+ without `docProps/core.xml` reads as the default part python-docx adds to
1134
+ it on first access (title "Word Document", last modified by
1135
+ "python-docx", revision 1, and as `modified` the time of the session's
1136
+ first read, which later reads keep, as python-docx keeps its part's;
1137
+ docx-studio's `Info` marks it `corePropertiesDefault`), and a property set
1138
+ there is written into that part, as python-docx writes it.
1114
1139
 
1115
1140
  - **`add_comment` without an `author` stores the session's name, not
1116
1141
  `""`.** `Document.add_comment` / `Comments.add_comment` send `author`
@@ -1166,8 +1191,12 @@ architecture or a DOCX Studio constraint:
1166
1191
  the base text keeps its room in the text-address space (`ruby` spans on the
1167
1192
  read's run; `tests/test_ruby_reads_python_docx_parity.py`). That holds while
1168
1193
  the paragraph's runs are as its records hold them, in the body, a table cell,
1169
- a header, a footer or a comment; a paragraph with a link or a tracked change
1170
- reads its runs from their marks, the base text included. A write to the run
1194
+ a header, a footer or a comment; a body or cell paragraph with a link or an
1195
+ inline content control reads its runs from the records its import keeps for
1196
+ the reads alone (`_readRunRecords`) until an edit changes them, and a
1197
+ paragraph with a tracked change, an edited one with a link, and a header's,
1198
+ footer's or comment's with a link read their runs from their marks, the base
1199
+ text included. A write to the run
1171
1200
  (its text, an append, its formatting) makes the base text ordinary text,
1172
1201
  which then reads as text: docx-studio keeps no guide through an edit, where
1173
1202
  upstream keeps the `w:ruby` through all but a text write.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: athena-python-docx
3
- Version: 0.38.0
3
+ Version: 0.39.0
4
4
  Summary: Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack
5
5
  Project-URL: Homepage, https://athenaintelligence.ai
6
6
  Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
@@ -6,7 +6,7 @@ See CLAUDE.md for the API parity contract.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.38.0"
9
+ __version__ = "0.39.0"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import discard_all, flush_all
@@ -797,6 +797,11 @@ class ImagesList(Command):
797
797
  # ``False`` leaves out each picture's ``src`` (a data URI can be MBs); an
798
798
  # older docx-studio ignores the field and sends ``src``.
799
799
  include_src: bool | None = None
800
+ # ``True`` also lists the copy of each picture in a text box that the
801
+ # box's VML fallback holds (a row with ``fallbackCopy``, under no id), as
802
+ # python-docx's ``inline_shapes`` lists it; an older docx-studio ignores
803
+ # the field and lists none.
804
+ fallback_copies: bool | None = None
800
805
 
801
806
 
802
807
  @dataclass
@@ -289,9 +289,21 @@ class Comment(BlockItemContainer):
289
289
 
290
290
  # ---- identity / metadata ----
291
291
  @property
292
- def comment_id(self) -> str:
293
- cid = self._info.get("id") or self._info.get("commentId") or ""
294
- return str(cid)
292
+ def _id(self) -> str:
293
+ """The id docx-studio addresses the comment by: its ``w:id``, as text."""
294
+ cid = self._info.get("id")
295
+ if cid is None or cid == "":
296
+ cid = self._info.get("commentId")
297
+ return "" if cid is None else str(cid)
298
+
299
+ @property
300
+ def comment_id(self) -> int:
301
+ """The comment's ``w:id``, an ``int`` as python-docx's
302
+ ``Comment.comment_id`` reads it (``ST_DecimalNumber``). docx-studio
303
+ reports it as text; an id that is not a number (no Word comment has
304
+ one) is returned as that text."""
305
+ cid = self._id
306
+ return int(cid) if re.fullmatch(r"-?\d+", cid) else cid # type: ignore[return-value]
295
307
 
296
308
  @property
297
309
  def author(self) -> str:
@@ -330,7 +342,7 @@ class Comment(BlockItemContainer):
330
342
  with when docx-studio does not answer, or holds no record of it (a
331
343
  comment range listed without one, with empty text)."""
332
344
  try:
333
- result: object = run_sync(self._session.doc.comments.get({"id": self.comment_id}))
345
+ result: object = run_sync(self._session.doc.comments.get({"id": self._id}))
334
346
  except NotFoundError as exc:
335
347
  if writes_unapplied(exc):
336
348
  raise
@@ -344,7 +356,7 @@ class Comment(BlockItemContainer):
344
356
  def text(self, value: str) -> None:
345
357
  from docx.commands import CommentsPatch
346
358
 
347
- run_sync(self._session.doc.comments.patch({"id": self.comment_id, "text": value}))
359
+ run_sync(self._session.doc.comments.patch({"id": self._id, "text": value}))
348
360
  self._info["text"] = value
349
361
  # CommentsPatch is a Command type — referenced for clarity / parity
350
362
  # with the bus dispatch path.
@@ -360,7 +372,7 @@ class Comment(BlockItemContainer):
360
372
  raw: object = run_sync(
361
373
  self._session.doc.blocks.list(
362
374
  {
363
- "in": {"kind": "story", "storyType": "comment", "commentId": self.comment_id},
375
+ "in": {"kind": "story", "storyType": "comment", "commentId": self._id},
364
376
  "nodeTypes": ["paragraph"],
365
377
  "includeText": True,
366
378
  "includeRuns": True,
@@ -437,7 +449,7 @@ class Comment(BlockItemContainer):
437
449
  # unlike python-docx's in-memory tree).
438
450
  paragraph_style_id(self._session, style)
439
451
  result: object = run_sync(
440
- self._session.doc.comments.paragraph_append({"id": self.comment_id, "text": text}),
452
+ self._session.doc.comments.paragraph_append({"id": self._id, "text": text}),
441
453
  )
442
454
  node_id = result.get("nodeId") if isinstance(result, dict) else None
443
455
  if not isinstance(node_id, str) or not node_id:
@@ -17,7 +17,11 @@ whatever its ``tzinfo``), ``revision`` only as a positive ``int``.
17
17
 
18
18
  docx-studio stamps ``modified`` with the time of a save that changes the
19
19
  package, a core property included, as Word does; a ``modified`` the script
20
- sets is kept instead. Every read asks docx-studio, so it sees that stamp, an
20
+ sets is kept instead. A package without ``docProps/core.xml`` reads as the
21
+ default part python-docx adds to it on first access (title "Word Document",
22
+ last modified by "python-docx", revision 1), whose ``modified`` is the time
23
+ of the session's first read, kept for later reads as python-docx keeps its
24
+ part's, until a write gives the document a part of its own. Every read asks docx-studio, so it sees that stamp, an
21
25
  edit another collaborator saved, and a write queued before it (sent in the
22
26
  same batch, saved before the read answers).
23
27
 
@@ -93,23 +97,30 @@ class _Record:
93
97
  writes: bool
94
98
  #: What this process set, which is all there is when ``writes`` is False.
95
99
  texts: dict[str, str | None]
100
+ #: For a package without ``docProps/core.xml``: the ``modified`` of
101
+ #: python-docx's default part as this session first read it. python-docx
102
+ #: adds that part once, on first access, and keeps its time; docx-studio
103
+ #: reports it with each read's time (``corePropertiesDefault``).
104
+ default_modified: str | None = None
96
105
 
97
106
 
98
107
  _records: "weakref.WeakKeyDictionary[Any, _Record]" = weakref.WeakKeyDictionary()
99
108
 
100
109
 
101
- def _served_texts(session: Any) -> dict[str, str | None] | None:
110
+ def _served_texts(session: Any) -> tuple[dict[str, str | None] | None, bool]:
102
111
  """The texts docx-studio reports (flushing the edits queued before), or
103
- None from one that reports none."""
112
+ None from one that reports none; and whether they are python-docx's
113
+ default part, which a package without the part reads as
114
+ (``corePropertiesDefault``)."""
104
115
  info: object = run_sync(session.doc.info({"includeCoreProperties": True}))
105
116
  served = info.get("coreProperties") if isinstance(info, dict) else None
106
117
  if not isinstance(served, dict):
107
- return None
118
+ return None, False
108
119
  texts: dict[str, str | None] = {}
109
120
  for name, wire in _WIRE_NAMES.items():
110
121
  text = served.get(wire)
111
122
  texts[name] = text if isinstance(text, str) else None
112
- return texts
123
+ return texts, isinstance(info, dict) and info.get("corePropertiesDefault") is True
113
124
 
114
125
 
115
126
  def _known_record(session: Any) -> _Record | None:
@@ -134,14 +145,22 @@ def _texts(session: Any) -> dict[str, str | None]:
134
145
  record = _known_record(session)
135
146
  if record is not None and not record.writes:
136
147
  return record.texts
137
- served = _served_texts(session)
148
+ served, default_part = _served_texts(session)
138
149
  if record is None:
139
150
  record = _remember(session, served)
140
- return served if served is not None else record.texts
151
+ if served is None:
152
+ return record.texts
153
+ if not default_part:
154
+ record.default_modified = None
155
+ return served
156
+ # python-docx's default part keeps the time of its first access.
157
+ if record.default_modified is None:
158
+ record.default_modified = served["modified"]
159
+ return {**served, "modified": record.default_modified}
141
160
 
142
161
 
143
162
  def _write(session: Any, name: str, text: str) -> None:
144
- record = _known_record(session) or _remember(session, _served_texts(session))
163
+ record = _known_record(session) or _remember(session, _served_texts(session)[0])
145
164
  if not record.writes:
146
165
  record.texts[name] = text
147
166
  warnings.warn(
@@ -96,6 +96,21 @@ def _extract_part_ref_id(response: object) -> str:
96
96
  return ""
97
97
 
98
98
 
99
+ def _resolves_as_paragraph_style(session: object, style_id: str) -> bool:
100
+ """Whether a ``w:pStyle`` of ``style_id`` names a style of the session's
101
+ document: its first style of that id is a paragraph style (python-docx's
102
+ ``Styles.get_by_id``). Without a style table (an older docx-studio) the
103
+ reference is written as python-docx writes it."""
104
+ from docx.enum.style import WD_STYLE_TYPE
105
+ from docx.styles._table import first_of_id, style_table
106
+
107
+ table = style_table(session)
108
+ if table is None:
109
+ return True
110
+ record = first_of_id(table, style_id)
111
+ return record is not None and record.type == WD_STYLE_TYPE.PARAGRAPH
112
+
113
+
99
114
  def _remember_header_footer_paragraph(session: object, node_id: str) -> None:
100
115
  """Note a header/footer paragraph id on the session's HTTP client, so a
101
116
  ``block not found`` on it gets the header/footer hint, not the
@@ -893,15 +908,24 @@ class _HeaderFooter(BlockItemContainer):
893
908
  in the Header (or Footer) style. docx-studio stores an empty part with
894
909
  one empty paragraph (a part needs a block), which gets the style; a
895
910
  part that holds none gets the paragraph. A server that does not list
896
- header/footer stories keeps its part as it stores it."""
911
+ header/footer stories keeps its part as it stores it.
912
+
913
+ python-docx's ``default-header.xml`` names the style by its id,
914
+ ``Header`` (``Footer``), whatever the document's styles are, and adds
915
+ no definition of it: in a document whose ``styles.xml`` has no
916
+ paragraph style of that id, the paragraph reads as the default
917
+ paragraph style (None without one). The paragraph then names no style,
918
+ which reads the same, and gives the export no reference to add Word's
919
+ definition for (``addReferencedBuiltInStyles``), so its ``styles.xml``
920
+ stays the document's, as python-docx's does."""
897
921
  listing = self._listing({"kind": "story", "storyType": "headerFooterPart", "refId": ref_id})
898
922
  if listing is None:
899
923
  return
900
924
  paragraphs = self._paragraphs_of(listing)
901
925
  first = paragraphs[0] if paragraphs else self._append_paragraph(ref_id, "")
902
- # python-docx writes this style id whatever the document's styles are;
903
- # docx-studio resolves it against them.
904
- first._set_style_id("Header" if self._kind == "header" else "Footer")
926
+ style_id = "Header" if self._kind == "header" else "Footer"
927
+ if _resolves_as_paragraph_style(self._section._session, style_id):
928
+ first._set_style_id(style_id)
905
929
 
906
930
  def _append_paragraph(self, ref_id: str, text: str) -> "Paragraph":
907
931
  """Append a paragraph holding ``text`` to the part ``ref_id``."""
@@ -113,15 +113,23 @@ class InlineShape:
113
113
  """``True`` (with a warning) for a shape docx-studio does not change
114
114
  through ``InlineShape``.
115
115
 
116
- docx-studio writes a SmartArt drawing back as its source has it, and
117
- holds a text box (a row with ``textBox``) as a text box, so a change of
118
- its size, alt text, title or decorative flag is not sent and the shape
119
- keeps reading what it has, where python-docx would change it.
116
+ docx-studio writes a SmartArt drawing back as its source has it, holds
117
+ a text box (a row with ``textBox``) as a text box, and writes the copy
118
+ of a text box's picture that the box's VML fallback holds (a row with
119
+ ``fallbackCopy``, which python-docx lists beside the picture itself)
120
+ from the box, so a change of its size, alt text, title or decorative
121
+ flag is not sent and the shape keeps reading what it has, where
122
+ python-docx would change it.
120
123
  """
121
124
  if self._info.get("kind") == "smartArt":
122
125
  held = "a SmartArt drawing, which docx-studio writes back as its source has it"
123
126
  elif self._info.get("textBox") is True:
124
127
  held = "a text box, which docx-studio holds as a text box"
128
+ elif self._info.get("fallbackCopy") is True:
129
+ held = (
130
+ "the copy of a text box's picture that its VML fallback holds,"
131
+ " which docx-studio writes from the box"
132
+ )
125
133
  else:
126
134
  return False
127
135
  from docx.errors import DocxUnsupportedCommandWarning
@@ -392,9 +400,15 @@ class InlineShapes:
392
400
  def __init__(self, *, session: "Session") -> None:
393
401
  self._session: "Session" = session
394
402
 
395
- def _rows(self, *, include_src: bool = True) -> list[dict]:
396
- """Every picture ``ImagesList`` names, a floating one too."""
397
- params: dict = {} if include_src else {"includeSrc": False}
403
+ def _rows(self, *, include_src: bool = True, fallback_copies: bool = False) -> list[dict]:
404
+ """Every picture ``ImagesList`` names, a floating one too, and with
405
+ ``fallback_copies`` the copy of a text box's picture that the box's
406
+ VML fallback holds, which python-docx lists as an inline shape too."""
407
+ params: dict = {}
408
+ if not include_src:
409
+ params["includeSrc"] = False
410
+ if fallback_copies:
411
+ params["fallbackCopies"] = True
398
412
  info: object = run_sync(self._session.doc.images.list(params))
399
413
  if isinstance(info, dict):
400
414
  items: object = info.get("items") or info.get("images") or []
@@ -408,7 +422,8 @@ class InlineShapes:
408
422
  # python-docx lists the pictures in the line (``wp:inline``) only; a
409
423
  # floating one (``wp:anchor``) is not an inline shape. A docx-studio
410
424
  # that does not say which a picture is gives every one.
411
- return [row for row in self._rows(include_src=include_src) if row.get("inline") is not False]
425
+ rows = self._rows(include_src=include_src, fallback_copies=True)
426
+ return [row for row in rows if row.get("inline") is not False]
412
427
 
413
428
  def __len__(self) -> int:
414
429
  return len(self._items())