athena-python-docx 0.11.1__tar.gz → 0.11.3__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 (339) hide show
  1. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/CLAUDE.md +12 -0
  2. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/PKG-INFO +1 -1
  3. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/__init__.py +1 -1
  4. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/errors.py +22 -0
  5. athena_python_docx-0.11.3/docx/oxml/__init__.py +216 -0
  6. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/table.py +32 -25
  7. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/pyproject.toml +1 -1
  8. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/complex_cases.py +15 -37
  9. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/extreme_cases.py +3 -12
  10. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/real_world_cases.py +4 -13
  11. athena_python_docx-0.11.3/tests/test_cell_add_table_not_supported.py +79 -0
  12. athena_python_docx-0.11.3/tests/test_oxml_shim.py +174 -0
  13. athena_python_docx-0.11.1/docx/oxml/__init__.py +0 -148
  14. athena_python_docx-0.11.1/tests/fidelity/op_snapshots/103_cell_tables_enumeration.json +0 -14
  15. athena_python_docx-0.11.1/tests/fidelity/op_snapshots/23_nested_table.json +0 -9
  16. athena_python_docx-0.11.1/tests/fidelity/op_snapshots/51_nested_tables_deep.json +0 -14
  17. athena_python_docx-0.11.1/tests/fidelity/op_snapshots/ex01_five_levels_deep_tables.json +0 -24
  18. athena_python_docx-0.11.1/tests/fidelity/op_snapshots/rw14_nested_cell_table.json +0 -10
  19. athena_python_docx-0.11.1/tests/test_oxml_shim.py +0 -123
  20. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/.gitignore +0 -0
  21. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/README.md +0 -0
  22. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_athena_extension.py +0 -0
  23. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_batching.py +0 -0
  24. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_buffer.py +0 -0
  25. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_http.py +0 -0
  26. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_http_doc.py +0 -0
  27. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_image_utils.py +0 -0
  28. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_ptc.py +0 -0
  29. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/_table_styles.py +0 -0
  30. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/api.py +0 -0
  31. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/bookmarks.py +0 -0
  32. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/charts.py +0 -0
  33. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/client.py +0 -0
  34. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/commands.py +0 -0
  35. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/comments.py +0 -0
  36. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/document.py +0 -0
  37. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/enum/__init__.py +0 -0
  38. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/enum/section.py +0 -0
  39. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/enum/style.py +0 -0
  40. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/enum/table.py +0 -0
  41. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/enum/text.py +0 -0
  42. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/exceptions.py +0 -0
  43. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/fields.py +0 -0
  44. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/footnotes.py +0 -0
  45. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/math.py +0 -0
  46. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/opc/__init__.py +0 -0
  47. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/opc/coreprops.py +0 -0
  48. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/revisions.py +0 -0
  49. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/sdt.py +0 -0
  50. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/section.py +0 -0
  51. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/settings.py +0 -0
  52. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/shape.py +0 -0
  53. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/shared.py +0 -0
  54. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/styles/__init__.py +0 -0
  55. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/styles/style.py +0 -0
  56. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/styles/styles.py +0 -0
  57. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/__init__.py +0 -0
  58. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/font.py +0 -0
  59. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/hyperlink.py +0 -0
  60. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/pagebreak.py +0 -0
  61. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/paragraph.py +0 -0
  62. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/parfmt.py +0 -0
  63. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/run.py +0 -0
  64. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/text/tabstops.py +0 -0
  65. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/toc.py +0 -0
  66. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/docx/typing.py +0 -0
  67. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/scripts/publish.sh +0 -0
  68. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/scripts/release.sh +0 -0
  69. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/scripts/round_trip_smoke.py +0 -0
  70. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/scripts/smoke_test_block_not_found.py +0 -0
  71. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/__init__.py +0 -0
  72. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/conftest.py +0 -0
  73. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/METHODOLOGY.md +0 -0
  74. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/README.md +0 -0
  75. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/__init__.py +0 -0
  76. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/ab_probe_cases.py +0 -0
  77. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/ab_probe_runner.py +0 -0
  78. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/auto_gen_cases.py +0 -0
  79. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/binary_round_trip.py +0 -0
  80. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/cases.py +0 -0
  81. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/coverage_report.py +0 -0
  82. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/extract.py +0 -0
  83. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/fake_session.py +0 -0
  84. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/firm_templates/README.md +0 -0
  85. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/firm_templates/__init__.py +0 -0
  86. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/firm_templates/_runner.py +0 -0
  87. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/firm_templates/extractor.py +0 -0
  88. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  89. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  90. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/local_runner.py +0 -0
  91. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/mega_cases.py +0 -0
  92. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshot.py +0 -0
  93. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  94. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  95. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  96. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  97. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  98. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  99. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  100. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  101. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  102. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  103. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  104. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  105. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  106. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  107. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  108. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  109. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  110. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  111. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  112. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  113. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  114. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  115. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  116. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  117. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  118. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  119. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  120. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  121. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  122. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  123. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  124. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  125. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  126. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  127. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  128. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  129. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  130. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  131. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  132. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  133. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  134. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  135. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  136. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  137. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  138. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  139. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  140. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  141. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  142. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  143. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  144. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  145. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  146. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  147. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  148. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  149. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  150. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  151. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  152. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  153. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  154. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  155. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  156. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  157. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  158. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  159. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  160. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  161. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  162. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  163. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  164. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  165. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  166. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  167. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  168. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  169. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  170. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  171. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  172. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  173. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  174. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  175. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  176. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  177. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  178. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  179. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  180. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  181. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  182. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  183. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  184. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  185. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  186. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  187. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  188. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  189. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  190. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  191. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  192. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  193. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  194. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  195. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  196. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  197. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  198. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  199. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  200. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  201. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  202. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  203. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  204. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  205. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  206. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  207. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  208. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  209. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  210. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  211. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  212. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  213. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  214. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  215. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  216. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  217. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  218. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  219. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  220. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  221. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  222. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  223. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  224. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  225. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  226. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  227. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  228. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  229. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  230. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  231. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  232. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  233. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  234. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  235. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  236. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  237. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  238. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  239. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  240. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/ours_spec.json +0 -0
  241. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/parity_crawl.py +0 -0
  242. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/parity_diff.json +0 -0
  243. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/round_trip_tests.py +0 -0
  244. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/runner.py +0 -0
  245. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/stock_spec.json +0 -0
  246. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/fidelity/test_e2e_against_staging.py +0 -0
  247. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/README.md +0 -0
  248. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/__init__.py +0 -0
  249. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/baseline_gaps.json +0 -0
  250. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/compare.py +0 -0
  251. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/intentional_deviations.json +0 -0
  252. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/introspect.py +0 -0
  253. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  254. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/reports/gap_report.json +0 -0
  255. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/run_parity.py +0 -0
  256. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/snapshots/athena_latest.json +0 -0
  257. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  258. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/parity/test_parity_gap.py +0 -0
  259. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_athena_extensions_contract.py +0 -0
  260. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_athena_extensions_registry.py +0 -0
  261. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_batching_perf.py +0 -0
  262. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_block_not_found_error.py +0 -0
  263. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_buffer.py +0 -0
  264. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  265. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_cell_text_plain_fastpath.py +0 -0
  266. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_collapsed_range_format.py +0 -0
  267. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_command_dataclasses.py +0 -0
  268. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_commands.py +0 -0
  269. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_comments.py +0 -0
  270. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_document_asset_id_property.py +0 -0
  271. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_document_create.py +0 -0
  272. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_document_create_from_template.py +0 -0
  273. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_document_factory_validation.py +0 -0
  274. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_e2e_partial_failure_cascade.py +0 -0
  275. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_http_transport.py +0 -0
  276. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_hyperlink_coalescing.py +0 -0
  277. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_insert_deferred.py +0 -0
  278. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_iter_inner_content.py +0 -0
  279. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_list_styles.py +0 -0
  280. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_merged_cell_secondary_slot.py +0 -0
  281. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_merged_cells.py +0 -0
  282. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_paragraph_text_len_cache.py +0 -0
  283. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_parity_misc.py +0 -0
  284. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_parity_round2.py +0 -0
  285. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_partial_failure_cascade.py +0 -0
  286. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_phase_a_behavior.py +0 -0
  287. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_phase_b_headers_footers.py +0 -0
  288. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_phase_c_tables.py +0 -0
  289. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_pr19766_review_fixes.py +0 -0
  290. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_ptc.py +0 -0
  291. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_python_docx_api_parity.py +0 -0
  292. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_revisions.py +0 -0
  293. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  294. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_add_picture.py +0 -0
  295. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_add_run.py +0 -0
  296. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  297. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_comments_add_comment.py +0 -0
  298. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_comments_get.py +0 -0
  299. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_document_audit.py +0 -0
  300. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_document_element.py +0 -0
  301. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_enum_section.py +0 -0
  302. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_font_audit.py +0 -0
  303. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_header_footer.py +0 -0
  304. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_hyperlink.py +0 -0
  305. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_inline_shape.py +0 -0
  306. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  307. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_misc.py +0 -0
  308. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_paragraph_strict.py +0 -0
  309. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_paragraph_style.py +0 -0
  310. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  311. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_parfmt.py +0 -0
  312. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_row_col_cell.py +0 -0
  313. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_run_add_break.py +0 -0
  314. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_run_bool_setters.py +0 -0
  315. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_run_style.py +0 -0
  316. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_run_style_strict.py +0 -0
  317. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_run_text.py +0 -0
  318. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_run_underline.py +0 -0
  319. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_section_audit.py +0 -0
  320. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_section_dimensions.py +0 -0
  321. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_section_onoff.py +0 -0
  322. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_settings.py +0 -0
  323. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_shared_audit.py +0 -0
  324. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_style.py +0 -0
  325. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_styles.py +0 -0
  326. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_table_audit.py +0 -0
  327. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_table_cell.py +0 -0
  328. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_table_dimensions.py +0 -0
  329. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_silent_stub_table_layout.py +0 -0
  330. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_smoke_integration.py +0 -0
  331. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_style_acceptance.py +0 -0
  332. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_style_font.py +0 -0
  333. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_style_setters_contract.py +0 -0
  334. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_table_set_cell_perf.py +0 -0
  335. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_table_style_id_resolution.py +0 -0
  336. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_temporarily_unavailable.py +0 -0
  337. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_wire_contract.py +0 -0
  338. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/tests/test_zod_wire_contract.py +0 -0
  339. {athena_python_docx-0.11.1 → athena_python_docx-0.11.3}/uv.lock +0 -0
@@ -39,6 +39,18 @@ These standard python-docx members don't apply to a Superdoc-backed SDK:
39
39
  `Comment.tables` — SuperDoc models a comment as a single text body,
40
40
  not a `BlockItemContainer`. Use `Comment.text` instead. The
41
41
  paragraph/table-bearing surface raises `CommentsNotImplementedError`.
42
+ - **`_Cell.add_table(rows, cols)`** — surface preserved for parity
43
+ (signature matches python-docx, no `width` kwarg) but raises
44
+ :class:`docx.errors.NestedTableNotSupportedError` (subclass of
45
+ `NotImplementedError`) at runtime since 0.11.2. SuperDoc 1.8.1 has
46
+ no anchor or content-fragment shape that places a new table inside
47
+ an existing `tableCell` — `create.table` rejects cell-inner
48
+ paragraph anchors with `INVALID_TARGET`, and the `doc.insert`
49
+ workaround used by `_Cell.add_paragraph` doesn't generalize
50
+ because the apps/api `Insert` schema doesn't yet forward
51
+ `nestingPolicy: {tables: "allow"}` and the SuperDoc table-content
52
+ fragment shape isn't documented. Tracked at
53
+ `docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md` § 13.
42
54
  - **`docx.oxml.*`** — the entire raw-OOXML module tree (``ns.qn``,
43
55
  ``OxmlElement``, ``CT_*`` classes, etc.) is unavailable because the
44
56
  SDK is HTTP-only against a SuperDoc Y.Doc; there is no local lxml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: athena-python-docx
3
- Version: 0.11.1
3
+ Version: 0.11.3
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.11.1"
9
+ __version__ = "0.11.3"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import flush_all
@@ -128,6 +128,28 @@ class LocalSaveTargetNotSupportedError(DocxError, NotImplementedError):
128
128
  """
129
129
 
130
130
 
131
+ class NestedTableNotSupportedError(DocxError, NotImplementedError):
132
+ """Raised when ``_Cell.add_table(...)`` is called.
133
+
134
+ SuperDoc 1.8.1 cannot place a new top-level block inside an
135
+ existing ``tableCell`` — ``create.table`` rejects a cell-inner
136
+ paragraph anchor with ``INVALID_TARGET - Expected paragraph:<id>
137
+ but found tableCell:<id>``, and there is no ``create.table``
138
+ anchor shape ("inside this cell") that addresses cell content
139
+ directly. The ``doc.insert``-based workaround used by
140
+ ``_Cell.text`` / ``_Cell.add_paragraph`` requires a
141
+ ``nestingPolicy: {tables: "allow"}`` flag and a table content
142
+ fragment that aren't yet plumbed through the docx-studio command
143
+ bus, so this entire method is unsupported until upstream
144
+ SuperDoc lands the cell-inner addressing fix tracked in
145
+ ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md`` § 13.
146
+
147
+ Subclasses :class:`NotImplementedError` so a generic
148
+ ``except NotImplementedError`` catches it without importing the
149
+ typed class.
150
+ """
151
+
152
+
131
153
  class ValidationError(DocxError):
132
154
  """Raised when SDK-level validation fails (bad args, out-of-range indices)."""
133
155
 
@@ -0,0 +1,216 @@
1
+ """Stub package — ``docx.oxml`` is intentionally unavailable in
2
+ athena-python-docx.
3
+
4
+ python-docx upstream exposes raw OOXML element classes (``OxmlElement``,
5
+ ``CT_*``, ``qn``, ``nsmap``, …) for advanced users who manipulate
6
+ Word's XML directly. athena-python-docx is backed by a SuperDoc Y.Doc
7
+ + Keryx pipeline, not a local OOXML tree, so there is no XML element
8
+ to manipulate.
9
+
10
+ Before 0.8.0 attempts to ``from docx.oxml.ns import qn`` failed with
11
+ the stdlib's generic ``ModuleNotFoundError: No module named
12
+ 'docx.oxml'`` — agent code had to discover the gap by retry. 0.8.0
13
+ turned this package into a typed stub, but the stub raised
14
+ ``OxmlNotAvailableError`` on attribute access — which is what
15
+ ``from docx.oxml.ns import qn`` triggers, so the import statement
16
+ itself crashed before any line of the agent's actual logic ran. Common
17
+ python-docx convention is to declare ``qn`` / ``OxmlElement`` at the
18
+ top of every script "just in case," and that preamble killed scripts
19
+ that only used the high-level API.
20
+
21
+ As of 0.11.3 the stub is **lazy**: ``from docx.oxml.ns import qn``
22
+ succeeds and returns a sentinel proxy that defers the typed error
23
+ until the symbol is actually called or further-attribute-accessed.
24
+ Scripts that import for parity but never use the symbol now run
25
+ cleanly; scripts that reach for ``qn("w:tcW")`` still get the
26
+ actionable error pointing at the high-level alternative.
27
+
28
+ The gap is documented in ``docx-studio/python-sdk/CLAUDE.md`` § "Intentionally
29
+ omitted" and locked into the parity matrix via
30
+ ``tests/parity/intentional_deviations.json`` (``docx.oxml**``).
31
+ """
32
+
33
+ from __future__ import annotations
34
+
35
+ import sys
36
+ import types
37
+ from typing import Any
38
+
39
+
40
+ class OxmlNotAvailableError(ImportError):
41
+ """Raised when a ``docx.oxml.*`` symbol is actually used.
42
+
43
+ Inherits :class:`ImportError` so callers using
44
+ ``try: from docx.oxml import X / except ImportError`` still match
45
+ after 0.11.3's lazy-stub change (the import itself succeeds, but
46
+ the first call site against the imported name raises this — and
47
+ code that uses ``except ImportError`` around a use-site still
48
+ catches it).
49
+
50
+ Use ``except OxmlNotAvailableError`` to distinguish a "no oxml
51
+ surface" miss from a real import-resolution failure or other
52
+ ``ImportError`` cause.
53
+ """
54
+
55
+
56
+ _MESSAGE: str = (
57
+ "docx.oxml is not available in athena-python-docx — the SuperDoc "
58
+ "backend doesn't expose raw OOXML elements. Use the high-level "
59
+ "python-docx API (Document.add_paragraph, Run.bold, _Cell.text, …) "
60
+ "or the typed command surface in docx.commands for any mutation "
61
+ "the high-level API doesn't cover. "
62
+ "See docx-studio/python-sdk/CLAUDE.md § 'Intentionally omitted' for "
63
+ "the parity rationale."
64
+ )
65
+
66
+
67
+ class _LazyRaisingProxy:
68
+ """Sentinel returned by the ``docx.oxml`` stub for any imported name.
69
+
70
+ Behaves as a callable, an attribute-accessible namespace, and an
71
+ awaitable for the union of common python-docx patterns:
72
+
73
+ * ``from docx.oxml.ns import qn`` → ``qn`` is a _LazyRaisingProxy.
74
+ Just importing it is a no-op. ``qn("w:tcW")`` raises with the
75
+ educated message.
76
+ * ``from docx.oxml import OxmlElement`` → same. ``OxmlElement(...)``
77
+ raises; ``OxmlElement.something`` raises.
78
+ * ``isinstance(x, OxmlElement)`` → raises (we'd rather a noisy
79
+ failure than silently say no, since the typed error tells the
80
+ caller what to do).
81
+
82
+ The proxy carries the full dotted path so the error message points
83
+ at exactly the offending symbol — ``docx.oxml.ns.qn`` rather than a
84
+ generic "docx.oxml".
85
+ """
86
+
87
+ __slots__ = ("_path",)
88
+
89
+ def __init__(self, path: str) -> None:
90
+ # Bypass __setattr__ guard.
91
+ object.__setattr__(self, "_path", path)
92
+
93
+ def _raise(self, suffix: str = "") -> None:
94
+ path = object.__getattribute__(self, "_path")
95
+ target = f"{path}{suffix}" if suffix else path
96
+ raise OxmlNotAvailableError(f"{target} — {_MESSAGE}")
97
+
98
+ def __call__(self, *args: Any, **kwargs: Any) -> Any: # noqa: ANN401
99
+ self._raise()
100
+
101
+ def __getattr__(self, name: str) -> Any: # noqa: ANN401
102
+ if name.startswith("__") and name.endswith("__"):
103
+ raise AttributeError(name)
104
+ self._raise(f".{name}")
105
+
106
+ def __setattr__(self, name: str, value: Any) -> None: # noqa: ANN401
107
+ # Block writes to the proxy so agents that try
108
+ # ``OxmlElement.tag = "..."`` get the typed error rather than a
109
+ # silent attribute set on the sentinel.
110
+ if name == "_path":
111
+ object.__setattr__(self, name, value)
112
+ return
113
+ self._raise(f".{name}")
114
+
115
+ def __repr__(self) -> str:
116
+ path = object.__getattribute__(self, "_path")
117
+ return f"<docx.oxml lazy stub {path!r} — call to raise>"
118
+
119
+
120
+ class _OxmlStubModule(types.ModuleType):
121
+ """ModuleType subclass that returns :class:`_LazyRaisingProxy`
122
+ sentinels for any attribute access.
123
+
124
+ Installed into :data:`sys.modules` at package-init time so
125
+ qualified imports like ``from docx.oxml.ns import qn`` find a real
126
+ module object (avoiding ``ModuleNotFoundError``). The proxy
127
+ returned defers the typed error until the symbol is actually
128
+ invoked, letting top-level python-docx import blocks succeed.
129
+
130
+ No ``__slots__`` — ``types.ModuleType`` itself carries a
131
+ ``__dict__``, so a slots declaration on a subclass is a no-op.
132
+ """
133
+
134
+ def __getattr__(self, name: str) -> Any: # noqa: ANN401
135
+ if name.startswith("__") and name.endswith("__"):
136
+ # Dunder access (e.g. ``__path__`` during submodule import)
137
+ # must fall through to AttributeError so Python's import
138
+ # machinery can probe without triggering our typed error.
139
+ raise AttributeError(name)
140
+ path = self.__name__
141
+ proxy = _LazyRaisingProxy(f"{path}.{name}")
142
+ # Cache so repeated `getattr` returns the same proxy and so
143
+ # `from X import Y` followed by another `from X import Y`
144
+ # gives the same instance.
145
+ object.__setattr__(self, name, proxy)
146
+ return proxy
147
+
148
+
149
+ # Common upstream submodule paths. Listed explicitly rather than wild-
150
+ # carded so adding a new one is a visible diff. Every entry maps to a
151
+ # single sentinel module; no per-submodule state.
152
+ _SUBMODULES: tuple[str, ...] = (
153
+ "ns",
154
+ "parser",
155
+ "element",
156
+ "xmlchemy",
157
+ "exceptions",
158
+ "ooxml",
159
+ "coreprops",
160
+ "document",
161
+ "text",
162
+ "table",
163
+ "comments",
164
+ "header_footer",
165
+ "footnote",
166
+ "endnote",
167
+ "shared",
168
+ "shape",
169
+ "section",
170
+ "settings",
171
+ "styles",
172
+ "numbering",
173
+ )
174
+
175
+
176
+ def _install_stub_submodules() -> None:
177
+ """Pre-populate :data:`sys.modules` with stub entries for every
178
+ well-known ``docx.oxml.*`` submodule.
179
+
180
+ Idempotent — re-running is a no-op for entries already installed
181
+ (covers the rare case of a test that reloads the package).
182
+ """
183
+ for short in _SUBMODULES:
184
+ full = f"docx.oxml.{short}"
185
+ if full in sys.modules:
186
+ continue
187
+ sys.modules[full] = _OxmlStubModule(full)
188
+
189
+
190
+ _install_stub_submodules()
191
+
192
+
193
+ def __getattr__(name: str) -> Any: # noqa: ANN401
194
+ """PEP 562 attribute hook for ``from docx.oxml import X``.
195
+
196
+ Submodule names (handled via :data:`sys.modules` injection in
197
+ :func:`_install_stub_submodules`) and dunder names fall through
198
+ normally. Everything else returns a :class:`_LazyRaisingProxy` so
199
+ the import succeeds and the typed error fires only on actual use.
200
+ """
201
+ if name.startswith("__") and name.endswith("__"):
202
+ raise AttributeError(name)
203
+ if name in _SUBMODULES:
204
+ # Should already be present in sys.modules; defensive fallback
205
+ # so we never leak ModuleNotFoundError if the caller reloaded
206
+ # the package between calls.
207
+ full = f"docx.oxml.{name}"
208
+ mod = sys.modules.get(full)
209
+ if mod is None:
210
+ mod = _OxmlStubModule(full)
211
+ sys.modules[full] = mod
212
+ return mod
213
+ return _LazyRaisingProxy(f"docx.oxml.{name}")
214
+
215
+
216
+ __all__ = ["OxmlNotAvailableError"]
@@ -1430,40 +1430,47 @@ class _Cell:
1430
1430
  def add_table(self, rows: int, cols: int) -> Table:
1431
1431
  """Append a nested table inside the cell.
1432
1432
 
1433
- Mirrors python-docx ``_Cell.add_table(rows, cols) -> Table``.
1433
+ Mirrors python-docx ``_Cell.add_table(rows, cols) -> Table``
1434
+ at the API surface, but raises
1435
+ :class:`docx.errors.NestedTableNotSupportedError` at runtime
1436
+ — SuperDoc 1.8.1 has no addressable shape for "create table
1437
+ inside this cell" (every available anchor either targets a
1438
+ cell-inner paragraph SuperDoc can't resolve, or promotes the
1439
+ new block to the cell's parent row level). The unblock is
1440
+ tracked at ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md`` § 13;
1441
+ the same gap was the proximate cause of the
1442
+ ``_Cell.add_paragraph`` failure fixed in 0.11.1 (#20745), and
1443
+ that fix worked only because ``doc.insert`` accepts a paragraph
1444
+ content fragment against a ``tableCell`` target — there is no
1445
+ analogous table-content fragment path through the current
1446
+ docx-studio command bus.
1447
+
1448
+ ``rows`` and ``cols`` are still validated upfront so callers
1449
+ get the same ``ValidationError`` they would have hit before, in
1450
+ case they were branching on it.
1451
+
1434
1452
  Note that upstream's ``_Cell.add_table`` does not take a
1435
1453
  ``width`` parameter — Word inherits cell-table widths from
1436
1454
  layout. ``Document.add_table`` and ``Section.header.add_table``
1437
1455
  DO take ``width`` because they're block-level.
1438
1456
  """
1439
- from docx.document import _extract_inserted_node_id
1457
+ from docx.errors import NestedTableNotSupportedError
1440
1458
 
1441
1459
  if rows < 1 or cols < 1:
1442
1460
  raise ValidationError(f"rows/cols must be >=1; got {rows}/{cols}")
1443
- # We can target the cell's last paragraph as an anchor.
1444
- ids = self._inner_paragraph_ids()
1445
- if ids:
1446
- anchor = {
1447
- "kind": "after",
1448
- "target": {
1449
- "kind": "block",
1450
- "nodeType": "paragraph",
1451
- "nodeId": ids[-1],
1452
- },
1453
- }
1454
- else:
1455
- anchor = {"kind": "documentEnd"}
1456
- result: object = run_sync(
1457
- self._table._session.doc.create.table(
1458
- {"rows": rows, "columns": cols, "at": anchor},
1459
- ),
1461
+ raise NestedTableNotSupportedError(
1462
+ "_Cell.add_table is unsupported on SuperDoc 1.8.1. The cell "
1463
+ "addressing gap (SUPERDOC_UPSTREAM_REQUESTS.md § 13) means "
1464
+ "no anchor or content-fragment shape currently lets the SDK "
1465
+ "place a new table inside an existing tableCell. Workarounds: "
1466
+ "(a) build the table at document or section level via "
1467
+ "Document.add_table and reference it from cell text, or "
1468
+ "(b) include the nested table in the original template "
1469
+ "document and address its cells directly. This method will "
1470
+ "be reinstated once SuperDoc exposes either recursive "
1471
+ "paragraph-anchor lookup or a cell-scoped create.table "
1472
+ "variant.",
1460
1473
  )
1461
- node_id: str = _extract_inserted_node_id(result, expected_type="table") if isinstance(result, dict) else ""
1462
- if not node_id:
1463
- raise RuntimeError(
1464
- f"Superdoc did not return nodeId for nested table: {result!r}",
1465
- )
1466
- return Table(session=self._table._session, node_id=node_id)
1467
1474
 
1468
1475
  def merge(self, other_cell: "_Cell") -> "_Cell":
1469
1476
  """Return a merged cell created by spanning the rectangular
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-docx"
7
- version = "0.11.1"
7
+ version = "0.11.3"
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"
@@ -319,18 +319,15 @@ CASES: list[ComplexCase] = [
319
319
  expected_ops=("tables.getCells", "create.paragraph"),
320
320
  tags=("level5", "table"),
321
321
  ),
322
- ComplexCase(
323
- name="23_nested_table",
324
- description="Add a nested table inside a cell",
325
- script=(
326
- "outer = doc.add_table(rows=1, cols=1)\n"
327
- "cell = outer.cell(0, 0)\n"
328
- "nested = cell.add_table(rows=2, cols=2)\n"
329
- 'nested.cell(0, 0).text = "nested"'
330
- ),
331
- expected_ops=("create.table",),
332
- tags=("level5", "table", "nested"),
333
- ),
322
+ # Removed in 0.11.2 (#20745 follow-up): ``_Cell.add_table`` now
323
+ # raises ``NestedTableNotSupportedError`` because SuperDoc 1.8.1
324
+ # has no addressable shape for "create new table inside this cell"
325
+ # — every available anchor either targets a cell-inner paragraph
326
+ # SuperDoc can't resolve or promotes the new block to the cell's
327
+ # parent row. Tracked at SUPERDOC_UPSTREAM_REQUESTS.md § 13. Pre-
328
+ # 0.11.2 this case "passed" by silently writing the nested table
329
+ # to documentEnd, which round-tripped in the fake but is wrong in
330
+ # production. See tests/test_cell_add_table_not_supported.py.
334
331
  ComplexCase(
335
332
  name="24_table_add_row_column",
336
333
  description="Add row and column dynamically (python-docx 1.x requires width for add_column)",
@@ -745,17 +742,9 @@ CASES: list[ComplexCase] = [
745
742
  ),
746
743
 
747
744
  # ---------- Level 17: deep nesting + iteration ----------
748
- ComplexCase(
749
- name="51_nested_tables_deep",
750
- description="Table in cell that contains another table in a cell",
751
- script=(
752
- "outer = doc.add_table(rows=1, cols=1)\n"
753
- "mid = outer.cell(0, 0).add_table(rows=1, cols=1)\n"
754
- "inner = mid.cell(0, 0).add_table(rows=2, cols=2)\n"
755
- 'inner.cell(0, 0).text = "deepest"'
756
- ),
757
- tags=("level17", "nested"),
758
- ),
745
+ # 51_nested_tables_deep removed in 0.11.2 (#20745 follow-up):
746
+ # _Cell.add_table now raises NestedTableNotSupportedError on
747
+ # SuperDoc 1.8.1; see SUPERDOC_UPSTREAM_REQUESTS.md § 13.
759
748
  ComplexCase(
760
749
  name="52_iterate_everything",
761
750
  description="Create a doc then iterate sections/paragraphs/tables",
@@ -1784,20 +1773,9 @@ CASES: list[ComplexCase] = [
1784
1773
  ),
1785
1774
 
1786
1775
  # ---------- Level 56: cell.tables for nested detection ----------
1787
- ComplexCase(
1788
- name="103_cell_tables_enumeration",
1789
- description="Enumerate cell.tables after nesting",
1790
- script=(
1791
- "outer = doc.add_table(rows=1, cols=1)\n"
1792
- "c = outer.cell(0, 0)\n"
1793
- "c.add_table(rows=2, cols=2)\n"
1794
- "c.add_table(rows=1, cols=1)\n"
1795
- "# cell.tables should list nested tables\n"
1796
- "nested = c.tables\n"
1797
- "# don't assert exact count — fake may not fully reflect"
1798
- ),
1799
- tags=("level56", "nested"),
1800
- ),
1776
+ # 103_cell_tables_enumeration removed in 0.11.2 (#20745 follow-up):
1777
+ # _Cell.add_table raises NestedTableNotSupportedError; see
1778
+ # SUPERDOC_UPSTREAM_REQUESTS.md § 13.
1801
1779
 
1802
1780
  # ---------- Level 57: core properties pull in datetime ----------
1803
1781
  ComplexCase(
@@ -11,18 +11,9 @@ from tests.fidelity.complex_cases import ComplexCase
11
11
 
12
12
  EXTREME_CASES: list[ComplexCase] = [
13
13
  # ---- Deep nesting ----
14
- ComplexCase(
15
- name="ex01_five_levels_deep_tables",
16
- description="5-level deep nested tables",
17
- script=(
18
- "current = doc.add_table(rows=1, cols=1).cell(0, 0)\n"
19
- "for i in range(4):\n"
20
- " nested = current.add_table(rows=1, cols=1)\n"
21
- " current = nested.cell(0, 0)\n"
22
- "current.text = 'deepest'"
23
- ),
24
- tags=("extreme", "nested"),
25
- ),
14
+ # ex01_five_levels_deep_tables removed in 0.11.2 (#20745 follow-up):
15
+ # _Cell.add_table raises NestedTableNotSupportedError on SuperDoc
16
+ # 1.8.1; see SUPERDOC_UPSTREAM_REQUESTS.md § 13.
26
17
 
27
18
  # ---- Unicode stress ----
28
19
  ComplexCase(
@@ -305,19 +305,10 @@ REAL_WORLD_CASES: list[ComplexCase] = [
305
305
  tags=("real_world", "headers", "even_odd"),
306
306
  ),
307
307
 
308
- # Cell-level _Cell.add_table nested table inside a cell, no width
309
- # parameter (matches upstream signature parity fix from Phase C).
310
- ComplexCase(
311
- name="rw14_nested_cell_table",
312
- description="Nested 2x2 table inside the (0,0) cell of a parent table",
313
- script=(
314
- "document = doc\n"
315
- "t = document.add_table(rows=2, cols=2, style='TableGrid')\n"
316
- "inner = t.cell(0, 0).add_table(2, 2)\n"
317
- "inner.cell(0, 0).text = 'inner'"
318
- ),
319
- tags=("real_world", "table", "nested"),
320
- ),
308
+ # rw14_nested_cell_table removed in 0.11.2 (#20745 follow-up):
309
+ # _Cell.add_table now raises NestedTableNotSupportedError; the
310
+ # functionality requires SuperDoc upstream work tracked at
311
+ # SUPERDOC_UPSTREAM_REQUESTS.md § 13.
321
312
 
322
313
  # Paragraph-style instances passed to add_paragraph (Phase A
323
314
  # tightening). Exercises the str | ParagraphStyle | None branch of
@@ -0,0 +1,79 @@
1
+ """Pinning test for ``_Cell.add_table`` raising
2
+ :class:`NestedTableNotSupportedError`.
3
+
4
+ SuperDoc 1.8.1 has no addressable shape for "create new table inside
5
+ this cell" — ``create.table`` rejects a cell-inner paragraph anchor
6
+ with ``INVALID_TARGET - Expected paragraph:<id> but found
7
+ tableCell:<id>``, and the ``doc.insert``-based workaround used by
8
+ ``_Cell.add_paragraph`` (paragraph fragment + ``placement: insideEnd``)
9
+ has no analog for table content fragments wired through the
10
+ docx-studio command bus. So ``_Cell.add_table`` raises a typed
11
+ ``NestedTableNotSupportedError`` rather than silently corrupting the
12
+ document (the pre-0.11.2 implementation either failed with the
13
+ cryptic INVALID_TARGET when the cell had content or silently wrote
14
+ the table to documentEnd when the cell was empty).
15
+
16
+ Tracked at ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md`` § 13.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from typing import Any
22
+
23
+ import pytest
24
+
25
+ from docx.errors import NestedTableNotSupportedError, ValidationError
26
+
27
+
28
+ def _make_cell(mock_session: Any, fake_sd_methods: Any) -> Any:
29
+ from docx.table import Table, _Cell
30
+
31
+ fake_sd_methods.scripted_returns["tables.get_cells"] = {
32
+ "cells": [
33
+ {
34
+ "nodeId": "cell-auto-x1",
35
+ "rowIndex": 0,
36
+ "columnIndex": 0,
37
+ "text": "",
38
+ },
39
+ ],
40
+ }
41
+ table = Table(session=mock_session, node_id="tbl-1")
42
+ return _Cell(table=table, row=0, col=0)
43
+
44
+
45
+ def test_cell_add_table_raises_nested_table_not_supported(
46
+ mock_session: Any, fake_sd_methods: Any
47
+ ) -> None:
48
+ cell = _make_cell(mock_session, fake_sd_methods)
49
+ with pytest.raises(NestedTableNotSupportedError) as exc_info:
50
+ cell.add_table(2, 2)
51
+ msg = str(exc_info.value)
52
+ assert "SUPERDOC_UPSTREAM_REQUESTS.md § 13" in msg
53
+ assert "Document.add_table" in msg
54
+
55
+
56
+ def test_cell_add_table_still_validates_dimensions_first(
57
+ mock_session: Any, fake_sd_methods: Any
58
+ ) -> None:
59
+ """``ValidationError`` for bad dimensions must still fire BEFORE the
60
+ NotImplementedError. Lets agents catch the more specific error
61
+ type without first reasoning about why the method is unsupported.
62
+ """
63
+ cell = _make_cell(mock_session, fake_sd_methods)
64
+ with pytest.raises(ValidationError, match="rows/cols"):
65
+ cell.add_table(0, 2)
66
+ with pytest.raises(ValidationError, match="rows/cols"):
67
+ cell.add_table(2, 0)
68
+
69
+
70
+ def test_nested_table_error_is_a_notimplementederror(
71
+ mock_session: Any, fake_sd_methods: Any
72
+ ) -> None:
73
+ """``NestedTableNotSupportedError`` subclasses ``NotImplementedError``
74
+ so generic ``except NotImplementedError`` (a common pattern) catches
75
+ it without needing to import the typed class.
76
+ """
77
+ cell = _make_cell(mock_session, fake_sd_methods)
78
+ with pytest.raises(NotImplementedError):
79
+ cell.add_table(2, 2)