athena-python-docx 0.13.0__tar.gz → 0.15.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.
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/CLAUDE.md +23 -1
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/PKG-INFO +1 -1
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/__init__.py +3 -1
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_buffer.py +53 -7
- athena_python_docx-0.15.0/docx/_execution.py +64 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_http.py +19 -8
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_http_doc.py +13 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_postproc.py +1163 -28
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/client.py +24 -4
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/commands.py +96 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/document.py +155 -5
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/errors.py +13 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/section.py +340 -62
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/table.py +324 -42
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/paragraph.py +142 -36
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/run.py +59 -35
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/pyproject.toml +1 -1
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/fake_session.py +25 -0
- athena_python_docx-0.15.0/tests/fidelity/op_snapshots/rw11_header_text.json +6 -0
- athena_python_docx-0.15.0/tests/fidelity/op_snapshots/rw12_first_page_footer.json +10 -0
- athena_python_docx-0.15.0/tests/fidelity/op_snapshots/rw13_even_page_header.json +9 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/reports/GAP_ANALYSIS.md +1 -1
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/reports/gap_report.json +14 -2
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/snapshots/athena_latest.json +2335 -1347
- athena_python_docx-0.15.0/tests/test_add_section_extract_items.py +137 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_athena_extensions_registry.py +2 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_buffer.py +57 -2
- athena_python_docx-0.15.0/tests/test_cell_inner_add_hyperlink_stash.py +110 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_inner_add_run_via_cell_insert.py +2 -2
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_inner_format_stash.py +100 -8
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_inner_run_format_stash.py +12 -12
- athena_python_docx-0.15.0/tests/test_cell_text_replace_semantics.py +116 -0
- athena_python_docx-0.15.0/tests/test_document_clear.py +132 -0
- athena_python_docx-0.15.0/tests/test_execution_scope.py +26 -0
- athena_python_docx-0.15.0/tests/test_find_replace_session_open.py +105 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_phase_b_headers_footers.py +116 -28
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_postproc_cell_format_rewrite.py +722 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_postproc_cell_run_format_rewrite.py +74 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_header_footer.py +6 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_section_dimensions.py +72 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_wire_contract.py +31 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/uv.lock +1 -1
- athena_python_docx-0.13.0/tests/fidelity/op_snapshots/rw11_header_text.json +0 -4
- athena_python_docx-0.13.0/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -6
- athena_python_docx-0.13.0/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -5
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/.gitignore +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/README.md +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_image_utils.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/api.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/bookmarks.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/charts.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/comments.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/enum/section.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/enum/style.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/enum/table.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/enum/text.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/fields.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/footnotes.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/math.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/opc/coreprops.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/oxml/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/sdt.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/session.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/settings.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/shape.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/shared.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/styles/style.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/styles/styles.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/hyperlink.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/pagebreak.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/parfmt.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/text/tabstops.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/toc.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/docx/typing.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/scripts/publish.sh +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/scripts/release.sh +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/scripts/smoke_test_block_not_found.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/METHODOLOGY.md +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/ab_probe_cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/firm_templates/README.md +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/firm_templates/_runner.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/firm_templates/extractor.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/runner.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/README.md +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/intentional_deviations.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_block_not_found_error.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_add_table_not_supported.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_inner_run_guard.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_cell_text_plain_fastpath.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_collapsed_range_format.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_comments.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_document_create.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_document_create_from_template.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_document_factory_validation.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_http_transport.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_hyperlink_coalescing.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_list_styles.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_merged_cell_secondary_slot.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_parity_misc.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_parity_round2.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_phase_a_behavior.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_postproc_ref_restore.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_revisions.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_enum_section.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_inline_shape.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_misc.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_parfmt.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_row_col_cell.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_run_style.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_run_style_strict.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_run_text.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_run_underline.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_section_onoff.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_style.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_silent_stub_table_layout.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_style_setters_contract.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_table_set_cell_perf.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_table_style_id_resolution.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_xml_attr_guard.py +0 -0
- {athena_python_docx-0.13.0 → athena_python_docx-0.15.0}/tests/test_zod_wire_contract.py +0 -0
|
@@ -349,6 +349,18 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
349
349
|
wontfix upstream but the request keeps recurring. Routes through
|
|
350
350
|
`ExportPDF` (SuperDoc handles the actual conversion).
|
|
351
351
|
|
|
352
|
+
- **`Document.clear()`** (0.14.0+) — empty the document body so subsequent
|
|
353
|
+
writes start from a clean slate. python-docx has no equivalent (it
|
|
354
|
+
operates on local files where the caller can simply construct a new
|
|
355
|
+
``Document``). Iterates every top-level paragraph and table cell and
|
|
356
|
+
empties their text content. Block structure is preserved (SuperDoc has
|
|
357
|
+
no wire op to delete blocks today), so post-clear the doc holds N
|
|
358
|
+
empty paragraphs rather than collapsing to a single one — for a truly
|
|
359
|
+
empty body, call ``Document.create()`` to mint a fresh asset instead.
|
|
360
|
+
Closes the gap that prompted the 0.14 series' agent-side ``find_replace``
|
|
361
|
+
cleanup loops, which left horizontal-rule and scratch-content artifacts
|
|
362
|
+
in the document during failed-run recoveries.
|
|
363
|
+
|
|
352
364
|
- **`Document.export_docx(path=None, *, include_revisions=False)
|
|
353
365
|
-> bytes`** (0.11.4+) — export the document's current state as
|
|
354
366
|
``.docx`` bytes, optionally writing to ``path``. Closes the gap
|
|
@@ -602,6 +614,16 @@ This is a **thin HTTP client** that mimics the sync python-docx API.
|
|
|
602
614
|
the context-manager exit drain explicitly; `docx.flush_all()` is
|
|
603
615
|
the Daytona-prelude hook that flushes every live buffer in the
|
|
604
616
|
process.
|
|
617
|
+
- Execution scope: executor sandboxes may keep Python globals
|
|
618
|
+
between tool calls so imports, constants, and helper functions can be
|
|
619
|
+
reused. Live SDK objects are different. The executor calls
|
|
620
|
+
`docx.begin_execution(request_id)` at the start of each tool call;
|
|
621
|
+
`Session` and `CommandBuffer` stamp that id and raise
|
|
622
|
+
`StaleDocumentHandleError` if a later call tries to reuse old
|
|
623
|
+
`Document`/paragraph/run/table/cell handles. `docx.flush_all(strict=True)`
|
|
624
|
+
is the executor path and raises `FlushAllError` for failed flushes or
|
|
625
|
+
stale pending buffers; plain `docx.flush_all()` keeps the historical
|
|
626
|
+
log-and-swallow behavior for local scripts.
|
|
605
627
|
- **Insert deferral (0.8.0+):** `Insert` was removed from the
|
|
606
628
|
response-bearing set because every in-tree caller
|
|
607
629
|
(`Paragraph._insert_run_text_segments`, `Run.add_text`, `_Cell.text`)
|
|
@@ -650,7 +672,7 @@ This is a **thin HTTP client** that mimics the sync python-docx API.
|
|
|
650
672
|
follow-up — the wire format is typed end-to-end either way.
|
|
651
673
|
- **Programmatic Tool Calling (PTC):** every `CommandBuffer.call` and
|
|
652
674
|
`flush` emits begin/end events to agora via `docx/_ptc.py` when run
|
|
653
|
-
inside
|
|
675
|
+
inside an execution sandbox with `ATHENA_PTC_URL` set. Each method call
|
|
654
676
|
surfaces as a nested sub-tool-card under the parent
|
|
655
677
|
`run_python_code` tool. See
|
|
656
678
|
[`docs/PROGRAMMATIC_TOOL_CALLING_GUIDE.md`](../../docs/PROGRAMMATIC_TOOL_CALLING_GUIDE.md)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
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,8 +6,9 @@ See CLAUDE.md for the API parity contract.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
__version__ = "0.
|
|
9
|
+
__version__ = "0.15.0"
|
|
10
10
|
|
|
11
|
+
from docx._execution import begin_execution
|
|
11
12
|
from docx.api import Document
|
|
12
13
|
from docx._buffer import flush_all
|
|
13
14
|
# Re-exports python-docx ships at docx top-level for convenience.
|
|
@@ -23,6 +24,7 @@ __all__ = [
|
|
|
23
24
|
"Twips",
|
|
24
25
|
"Length",
|
|
25
26
|
"RGBColor",
|
|
27
|
+
"begin_execution",
|
|
26
28
|
"flush_all",
|
|
27
29
|
"__version__",
|
|
28
30
|
]
|
|
@@ -34,8 +34,13 @@ import weakref
|
|
|
34
34
|
from typing import TYPE_CHECKING, Any
|
|
35
35
|
|
|
36
36
|
from docx import _ptc
|
|
37
|
+
from docx._execution import (
|
|
38
|
+
assert_current_execution,
|
|
39
|
+
current_execution_id,
|
|
40
|
+
is_stale_execution,
|
|
41
|
+
)
|
|
37
42
|
from docx.commands import Command, is_response_bearing, must_flush_immediately
|
|
38
|
-
from docx.errors import DocxError
|
|
43
|
+
from docx.errors import DocxError, FlushAllError
|
|
39
44
|
|
|
40
45
|
|
|
41
46
|
def _apply_proxy_id_rewrites(
|
|
@@ -172,13 +177,17 @@ def _unregister(buffer: "CommandBuffer") -> None:
|
|
|
172
177
|
]
|
|
173
178
|
|
|
174
179
|
|
|
175
|
-
def flush_all() -> None:
|
|
180
|
+
def flush_all(*, strict: bool = False) -> None:
|
|
176
181
|
"""Flush every live CommandBuffer in this process.
|
|
177
182
|
|
|
178
183
|
Used by the Daytona sandbox prelude after user code returns, so
|
|
179
184
|
buffered mutations make it to Keryx before the sandbox is suspended.
|
|
180
|
-
Safe to call when no Buffers exist (no-op).
|
|
181
|
-
|
|
185
|
+
Safe to call when no Buffers exist (no-op).
|
|
186
|
+
|
|
187
|
+
By default, failures are logged and swallowed for backwards
|
|
188
|
+
compatibility with existing local scripts. The executor calls
|
|
189
|
+
``flush_all(strict=True)`` so failed or stale writes surface as real tool
|
|
190
|
+
failures instead of being hidden in stderr.
|
|
182
191
|
"""
|
|
183
192
|
with _registry_lock:
|
|
184
193
|
snapshot = list(_active_buffers)
|
|
@@ -186,16 +195,35 @@ def flush_all() -> None:
|
|
|
186
195
|
live = [ref for ref in snapshot if ref() is not None]
|
|
187
196
|
_active_buffers[:] = live
|
|
188
197
|
|
|
198
|
+
failures: list[str] = []
|
|
189
199
|
for ref in live:
|
|
190
200
|
buf = ref()
|
|
191
201
|
if buf is None:
|
|
192
202
|
continue
|
|
203
|
+
if buf.is_stale_for_current_execution:
|
|
204
|
+
pending_count = buf.pending_count
|
|
205
|
+
if pending_count > 0:
|
|
206
|
+
msg = (
|
|
207
|
+
f"buffer {buf.asset_id} belongs to a previous "
|
|
208
|
+
f"execute_word_document_code call and still has "
|
|
209
|
+
f"{pending_count} unflushed command(s)"
|
|
210
|
+
)
|
|
211
|
+
if strict:
|
|
212
|
+
failures.append(msg)
|
|
213
|
+
else:
|
|
214
|
+
sys.stderr.write(f"[docx-sdk] flush_all: {msg}\n")
|
|
215
|
+
continue
|
|
193
216
|
try:
|
|
194
217
|
buf.flush()
|
|
195
218
|
except Exception as e: # noqa: BLE001
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
219
|
+
msg = f"buffer {buf.asset_id} flush failed: {e}"
|
|
220
|
+
if strict:
|
|
221
|
+
failures.append(msg)
|
|
222
|
+
else:
|
|
223
|
+
sys.stderr.write(f"[docx-sdk] flush_all: {msg}\n")
|
|
224
|
+
|
|
225
|
+
if failures:
|
|
226
|
+
raise FlushAllError(failures)
|
|
199
227
|
|
|
200
228
|
|
|
201
229
|
# ---------------------------------------------------------------------------
|
|
@@ -240,6 +268,7 @@ class CommandBuffer:
|
|
|
240
268
|
self._timer: threading.Timer | None = None
|
|
241
269
|
self._auto_flush_seconds: float = auto_flush_seconds
|
|
242
270
|
self._closed: bool = False
|
|
271
|
+
self._execution_id: str | None = current_execution_id()
|
|
243
272
|
# Track-changes envelope state — propagated as request-level
|
|
244
273
|
# ``changeMode`` and ``user`` on every batch. ``Document``
|
|
245
274
|
# mutates these via :meth:`set_change_mode` / :meth:`set_user`,
|
|
@@ -263,6 +292,7 @@ class CommandBuffer:
|
|
|
263
292
|
the per-cmd result for ``real_node_id`` / ``real_entity_id``
|
|
264
293
|
echoes and applies setattr to every registered ref.
|
|
265
294
|
"""
|
|
295
|
+
self._assert_current_execution()
|
|
266
296
|
with self._lock:
|
|
267
297
|
self._proxy_id_refs.setdefault(client_id, []).append((proxy, attr))
|
|
268
298
|
|
|
@@ -275,6 +305,10 @@ class CommandBuffer:
|
|
|
275
305
|
with self._lock:
|
|
276
306
|
return len(self._pending)
|
|
277
307
|
|
|
308
|
+
@property
|
|
309
|
+
def is_stale_for_current_execution(self) -> bool:
|
|
310
|
+
return is_stale_execution(self._execution_id)
|
|
311
|
+
|
|
278
312
|
@property
|
|
279
313
|
def change_mode(self) -> str | None:
|
|
280
314
|
return self._change_mode
|
|
@@ -291,6 +325,7 @@ class CommandBuffer:
|
|
|
291
325
|
retro-actively re-tag earlier mutations. ``mode`` is one of
|
|
292
326
|
``"direct"``, ``"tracked"``, or ``None`` to clear.
|
|
293
327
|
"""
|
|
328
|
+
self._assert_current_execution()
|
|
294
329
|
if mode is not None and mode not in ("direct", "tracked"):
|
|
295
330
|
raise ValueError(f"change_mode must be 'direct', 'tracked', or None; got {mode!r}")
|
|
296
331
|
with self._lock:
|
|
@@ -311,6 +346,7 @@ class CommandBuffer:
|
|
|
311
346
|
a pooled session ignore the value, but the payload is still
|
|
312
347
|
included so a fresh session picks it up.
|
|
313
348
|
"""
|
|
349
|
+
self._assert_current_execution()
|
|
314
350
|
if name is None:
|
|
315
351
|
with self._lock:
|
|
316
352
|
self._user = None
|
|
@@ -339,6 +375,7 @@ class CommandBuffer:
|
|
|
339
375
|
``clientIdMap`` on flush and the buffer rewrites each registered
|
|
340
376
|
proxy's ``_node_id`` in-place.
|
|
341
377
|
"""
|
|
378
|
+
self._assert_current_execution()
|
|
342
379
|
if self._closed:
|
|
343
380
|
raise RuntimeError(
|
|
344
381
|
f"CommandBuffer for {self._asset_id} is closed",
|
|
@@ -397,6 +434,7 @@ class CommandBuffer:
|
|
|
397
434
|
proxies pick up real ids without the caller ever seeing the
|
|
398
435
|
UUID swap.
|
|
399
436
|
"""
|
|
437
|
+
self._assert_current_execution()
|
|
400
438
|
with self._lock:
|
|
401
439
|
self._cancel_timer_locked()
|
|
402
440
|
pending = self._pending
|
|
@@ -436,6 +474,7 @@ class CommandBuffer:
|
|
|
436
474
|
"""Flush and disable. Idempotent."""
|
|
437
475
|
if self._closed:
|
|
438
476
|
return
|
|
477
|
+
self._assert_current_execution()
|
|
439
478
|
try:
|
|
440
479
|
self.flush()
|
|
441
480
|
finally:
|
|
@@ -453,6 +492,7 @@ class CommandBuffer:
|
|
|
453
492
|
still get their real ids written back via the same flush-time
|
|
454
493
|
rewrite that :meth:`flush` does.
|
|
455
494
|
"""
|
|
495
|
+
self._assert_current_execution()
|
|
456
496
|
with self._lock:
|
|
457
497
|
self._cancel_timer_locked()
|
|
458
498
|
pending = self._pending
|
|
@@ -515,5 +555,11 @@ class CommandBuffer:
|
|
|
515
555
|
f"[docx-sdk] auto-flush failed for {self._asset_id}: {e}\n",
|
|
516
556
|
)
|
|
517
557
|
|
|
558
|
+
def _assert_current_execution(self) -> None:
|
|
559
|
+
assert_current_execution(
|
|
560
|
+
self._execution_id,
|
|
561
|
+
object_name=f"CommandBuffer for {self._asset_id}",
|
|
562
|
+
)
|
|
563
|
+
|
|
518
564
|
|
|
519
565
|
__all__ = ["CommandBuffer", "flush_all", "DEFAULT_AUTO_FLUSH_SECONDS"]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Execution-scope helpers for long-lived sandbox processes.
|
|
2
|
+
|
|
3
|
+
Document execution sandboxes intentionally keep Python globals alive between
|
|
4
|
+
tool calls so agents can reuse helper functions and imports. Live SDK handles
|
|
5
|
+
are different: a ``Document``/``Paragraph``/``Run`` proxy captures a transport
|
|
6
|
+
session and a snapshot of node ids from the moment it was opened. Reusing that
|
|
7
|
+
proxy in a later tool call can overwrite manual user edits made between calls.
|
|
8
|
+
|
|
9
|
+
The executor calls :func:`begin_execution` once per tool call. Sessions and
|
|
10
|
+
buffers created after that stamp themselves with the active execution id; any
|
|
11
|
+
later operation under a different id fails before issuing HTTP.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from docx.errors import StaleDocumentHandleError
|
|
17
|
+
|
|
18
|
+
_current_execution_id: str | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def begin_execution(execution_id: str | None) -> None:
|
|
22
|
+
"""Mark the start of a logical executor call.
|
|
23
|
+
|
|
24
|
+
Passing ``None`` disables stale-handle checks, which keeps local scripts
|
|
25
|
+
and existing tests behaving like normal in-memory Python programs.
|
|
26
|
+
"""
|
|
27
|
+
global _current_execution_id
|
|
28
|
+
_current_execution_id = str(execution_id) if execution_id else None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def current_execution_id() -> str | None:
|
|
32
|
+
"""Return the active executor id, if one has been declared."""
|
|
33
|
+
return _current_execution_id
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def is_stale_execution(owner_execution_id: str | None) -> bool:
|
|
37
|
+
"""Whether an object stamped with ``owner_execution_id`` is stale."""
|
|
38
|
+
current = current_execution_id()
|
|
39
|
+
return current is not None and owner_execution_id != current
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def assert_current_execution(
|
|
43
|
+
owner_execution_id: str | None,
|
|
44
|
+
*,
|
|
45
|
+
object_name: str,
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Raise if an SDK object belongs to a prior executor call."""
|
|
48
|
+
if not is_stale_execution(owner_execution_id):
|
|
49
|
+
return
|
|
50
|
+
raise StaleDocumentHandleError(
|
|
51
|
+
f"{object_name} belongs to a previous execute_word_document_code call. "
|
|
52
|
+
"Reopen the document inside the current tool call with "
|
|
53
|
+
"Document('asset_xxx') and pass that fresh Document into reusable "
|
|
54
|
+
"helper functions. Imports, constants, and function definitions can "
|
|
55
|
+
"still persist across calls."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
__all__ = [
|
|
60
|
+
"assert_current_execution",
|
|
61
|
+
"begin_execution",
|
|
62
|
+
"current_execution_id",
|
|
63
|
+
"is_stale_execution",
|
|
64
|
+
]
|
|
@@ -100,17 +100,24 @@ def create_empty_document(
|
|
|
100
100
|
DocxError: any other 4xx/5xx from the server.
|
|
101
101
|
"""
|
|
102
102
|
resolved_base: str | None = base_url or os.environ.get(_BASE_URL_ENV)
|
|
103
|
-
|
|
103
|
+
# api_key falls back to ATHENA_API_KEY (the canonical Athena user API
|
|
104
|
+
# key) so code running in sandboxes that only inject ATHENA_API_KEY
|
|
105
|
+
# still authenticates without an extra env var.
|
|
106
|
+
resolved_key: str | None = (
|
|
107
|
+
api_key or os.environ.get(_API_KEY_ENV) or os.environ.get("ATHENA_API_KEY")
|
|
108
|
+
)
|
|
104
109
|
|
|
105
110
|
if not resolved_base:
|
|
106
111
|
raise SessionError(
|
|
107
112
|
f"Missing base_url and {_BASE_URL_ENV} env var. "
|
|
108
|
-
"Pass base_url= to Document.create() or set the env var
|
|
113
|
+
"Pass base_url= to Document.create() or set the env var "
|
|
114
|
+
'(e.g. ATHENA_DOCX_BASE_URL="https://docx-studio.prd.athenaintel.com").',
|
|
109
115
|
)
|
|
110
116
|
if not resolved_key:
|
|
111
117
|
raise AuthenticationError(
|
|
112
118
|
f"Missing api_key and {_API_KEY_ENV} env var. "
|
|
113
|
-
"Pass api_key= to Document.create() or set the env var
|
|
119
|
+
"Pass api_key= to Document.create() or set the env var "
|
|
120
|
+
"(or set ATHENA_API_KEY as a fallback).",
|
|
114
121
|
)
|
|
115
122
|
|
|
116
123
|
url: str = resolved_base.rstrip("/") + "/docs/empty"
|
|
@@ -256,7 +263,12 @@ def upload_document(
|
|
|
256
263
|
import uuid
|
|
257
264
|
|
|
258
265
|
resolved_docx_base: str | None = docx_base_url or os.environ.get(_BASE_URL_ENV)
|
|
259
|
-
|
|
266
|
+
# api_key falls back to ATHENA_API_KEY (the canonical Athena user API
|
|
267
|
+
# key) so code running in sandboxes that only inject ATHENA_API_KEY
|
|
268
|
+
# still authenticates without an extra env var.
|
|
269
|
+
resolved_key: str | None = (
|
|
270
|
+
api_key or os.environ.get(_API_KEY_ENV) or os.environ.get("ATHENA_API_KEY")
|
|
271
|
+
)
|
|
260
272
|
resolved_agora_base: str | None = (
|
|
261
273
|
agora_base_url
|
|
262
274
|
or os.environ.get(_AGORA_BASE_URL_ENV)
|
|
@@ -273,7 +285,8 @@ def upload_document(
|
|
|
273
285
|
if not resolved_key:
|
|
274
286
|
raise AuthenticationError(
|
|
275
287
|
f"Missing api_key and {_API_KEY_ENV} env var. "
|
|
276
|
-
"Pass api_key= to Document.create() or set the env var
|
|
288
|
+
"Pass api_key= to Document.create() or set the env var "
|
|
289
|
+
"(or set ATHENA_API_KEY as a fallback).",
|
|
277
290
|
)
|
|
278
291
|
|
|
279
292
|
if not os.path.exists(docx_path):
|
|
@@ -297,9 +310,7 @@ def upload_document(
|
|
|
297
310
|
qs["parent_folder_id"] = parent_folder_id
|
|
298
311
|
|
|
299
312
|
url: str = (
|
|
300
|
-
resolved_agora_base.rstrip("/")
|
|
301
|
-
+ "/api/super-docs/create-from-upload?"
|
|
302
|
-
+ urlencode(qs)
|
|
313
|
+
resolved_agora_base.rstrip("/") + "/api/super-docs/create-from-upload?" + urlencode(qs)
|
|
303
314
|
)
|
|
304
315
|
|
|
305
316
|
# Build a minimal multipart/form-data body without pulling in
|
|
@@ -95,6 +95,11 @@ from docx.commands import (
|
|
|
95
95
|
GetNodeById,
|
|
96
96
|
HeaderFootersGet,
|
|
97
97
|
HeaderFootersList,
|
|
98
|
+
HeaderFootersPartsCreate,
|
|
99
|
+
HeaderFootersPartsDelete,
|
|
100
|
+
HeaderFootersPartsList,
|
|
101
|
+
HeaderFootersRefsClear,
|
|
102
|
+
HeaderFootersRefsSet,
|
|
98
103
|
HeaderFootersRefsSetLinkedToPrevious,
|
|
99
104
|
HeaderFootersResolve,
|
|
100
105
|
ImagesGet,
|
|
@@ -152,6 +157,7 @@ from docx.commands import (
|
|
|
152
157
|
TablesSetColumnWidth,
|
|
153
158
|
TablesSetLayout,
|
|
154
159
|
TablesSetRowHeight,
|
|
160
|
+
TablesSetRowOptions,
|
|
155
161
|
TablesSetStyle,
|
|
156
162
|
TablesSetTableOptions,
|
|
157
163
|
TableSetCell,
|
|
@@ -307,6 +313,7 @@ _TABLE_QUERY_COMMANDS: frozenset[str] = frozenset(
|
|
|
307
313
|
"TablesSetCellProperties",
|
|
308
314
|
"TablesSetColumnWidth",
|
|
309
315
|
"TablesSetRowHeight",
|
|
316
|
+
"TablesSetRowOptions",
|
|
310
317
|
"TablesInsertRow",
|
|
311
318
|
"TablesInsertColumn",
|
|
312
319
|
"TablesMergeCells",
|
|
@@ -821,6 +828,7 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
|
|
|
821
828
|
"tables.set_cell_properties": TablesSetCellProperties,
|
|
822
829
|
"tables.set_column_width": TablesSetColumnWidth,
|
|
823
830
|
"tables.set_row_height": TablesSetRowHeight,
|
|
831
|
+
"tables.set_row_options": TablesSetRowOptions,
|
|
824
832
|
"tables.set_cell": TableSetCell,
|
|
825
833
|
# Images (mutations)
|
|
826
834
|
"images.set_size": SetImageSize,
|
|
@@ -851,6 +859,11 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
|
|
|
851
859
|
"header_footers.get": HeaderFootersGet,
|
|
852
860
|
"header_footers.resolve": HeaderFootersResolve,
|
|
853
861
|
"header_footers.refs.set_linked_to_previous": HeaderFootersRefsSetLinkedToPrevious,
|
|
862
|
+
"header_footers.parts.create": HeaderFootersPartsCreate,
|
|
863
|
+
"header_footers.parts.list": HeaderFootersPartsList,
|
|
864
|
+
"header_footers.parts.delete": HeaderFootersPartsDelete,
|
|
865
|
+
"header_footers.refs.set": HeaderFootersRefsSet,
|
|
866
|
+
"header_footers.refs.clear": HeaderFootersRefsClear,
|
|
854
867
|
# Lists & Selection. ``lists.create`` and ``lists.attach`` are
|
|
855
868
|
# consumed internally by ``Document.add_paragraph`` to make
|
|
856
869
|
# ``style="List Bullet" | "List Number"`` produce real list
|