athena-python-docx 0.20.0__tar.gz → 0.21.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/CLAUDE.md +128 -73
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/DOCX_EXEC_LAB.md +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/PKG-INFO +9 -12
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/README.md +6 -7
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/__init__.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_buffer.py +5 -5
- athena_python_docx-0.21.1/docx/_citations.py +149 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_http.py +122 -91
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_http_doc.py +32 -24
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_image_utils.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_postproc.py +48 -48
- athena_python_docx-0.21.1/docx/_references.py +91 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_timeouts.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/api.py +6 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/bookmarks.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/charts.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/client.py +2 -9
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/commands.py +95 -62
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/comments.py +23 -23
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/document.py +118 -73
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/enum/section.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/enum/table.py +5 -5
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/enum/text.py +22 -22
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/errors.py +14 -14
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/footnotes.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/math.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/opc/coreprops.py +5 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/oxml/__init__.py +5 -5
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/revisions.py +14 -14
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/sdt.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/section.py +80 -80
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/settings.py +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/shape.py +8 -8
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/styles/style.py +31 -33
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/styles/styles.py +54 -24
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/table.py +115 -147
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/hyperlink.py +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/pagebreak.py +9 -9
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/paragraph.py +100 -40
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/parfmt.py +12 -12
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/run.py +32 -33
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/tabstops.py +15 -15
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/typing.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/pyproject.toml +4 -9
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/docx_exec_lab.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/docx_exec_lab_server.py +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/dump_wire_fixtures.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/round_trip_smoke.py +7 -8
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/smoke_test_block_not_found.py +6 -15
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/validate_find_replace_asset.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/conftest.py +6 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/METHODOLOGY.md +9 -9
- athena_python_docx-0.21.1/tests/fidelity/README.md +50 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/__init__.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/ab_probe_cases.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/ab_probe_runner.py +6 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/binary_round_trip.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/cases.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/complex_cases.py +5 -5
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/extract.py +5 -5
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/extreme_cases.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/fake_session.py +44 -45
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/firm_templates/README.md +7 -7
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/firm_templates/_runner.py +12 -11
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/firm_templates/extractor.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/firm_templates/test_pw_corpus.py +15 -15
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/firm_templates/test_pw_research_digest.py +10 -10
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshot.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/ours_spec.json +7 -7
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/real_world_cases.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/test_e2e_against_staging.py +20 -107
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/intentional_deviations.json +3 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/snapshots/athena_latest.json +12 -12
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_add_section_extract_items.py +5 -5
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_athena_extensions_registry.py +5 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_batching_perf.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_block_not_found_error.py +12 -12
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_add_paragraph_wire_shape.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_add_table_not_supported.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_inner_add_run_via_cell_insert.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_inner_format_stash.py +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_inner_run_guard.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_text_plain_fastpath.py +1 -1
- athena_python_docx-0.21.1/tests/test_citations.py +316 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_collapsed_range_format.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_commands.py +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_comments.py +4 -4
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_document_clear.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_document_create.py +5 -11
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_document_create_from_template.py +167 -52
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_document_factory_validation.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_docx_exec_lab.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_e2e_partial_failure_cascade.py +8 -8
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_http_transport.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_hyperlink_coalescing.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_list_styles.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_merged_cell_secondary_slot.py +6 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_merged_cells.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_parity_misc.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_parity_round2.py +10 -10
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_partial_failure_cascade.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_phase_a_behavior.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_phase_b_headers_footers.py +10 -10
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_phase_c_tables.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_positional_cell_id.py +7 -7
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_postproc_cell_format_rewrite.py +7 -7
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_postproc_ref_restore.py +8 -8
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_pr19766_review_fixes.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_python_docx_api_parity.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_revisions.py +13 -13
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_add_paragraph_style.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_cell_add_paragraph.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_comments_add_comment.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_comments_get.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_document_audit.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_enum_section.py +8 -8
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_header_footer.py +7 -7
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_hyperlink.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_inline_shape.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_misc.py +20 -20
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_paragraph_strict.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_paragraph_style_strict.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_parfmt.py +18 -18
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_row_col_cell.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_run_style.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_run_style_strict.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_run_text.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_run_underline.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_section_audit.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_section_dimensions.py +6 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_section_onoff.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_settings.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_style.py +6 -6
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_styles.py +10 -10
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_table_dimensions.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_table_layout.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_smoke_integration.py +4 -5
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_style_font.py +3 -3
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_style_setters_contract.py +10 -11
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_table_set_cell_perf.py +1 -1
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_wire_contract.py +12 -12
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_zod_wire_contract.py +2 -2
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/uv.lock +13 -114
- athena_python_docx-0.20.0/tests/fidelity/README.md +0 -71
- athena_python_docx-0.20.0/tests/fidelity/runner.py +0 -486
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/.gitignore +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_batching.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_execution.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_ptc.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/enum/shape.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/enum/style.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/exceptions.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/fields.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/session.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/shared.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/text/font.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/docx/toc.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/publish.sh +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/scripts/release.sh +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/README.md +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/reports/gap_report.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_inner_run_format_stash.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_cell_text_replace_semantics.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_execution_scope.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_find_replace_session_open.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_image_url_data_uri.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_table_style_id_resolution.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_validate_find_replace_asset_script.py +0 -0
- {athena_python_docx-0.20.0 → athena_python_docx-0.21.1}/tests/test_xml_attr_guard.py +0 -0
|
@@ -25,35 +25,35 @@ Before adding or modifying any API surface:
|
|
|
25
25
|
|
|
26
26
|
Run `uv run pytest tests/test_python_docx_api_parity.py -v -s` to verify parity.
|
|
27
27
|
|
|
28
|
-
### Intentionally omitted (
|
|
28
|
+
### Intentionally omitted (current SDK limitations)
|
|
29
29
|
|
|
30
|
-
These standard python-docx members don't apply to a
|
|
30
|
+
These standard python-docx members don't apply to a DOCX Studio-backed SDK:
|
|
31
31
|
|
|
32
32
|
- `Paragraph._p`, `Run._r` — XML element access (no local XML)
|
|
33
33
|
- `Document.part`, `Paragraph.part`, `Run.part` — package part access
|
|
34
34
|
- `Document.core_properties.last_modified_by` — we use Keryx attribution instead
|
|
35
|
-
- `Document.settings` — Word app settings (not surfaced by
|
|
36
|
-
- `InlineShape.chart` — charts
|
|
35
|
+
- `Document.settings` — Word app settings (not surfaced by DOCX Studio)
|
|
36
|
+
- `InlineShape.chart` — charts are not currently surfaced by the SDK.
|
|
37
37
|
- `Comment.add_paragraph` / `Comment.add_table` /
|
|
38
38
|
`Comment.iter_inner_content` / `Comment.paragraphs` /
|
|
39
|
-
`Comment.tables` —
|
|
39
|
+
`Comment.tables` — DOCX Studio 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
42
|
- **`_Cell.add_table(rows, cols)`** — surface preserved for parity
|
|
43
43
|
(signature matches python-docx, no `width` kwarg) but raises
|
|
44
44
|
:class:`docx.errors.NestedTableNotSupportedError` (subclass of
|
|
45
|
-
`NotImplementedError`) at runtime since 0.11.2.
|
|
46
|
-
no anchor or content-fragment shape
|
|
47
|
-
an existing `tableCell` — `create.table` rejects cell-inner
|
|
45
|
+
`NotImplementedError`) at runtime since 0.11.2. The current
|
|
46
|
+
docx-editor command surface has no anchor or content-fragment shape
|
|
47
|
+
that places a new table inside an existing `tableCell` — `create.table` rejects cell-inner
|
|
48
48
|
paragraph anchors with `INVALID_TARGET`, and the `doc.insert`
|
|
49
49
|
workaround used by `_Cell.add_paragraph` doesn't generalize
|
|
50
50
|
because the apps/api `Insert` schema doesn't yet forward
|
|
51
|
-
`nestingPolicy: {tables: "allow"}` and the
|
|
51
|
+
`nestingPolicy: {tables: "allow"}` and the DOCX editor table-content
|
|
52
52
|
fragment shape isn't documented. Tracked at
|
|
53
|
-
`docx-studio/
|
|
53
|
+
`docx-studio/DOCX_STUDIO_LIMITATIONS.md` § 13.
|
|
54
54
|
- **`docx.oxml.*`** — the entire raw-OOXML module tree (``ns.qn``,
|
|
55
55
|
``OxmlElement``, ``CT_*`` classes, etc.) is unavailable because the
|
|
56
|
-
SDK is HTTP-only against a
|
|
56
|
+
SDK is HTTP-only against a DOCX Studio Y.Doc; there is no local lxml
|
|
57
57
|
tree to manipulate. As of 0.8.0, ``docx.oxml`` is a real stub
|
|
58
58
|
package that raises a typed
|
|
59
59
|
:class:`docx.oxml.OxmlNotAvailableError` (subclass of
|
|
@@ -64,25 +64,21 @@ These standard python-docx members don't apply to a Superdoc-backed SDK:
|
|
|
64
64
|
generic ``ModuleNotFoundError: No module named 'docx.oxml'`` and
|
|
65
65
|
agents had to retry to discover the gap.
|
|
66
66
|
|
|
67
|
-
###
|
|
67
|
+
### Known partially supported surface
|
|
68
68
|
|
|
69
69
|
These are *shipped at the surface* but partially or fully no-op at
|
|
70
|
-
runtime, pending
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
and the bundled TypeScript types in
|
|
74
|
-
`node_modules/@superdoc-dev/sdk/dist/generated/client.d.ts`. See
|
|
75
|
-
`docx-studio/PYTHON_DOCX_PARITY_GAPS.md` § *What unblocks the
|
|
76
|
-
remaining work* for the exact wire-op shape needed to unblock each.
|
|
70
|
+
runtime, pending additional docx-editor command support. Behavior should be
|
|
71
|
+
pinned by focused tests and documented in
|
|
72
|
+
`docx-studio/DOCX_STUDIO_LIMITATIONS.md`.
|
|
77
73
|
|
|
78
74
|
- **24 setters on `BaseStyle` / `CharacterStyle` / `ParagraphStyle`**
|
|
79
75
|
(`name`, `style_id`, `hidden`, `locked`, `priority`, `quick_style`,
|
|
80
76
|
`unhide_when_used`, `base_style`, `next_paragraph_style`) emit
|
|
81
77
|
`PendingStyleMutationWarning` and stash on `_overrides`.
|
|
82
|
-
|
|
78
|
+
The current `doc.styles.apply` command surface is constrained to
|
|
83
79
|
`target.scope: "docDefaults"` — no per-style metadata variant.
|
|
84
80
|
Behavior pinned by `tests/test_style_setters_contract.py` (11
|
|
85
|
-
tests); when
|
|
81
|
+
tests); when docx-editor lands a metadata op, those tests will need
|
|
86
82
|
to flip to assert real bus calls.
|
|
87
83
|
- **`Styles.latent_styles`** returns an empty `_LatentStyles` —
|
|
88
84
|
`DocInfoResult.styles` only surfaces `paragraphStyles[]` (a flat
|
|
@@ -123,25 +119,24 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
123
119
|
and silently falls back to ``Normal Table`` (no borders, no
|
|
124
120
|
header fill, no banding). Custom user-defined style names pass
|
|
125
121
|
through unchanged. Whether Word actually renders a Word 2013+
|
|
126
|
-
style after resolution also depends on
|
|
122
|
+
style after resolution also depends on the exported
|
|
127
123
|
``styles.xml`` containing the matching ``<w:style w:type="table">``
|
|
128
|
-
definition
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
124
|
+
definition. If the exported ``styles.xml`` only carries the Word 2007
|
|
125
|
+
set, Word 2013+ styleIds resolve in the ``<w:tblStyle>`` element but
|
|
126
|
+
still fall back to ``Normal Table`` until the export path ships an
|
|
127
|
+
expanded ``styles.xml``.
|
|
132
128
|
|
|
133
129
|
- **`Document.create(name=, base_url=, api_key=, parent_folder_id=, workspace_id=, docx=, agora_base_url=)`**
|
|
134
130
|
classmethod. Stock python-docx returns a blank in-memory document
|
|
135
|
-
for `Document(None)`; we can't fabricate a
|
|
131
|
+
for `Document(None)`; we can't fabricate a Word document asset
|
|
136
132
|
client-side, so net-new asset creation is a separate factory that
|
|
137
133
|
hits `POST {base_url}/docs/empty`. The constructor positional-arg
|
|
138
134
|
shape (`Document(asset_id)`) is preserved for parity.
|
|
139
135
|
- **`docx=path`** mirrors the upstream `Document(docx="template.docx")`
|
|
140
|
-
constructor kwarg: when provided, the
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
default Athena template is applied as today.
|
|
136
|
+
constructor kwarg: when provided, the SDK creates a normal Word
|
|
137
|
+
document asset through Agora's docx-studio bridge, then imports the
|
|
138
|
+
local `.docx` into that asset. Without `docx=`, the default Athena
|
|
139
|
+
template is applied as today.
|
|
145
140
|
- **`agora_base_url=`** is a transport-detail kwarg only required when
|
|
146
141
|
the SDK can't derive the agora host from `base_url` (or from
|
|
147
142
|
`$ATHENA_AGORA_BASE_URL`). The default substitution rule replaces
|
|
@@ -169,14 +164,14 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
169
164
|
When a path or stream IS supplied, the SDK cannot fulfill the
|
|
170
165
|
implied "write bytes to this target" contract, so the call raises
|
|
171
166
|
loudly rather than silently flushing — agents must use Olympus's
|
|
172
|
-
Export DOCX (which goes through the
|
|
167
|
+
Export DOCX (which goes through the DOCX Studio session that already
|
|
173
168
|
has the bytes) instead of expecting a local file.
|
|
174
169
|
|
|
175
170
|
- **`Document.track_revisions: bool`** — when `True`, all subsequent
|
|
176
171
|
mutations are recorded as tracked revisions instead of direct edits.
|
|
177
172
|
python-docx upstream has no top-level toggle (the closest is
|
|
178
173
|
hand-edited `<w:trackChanges/>` on `Document.settings.element`).
|
|
179
|
-
We expose this as a Document-level property because every
|
|
174
|
+
We expose this as a Document-level property because every DOCX Studio
|
|
180
175
|
mutation accepts a per-call `changeMode` envelope field. The
|
|
181
176
|
python-docx-parity alias `Document.settings.track_revisions` reads
|
|
182
177
|
and writes the same flag so call sites that walk `doc.settings`
|
|
@@ -189,10 +184,10 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
189
184
|
because the upstream package has no track-changes API at all.
|
|
190
185
|
|
|
191
186
|
- **`Document.user_name: str | None` / `Document.user_email: str |
|
|
192
|
-
None`** — author identity threaded through to
|
|
187
|
+
None`** — author identity threaded through to DOCX Studio on session-
|
|
193
188
|
open for tracked-change attribution. python-docx's
|
|
194
189
|
`Document.core_properties.last_modified_by` is the closest upstream
|
|
195
|
-
surface; we use the
|
|
190
|
+
surface; we use the DOCX Studio-native fields directly because DOCX Studio
|
|
196
191
|
bakes them into the change records.
|
|
197
192
|
|
|
198
193
|
- **`Document.revisions: Revisions`** — collection of tracked changes
|
|
@@ -200,7 +195,7 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
200
195
|
`accept(id)`, `reject(id)`. Per-revision `Revision.accept()` /
|
|
201
196
|
`Revision.reject()` resolve a single change. python-docx upstream
|
|
202
197
|
has zero track-changes API, so this entire surface is an Athena
|
|
203
|
-
extension wired to
|
|
198
|
+
extension wired to DOCX Studio's `doc.trackChanges.{list,get,decide}`.
|
|
204
199
|
|
|
205
200
|
### Athena extensions for most-requested upstream features (v0.11.0+)
|
|
206
201
|
|
|
@@ -218,7 +213,7 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
218
213
|
tooltip=None) -> Hyperlink`** — appends a hyperlinked run.
|
|
219
214
|
python-docx surfaces `Hyperlink` as read-only; PR #74 has been open
|
|
220
215
|
since 2014 and is the single most-requested missing feature. Routes
|
|
221
|
-
through `CreateHyperlink` (
|
|
216
|
+
through `CreateHyperlink` (DOCX Studio `doc.hyperlinks.create`). Returns
|
|
222
217
|
the same `Hyperlink` class the read path already exposes. Also
|
|
223
218
|
available as `Run.add_hyperlink` for convenience.
|
|
224
219
|
|
|
@@ -298,7 +293,7 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
298
293
|
metadata. python-docx PR #1530 is in flight but unreleased; the
|
|
299
294
|
feature has been requested for years. Routes through
|
|
300
295
|
`SetImageAltText` / `SetImageDecorative` (already wired in
|
|
301
|
-
|
|
296
|
+
DOCX Studio).
|
|
302
297
|
|
|
303
298
|
- **`InlineShape.anchor(*, wrap="square", position_x_pt=,
|
|
304
299
|
position_y_pt=, relative_from_x=, relative_from_y=,
|
|
@@ -375,13 +370,13 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
375
370
|
include_revisions=False) -> bytes`** — render to PDF via the
|
|
376
371
|
Daytona-hosted LibreOffice. python-docx issue #113 was closed as
|
|
377
372
|
wontfix upstream but the request keeps recurring. Routes through
|
|
378
|
-
`ExportPDF` (
|
|
373
|
+
`ExportPDF` (DOCX Studio handles the actual conversion).
|
|
379
374
|
|
|
380
375
|
- **`Document.clear()`** (0.14.0+) — empty the document body so subsequent
|
|
381
376
|
writes start from a clean slate. python-docx has no equivalent (it
|
|
382
377
|
operates on local files where the caller can simply construct a new
|
|
383
378
|
``Document``). Iterates every top-level paragraph and table cell and
|
|
384
|
-
empties their text content. Block structure is preserved (
|
|
379
|
+
empties their text content. Block structure is preserved (DOCX Studio has
|
|
385
380
|
no wire op to delete blocks today), so post-clear the doc holds N
|
|
386
381
|
empty paragraphs rather than collapsing to a single one — for a truly
|
|
387
382
|
empty body, call ``Document.create()`` to mint a fresh asset instead.
|
|
@@ -389,6 +384,69 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
389
384
|
cleanup loops, which left horizontal-rule and scratch-content artifacts
|
|
390
385
|
in the document during failed-run recoveries.
|
|
391
386
|
|
|
387
|
+
- **`Paragraph.add_citation(source, *, anchor=None, excerpt=None,
|
|
388
|
+
display_value=None) -> str`** + **`Paragraph.clear_citations()`** +
|
|
389
|
+
**`Document.add_citation(source, *, destination_anchor, anchor=None,
|
|
390
|
+
...)`** + **`Document.remove_citation(citation_id)`** (0.20.0+) —
|
|
391
|
+
SDK-native Athena citations. This is the programmatic equivalent of
|
|
392
|
+
the user selecting DOCX text and choosing "Use selection as citation
|
|
393
|
+
destination/source" in Olympus: it writes the canonical document
|
|
394
|
+
citation record into the document's ``citations`` Y.Array and applies
|
|
395
|
+
the citation-blue highlight to the destination paragraph/range. It is
|
|
396
|
+
not a live link and does not overwrite destination text.
|
|
397
|
+
|
|
398
|
+
Use citations as evidence, not as generic source mentions.
|
|
399
|
+
``Paragraph.add_citation(...)`` highlights the whole paragraph in Athena, so
|
|
400
|
+
make the destination unit match the evidence: a metric cell/table row for a
|
|
401
|
+
number, one short sentence for a claim, or one short paragraph only when the
|
|
402
|
+
same source supports the full paragraph. If only a few words or numbers in a
|
|
403
|
+
long paragraph are supported, split that claim into its own sentence,
|
|
404
|
+
paragraph, or table row before citing it. Do not add duplicate citations to
|
|
405
|
+
every rendered line when one citation on the semantic claim/table row is
|
|
406
|
+
sufficient.
|
|
407
|
+
Use a mention/reference instead when you only need to point at a related
|
|
408
|
+
source without claiming evidentiary support. For PDFs, prefer a tight page
|
|
409
|
+
text anchor or a page anchor with an ``excerpt`` containing the exact
|
|
410
|
+
phrase/number being supported, not just a broad section title.
|
|
411
|
+
|
|
412
|
+
Prefer a canonical citation string when the source/anchor is already known
|
|
413
|
+
as a Spaces URL, or when the source type is not modeled by the DOCX SDK
|
|
414
|
+
(video/audio time ranges, browser sessions, external URLs, etc.). Typed
|
|
415
|
+
``AssetReference`` + anchor objects are still useful convenience helpers for
|
|
416
|
+
common Athena assets such as spreadsheets and PDFs, but they are not the only
|
|
417
|
+
valid source form.
|
|
418
|
+
|
|
419
|
+
Common agent pattern after writing a supported claim:
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
from docx import Document
|
|
423
|
+
from docx._references import AssetReference, SheetRangeAnchor
|
|
424
|
+
|
|
425
|
+
doc = Document("asset_word")
|
|
426
|
+
p = doc.add_paragraph("The combined assessment identified 20,049 total vulnerabilities.")
|
|
427
|
+
|
|
428
|
+
# Preferred generic path: pass a canonical Spaces URL or https URL.
|
|
429
|
+
citation_id = p.add_citation(
|
|
430
|
+
"/dashboard/spaces/?asset_ids=asset_spreadsheet&type=spreadsheet"
|
|
431
|
+
"&anchor=sheet_range&sheet_id=0&range=B2%3AB8",
|
|
432
|
+
excerpt="20,049 total vulnerabilities",
|
|
433
|
+
display_value="Vulnerability total",
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
# Typed helper path: still fine when the SDK has the source/anchor dataclasses.
|
|
437
|
+
citation_id = p.add_citation(
|
|
438
|
+
AssetReference(id="asset_spreadsheet"),
|
|
439
|
+
anchor=SheetRangeAnchor(sheet_id=0, range="B2:B8"),
|
|
440
|
+
excerpt="20,049 total vulnerabilities",
|
|
441
|
+
display_value="Vulnerability total",
|
|
442
|
+
)
|
|
443
|
+
doc.save()
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
Use ``Document.add_citation(..., destination_anchor=PmNodeAnchor(...))``
|
|
447
|
+
only when you already have a DOCX editor anchor id. For normal writing,
|
|
448
|
+
cite the ``Paragraph`` proxy you just created or found.
|
|
449
|
+
|
|
392
450
|
- **`Document.export_docx(path=None, *, include_revisions=False)
|
|
393
451
|
-> bytes`** (0.11.4+) — export the document's current state as
|
|
394
452
|
``.docx`` bytes, optionally writing to ``path``. Closes the gap
|
|
@@ -397,16 +455,13 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
397
455
|
harnesses and CI workflows need a programmatic .docx export to
|
|
398
456
|
diff against ``python-docx`` output that doesn't require a
|
|
399
457
|
human-driven Olympus UI action. Routes through ``ExportDocx`` →
|
|
400
|
-
apps/api
|
|
401
|
-
recommended backend export path per the SuperDoc team — Document
|
|
402
|
-
API, not the browser-side ``editor.exportDocx`` shim). apps/api
|
|
458
|
+
apps/api's backend export path. apps/api
|
|
403
459
|
writes the session state to a temp ``.docx``, reads bytes back,
|
|
404
460
|
base64-encodes for the wire, and unlinks the temp in a
|
|
405
461
|
``finally`` block. The SDK decodes and writes to ``path``.
|
|
406
462
|
``include_revisions=True`` raises ``DocxError`` pre-flight:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
through ``doc.save({out})``.
|
|
463
|
+
the current backend export path has no ``includeRevisions`` support,
|
|
464
|
+
so honoring the flag isn't possible yet.
|
|
410
465
|
|
|
411
466
|
Template seeding: ``Document.create()`` (no ``docx=``) already
|
|
412
467
|
produces an exportable asset because ``POST /docs/empty`` seeds
|
|
@@ -420,7 +475,7 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
420
475
|
Format ops on cell-inner paragraphs (`paragraph.alignment`,
|
|
421
476
|
`paragraph.style`, every `paragraph_format` setter, and
|
|
422
477
|
`paragraph.add_hyperlink`) used to cascade-fail the entire HTTP
|
|
423
|
-
batch.
|
|
478
|
+
batch. The current docx-editor applier's
|
|
424
479
|
``SetParagraphAlignment``/``SetParagraphStyle``/``SetParagraphIndentation``/``SetParagraphSpacing``/``CreateHyperlink``
|
|
425
480
|
reject cell-inner block targets with ``BlockNotFoundError``, and the
|
|
426
481
|
applier's all-or-nothing batch model meant one cell-paragraph
|
|
@@ -434,7 +489,7 @@ instead of forwarding the broken command. The format op is dropped,
|
|
|
434
489
|
the surrounding batch survives, and the workaround pointer (
|
|
435
490
|
``cell.text = 'value'`` to materialize, then ``cell.paragraphs[0]``
|
|
436
491
|
for the addressable proxy) is in the warning text. Tracked at
|
|
437
|
-
``docx-studio/
|
|
492
|
+
``docx-studio/DOCX_STUDIO_LIMITATIONS.md`` § 13.
|
|
438
493
|
|
|
439
494
|
**0.11.5 follow-up: post-export OOXML rewrite.** When the parent
|
|
440
495
|
table was created via ``Document.add_table`` in this session
|
|
@@ -444,7 +499,7 @@ OOXML-shaped props (``alignment``, ``style``, ``left_twips``,
|
|
|
444
499
|
:class:`docx._postproc.PostExportOps` collector). ``Document.export_docx``
|
|
445
500
|
applies them via an OOXML rewrite of ``word/document.xml`` before
|
|
446
501
|
returning bytes — so the **exported ``.docx`` carries the formatting
|
|
447
|
-
the agent asked for** even though
|
|
502
|
+
the agent asked for** even though DOCX Studio never accepted the wire
|
|
448
503
|
op. Live-session state is unchanged (Olympus collaborators don't
|
|
449
504
|
see the formatting until export). Template-seeded tables where
|
|
450
505
|
``_doc_index`` is ``None`` still warn-and-skip (no stable OOXML
|
|
@@ -463,7 +518,7 @@ helper pattern —
|
|
|
463
518
|
|
|
464
519
|
— used to silently drop both the ``Hello world`` text AND the bold
|
|
465
520
|
format because ``Paragraph.add_run`` on a cell-inner paragraph
|
|
466
|
-
returned a stub Run with collapsed range, and
|
|
521
|
+
returned a stub Run with collapsed range, and the docx-editor applier
|
|
467
522
|
rejected the wire-level ``doc.insert`` against the cell-inner
|
|
468
523
|
paragraph's blockId with ``Block <id> not found``. The 0.13.0 fix
|
|
469
524
|
adds a ``_cell`` back-reference to every cell-inner Paragraph proxy
|
|
@@ -473,7 +528,7 @@ called on a cell-inner paragraph with non-empty text AND the
|
|
|
473
528
|
back-ref is set, the SDK ships ``doc.insert(target=cell,
|
|
474
529
|
placement="insideEnd", content=paragraph-fragment-with-text)``
|
|
475
530
|
instead — the SAME wire path ``_Cell.add_paragraph(text)`` already
|
|
476
|
-
uses.
|
|
531
|
+
uses. DOCX Studio collapses the new paragraph into the cell's single
|
|
477
532
|
template paragraph as an inline run; the exported DOCX expands each
|
|
478
533
|
non-empty inline run into its own ``<w:p>``. The returned Run is
|
|
479
534
|
real (non-collapsed range) and carries the new exported-paragraph
|
|
@@ -500,10 +555,10 @@ of dropping it silently at the wire layer. The post-export rewrite
|
|
|
500
555
|
walks every ``<w:r>`` in the targeted cell paragraph and injects
|
|
501
556
|
``<w:rPr>`` carrying the props — so ``cell.text = "Total"; cell.
|
|
502
557
|
paragraphs[0].runs[0].bold = True`` produces a bold ``Total`` in
|
|
503
|
-
the exported ``.docx`` even though
|
|
558
|
+
the exported ``.docx`` even though DOCX Studio never committed the
|
|
504
559
|
format wire op. Apply-to-all-runs semantics: the rewrite targets
|
|
505
560
|
every ``<w:r>`` in the cell paragraph, because run-level addressing
|
|
506
|
-
inside a cell isn't recoverable after
|
|
561
|
+
inside a cell isn't recoverable after DOCX Studio collapses cell-
|
|
507
562
|
inner inserts. Multi-run cell paragraphs with partial-run
|
|
508
563
|
formatting are a documented limitation — agents should use one
|
|
509
564
|
run per format intent.
|
|
@@ -526,7 +581,7 @@ rels entry so the rels file doesn't grow unboundedly. Behavior
|
|
|
526
581
|
pinned by ``tests/test_postproc_cell_run_format_rewrite.py``.
|
|
527
582
|
|
|
528
583
|
Live Olympus rendering still won't show cell-inner formatting or
|
|
529
|
-
hyperlinks until
|
|
584
|
+
hyperlinks until DOCX Studio lands the corresponding wire ops —
|
|
530
585
|
``Document.export_docx`` is the source of truth for the
|
|
531
586
|
deliverable until then.
|
|
532
587
|
|
|
@@ -541,7 +596,7 @@ deliverable until then.
|
|
|
541
596
|
workaround pointer and avoids re-issuing the slow query.
|
|
542
597
|
- **`Table._fresh_node_info` rotation tracking.** Each ``Table``
|
|
543
598
|
created via ``Document.add_table`` records its document-order
|
|
544
|
-
position as ``_doc_index``. When
|
|
599
|
+
position as ``_doc_index``. When DOCX Studio rotates the table's
|
|
545
600
|
nodeId between saves, the fallback resolves the rotated address
|
|
546
601
|
by position instead of always picking the last ``doc.find`` item.
|
|
547
602
|
Pre-0.11.4 the "take the last" heuristic silently mapped N
|
|
@@ -560,18 +615,18 @@ deliverable until then.
|
|
|
560
615
|
every other field kind) now emits ``at.segments`` with
|
|
561
616
|
``[{blockId, start, end}]`` instead of the ``{kind: "selection",
|
|
562
617
|
start, end}`` cursor envelope used by other create-ops.
|
|
563
|
-
|
|
564
|
-
``
|
|
618
|
+
DOCX Studio's ``doc.fields.insert`` rejects the cursor form with
|
|
619
|
+
``DocxStudioCommandError: fields insert:at.segments is required``;
|
|
565
620
|
pre-0.11.4 the call took down the whole batch on every flush.
|
|
566
621
|
|
|
567
622
|
### 0.11.5 — `REF` field round-trip preservation (post-export rewrite)
|
|
568
623
|
|
|
569
|
-
|
|
624
|
+
The DOCX editor import/export path can strip ``REF`` field codes
|
|
570
625
|
(``<w:fldChar>`` / ``<w:instrText REF …>`` / result-runs / end
|
|
571
626
|
``<w:fldChar>``) on import. On the Paul Weiss Purchase Agreement
|
|
572
627
|
this loses all 301 cross-references — readers see chains of empty
|
|
573
628
|
commas instead of "Section 3.02(b)" cross-refs. Tracked at
|
|
574
|
-
``docx-studio/
|
|
629
|
+
``docx-studio/DOCX_STUDIO_LIMITATIONS.md`` § 18.
|
|
575
630
|
|
|
576
631
|
As of 0.11.5, ``Document.create(docx=template.docx)`` scans the
|
|
577
632
|
local template bytes with a stdlib zipfile + xml.etree parser and
|
|
@@ -590,7 +645,7 @@ same Python process that called ``Document.create(docx=...)`` also
|
|
|
590
645
|
calls ``export_docx``. Cross-process flows (agent A creates, agent
|
|
591
646
|
B exports) need agora-side persistence (separate follow-up). (2)
|
|
592
647
|
Paragraph-wholesale replacement preserves the source paragraph but
|
|
593
|
-
overwrites any
|
|
648
|
+
overwrites any DOCX Studio in-paragraph edits — for round-trip
|
|
594
649
|
preservation (the primary use case) this is exactly right. (3) Only
|
|
595
650
|
top-level body paragraphs are scanned; cell-inner REFs aren't
|
|
596
651
|
captured (rare for legal cross-references).
|
|
@@ -619,9 +674,9 @@ routing, `add_picture` native size + aspect ratio, `WD_BUILTIN_STYLE`
|
|
|
619
674
|
and `CoreProperties` validation. These are not deviations — they close
|
|
620
675
|
gaps. The items below are the **residual intentional deviations** that
|
|
621
676
|
remain because matching upstream would break the asset-backed/HTTP
|
|
622
|
-
architecture or a
|
|
677
|
+
architecture or a DOCX Studio constraint:
|
|
623
678
|
|
|
624
|
-
- **`WD_*` enum `.value` is the
|
|
679
|
+
- **`WD_*` enum `.value` is the DOCX Studio wire string, not the MS Word
|
|
625
680
|
integer constant.** `WD_ALIGN_PARAGRAPH.CENTER.value == "center"`
|
|
626
681
|
(upstream: `1`); `int(member)` / `member == 1` / `WD_*(1)` therefore
|
|
627
682
|
differ. The string value is load-bearing — every command serializes
|
|
@@ -637,7 +692,7 @@ architecture or a SuperDoc constraint:
|
|
|
637
692
|
stripped before the (otherwise byte-identical) upstream slice parse.
|
|
638
693
|
A strict superset — every value upstream accepts parses identically.
|
|
639
694
|
|
|
640
|
-
- **`_Cell.vertical_alignment` setter accepts the four
|
|
695
|
+
- **`_Cell.vertical_alignment` setter accepts the four DOCX Studio wire
|
|
641
696
|
tokens** (`"top"`/`"center"`/`"bottom"`/`"both"`) in addition to
|
|
642
697
|
`WD_ALIGN_VERTICAL` members. Upstream rejects all plain strings; this
|
|
643
698
|
is an ergonomic superset (typos like `"middle"` still raise
|
|
@@ -661,19 +716,19 @@ architecture or a SuperDoc constraint:
|
|
|
661
716
|
|
|
662
717
|
- **`Document.add_table(rows, cols)` requires `rows >= 1` and
|
|
663
718
|
`cols >= 1`.** Upstream allows a 0-row/0-col grid you later populate,
|
|
664
|
-
but
|
|
719
|
+
but DOCX Studio's ProseMirror table node can't represent one; the SDK
|
|
665
720
|
raises eagerly rather than failing opaquely on the wire.
|
|
666
721
|
|
|
667
|
-
- **`Comment.comment_id` returns `str`, not `int`.**
|
|
722
|
+
- **`Comment.comment_id` returns `str`, not `int`.** DOCX Studio uses
|
|
668
723
|
non-numeric entity ids (`"c-42"`), so the upstream `int` contract
|
|
669
|
-
can't be honored. Tracked in `
|
|
724
|
+
can't be honored. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
|
|
670
725
|
|
|
671
726
|
- **`Section` dimension setters and `ParagraphFormat.line_spacing_rule
|
|
672
727
|
= None` warn-and-preserve on a clear** rather than raising (upstream
|
|
673
|
-
accepts `None` to clear, but
|
|
728
|
+
accepts `None` to clear, but DOCX Studio's merging mutation ops have no
|
|
674
729
|
single-attribute clear). They emit a `Pending…ClearWarning` and leave
|
|
675
730
|
the value intact instead of destructively clearing the whole block.
|
|
676
|
-
Tracked in `
|
|
731
|
+
Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
|
|
677
732
|
|
|
678
733
|
### If you need a deviation
|
|
679
734
|
|
|
@@ -699,13 +754,13 @@ This is a **thin HTTP client** that mimics the sync python-docx API.
|
|
|
699
754
|
(a `SessionError`) carrying `http_status` and an optional
|
|
700
755
|
`retry_after_seconds` parsed from the server's `Retry-After` header.
|
|
701
756
|
Agent code can catch this typed error to back off at the agent level
|
|
702
|
-
vs. treating it as a script bug. The
|
|
703
|
-
(embedded
|
|
704
|
-
0.5.0; agent pods no longer embed
|
|
757
|
+
vs. treating it as a script bug. The former `transport="direct"`
|
|
758
|
+
(embedded DOCX Studio CLI + y-websocket from Python) was removed in
|
|
759
|
+
0.5.0; agent pods no longer embed DOCX Studio.
|
|
705
760
|
- **Transparent batching (0.7.0+):** Create* commands
|
|
706
761
|
(`CreateParagraph`, `CreateHeading`, `CreateTable`, `CreateImage`)
|
|
707
762
|
ALWAYS pre-mint a client-side UUID (`client_node_id`) and defer
|
|
708
|
-
through the buffer. The applier resolves UUIDs to real
|
|
763
|
+
through the buffer. The applier resolves UUIDs to real DOCX Studio
|
|
709
764
|
ids via per-batch `clientIdMap` on flush, and the buffer rewrites
|
|
710
765
|
each proxy's `_node_id` in-place. Net result: 30 `add_paragraph`
|
|
711
766
|
calls = 1 HTTP request, with no explicit `batch()` context manager
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# DocX Execution Lab
|
|
2
2
|
|
|
3
3
|
`scripts/docx_exec_lab.py` is a headless runner for quickly testing
|
|
4
|
-
`athena-python-docx` snippets against Athena
|
|
4
|
+
`athena-python-docx` snippets against Athena Word document assets. It
|
|
5
5
|
shortens the debug loop by running local SDK code directly against a
|
|
6
6
|
chosen DOCX Studio API, capturing stdout/stderr/errors/timings, and
|
|
7
7
|
optionally exporting the result to `.docx` for assertions.
|
|
@@ -85,10 +85,10 @@ uv run python scripts/docx_exec_lab.py \
|
|
|
85
85
|
--export-docx
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
## Local UI With
|
|
88
|
+
## Local UI With DOCX Editor Embed
|
|
89
89
|
|
|
90
90
|
The lab also includes a local-only HTML UI that wraps the same headless
|
|
91
|
-
runner and iframes Olympus's existing
|
|
91
|
+
runner and iframes Olympus's existing DOCX editor embed route.
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
94
|
cd docx-studio/python-sdk
|
|
@@ -107,7 +107,7 @@ Defaults:
|
|
|
107
107
|
The UI accepts an `asset_id`, Python code, and optional assertions. The
|
|
108
108
|
right pane can mint an editable embed token through staging Agora and
|
|
109
109
|
iframe the returned `https://staging-app.athenaintel.com/embed/{token}`
|
|
110
|
-
URL, so changes render in the real Olympus
|
|
110
|
+
URL, so changes render in the real Olympus DOCX editor viewer.
|
|
111
111
|
|
|
112
112
|
If the staging Agora URL differs, pass:
|
|
113
113
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Drop-in replacement for python-docx that connects to Athena's
|
|
3
|
+
Version: 0.21.1
|
|
4
|
+
Summary: Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack
|
|
5
5
|
Project-URL: Homepage, https://athenaintelligence.ai
|
|
6
6
|
Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
|
|
7
7
|
License-Expression: MIT
|
|
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Requires-Python: >=3.11
|
|
14
|
+
Requires-Dist: athena-references>=0.1.0
|
|
14
15
|
Requires-Dist: requests>=2.28
|
|
15
16
|
Requires-Dist: urllib3>=1.26.6
|
|
16
17
|
Provides-Extra: dev
|
|
@@ -20,14 +21,11 @@ Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
|
20
21
|
Requires-Dist: python-docx>=1.1; extra == 'dev'
|
|
21
22
|
Requires-Dist: responses>=0.24; extra == 'dev'
|
|
22
23
|
Requires-Dist: ruff>=0.3; extra == 'dev'
|
|
23
|
-
Provides-Extra: fidelity
|
|
24
|
-
Requires-Dist: httpx>=0.27; extra == 'fidelity'
|
|
25
|
-
Requires-Dist: superdoc-sdk>=1.8.0; extra == 'fidelity'
|
|
26
24
|
Description-Content-Type: text/markdown
|
|
27
25
|
|
|
28
26
|
# athena-python-docx
|
|
29
27
|
|
|
30
|
-
Drop-in replacement for [python-docx](https://python-docx.readthedocs.io/) that connects to Athena's
|
|
28
|
+
Drop-in replacement for [python-docx](https://python-docx.readthedocs.io/) that connects to Athena's Keryx-backed Word document stack.
|
|
31
29
|
|
|
32
30
|
## Quick start
|
|
33
31
|
|
|
@@ -35,7 +33,7 @@ Drop-in replacement for [python-docx](https://python-docx.readthedocs.io/) that
|
|
|
35
33
|
from docx import Document
|
|
36
34
|
from docx.shared import Inches, Pt, RGBColor
|
|
37
35
|
|
|
38
|
-
# Open an existing
|
|
36
|
+
# Open an existing Word document asset by its Athena asset_id
|
|
39
37
|
with Document("asset_abc123") as doc:
|
|
40
38
|
doc.add_heading("Market Analysis", level=1)
|
|
41
39
|
|
|
@@ -74,15 +72,14 @@ headless runner in `scripts/docx_exec_lab.py`. It executes an arbitrary
|
|
|
74
72
|
Python snippet with this checkout of `athena-python-docx`, captures
|
|
75
73
|
stdout/stderr/errors/timings, and can export the resulting `.docx` for
|
|
76
74
|
text assertions. `scripts/docx_exec_lab_server.py` adds a local UI with
|
|
77
|
-
an Olympus
|
|
75
|
+
an Olympus Word document embed preview pane. See `DOCX_EXEC_LAB.md`.
|
|
78
76
|
|
|
79
77
|
## Environment variables
|
|
80
78
|
|
|
81
|
-
Required when connecting to
|
|
79
|
+
Required when connecting to DOCX Studio (set by Athena backend when executing in Daytona):
|
|
82
80
|
|
|
83
|
-
- `
|
|
84
|
-
- `
|
|
85
|
-
- `ATHENA_WORKSPACE_ID` — workspace routing segment
|
|
81
|
+
- `ATHENA_DOCX_BASE_URL` — DOCX Studio API base URL
|
|
82
|
+
- `ATHENA_DOCX_API_KEY` — Athena API key or service-issued DOCX Studio token
|
|
86
83
|
|
|
87
84
|
## License
|
|
88
85
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# athena-python-docx
|
|
2
2
|
|
|
3
|
-
Drop-in replacement for [python-docx](https://python-docx.readthedocs.io/) that connects to Athena's
|
|
3
|
+
Drop-in replacement for [python-docx](https://python-docx.readthedocs.io/) that connects to Athena's Keryx-backed Word document stack.
|
|
4
4
|
|
|
5
5
|
## Quick start
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ Drop-in replacement for [python-docx](https://python-docx.readthedocs.io/) that
|
|
|
8
8
|
from docx import Document
|
|
9
9
|
from docx.shared import Inches, Pt, RGBColor
|
|
10
10
|
|
|
11
|
-
# Open an existing
|
|
11
|
+
# Open an existing Word document asset by its Athena asset_id
|
|
12
12
|
with Document("asset_abc123") as doc:
|
|
13
13
|
doc.add_heading("Market Analysis", level=1)
|
|
14
14
|
|
|
@@ -47,15 +47,14 @@ headless runner in `scripts/docx_exec_lab.py`. It executes an arbitrary
|
|
|
47
47
|
Python snippet with this checkout of `athena-python-docx`, captures
|
|
48
48
|
stdout/stderr/errors/timings, and can export the resulting `.docx` for
|
|
49
49
|
text assertions. `scripts/docx_exec_lab_server.py` adds a local UI with
|
|
50
|
-
an Olympus
|
|
50
|
+
an Olympus Word document embed preview pane. See `DOCX_EXEC_LAB.md`.
|
|
51
51
|
|
|
52
52
|
## Environment variables
|
|
53
53
|
|
|
54
|
-
Required when connecting to
|
|
54
|
+
Required when connecting to DOCX Studio (set by Athena backend when executing in Daytona):
|
|
55
55
|
|
|
56
|
-
- `
|
|
57
|
-
- `
|
|
58
|
-
- `ATHENA_WORKSPACE_ID` — workspace routing segment
|
|
56
|
+
- `ATHENA_DOCX_BASE_URL` — DOCX Studio API base URL
|
|
57
|
+
- `ATHENA_DOCX_API_KEY` — Athena API key or service-issued DOCX Studio token
|
|
59
58
|
|
|
60
59
|
## License
|
|
61
60
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""athena-python-docx — drop-in replacement for python-docx.
|
|
2
2
|
|
|
3
|
-
Calls translate into
|
|
3
|
+
Calls translate into DOCX Studio SDK operations against a Keryx Y.Doc.
|
|
4
4
|
See CLAUDE.md for the API parity contract.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
__version__ = "0.
|
|
9
|
+
__version__ = "0.21.1"
|
|
10
10
|
|
|
11
11
|
from docx.api import Document
|
|
12
12
|
from docx._buffer import flush_all
|
|
@@ -8,7 +8,7 @@ ships as one HTTP request instead of N.
|
|
|
8
8
|
Create* commands are deferred because the SDK pre-mints a client-side
|
|
9
9
|
UUID for every new node (see ``Document._mint_client_node_id``). The
|
|
10
10
|
proxy returned to the caller is stamped with that UUID; the applier
|
|
11
|
-
resolves UUIDs to real
|
|
11
|
+
resolves UUIDs to real DOCX Studio ids via ``clientIdMap`` and echoes the
|
|
12
12
|
mapping back, at which point the buffer rewrites each proxy's
|
|
13
13
|
``_node_id``. This makes batching invisible at the call site — user
|
|
14
14
|
code looks like python-docx, runs at python-docx-batched speed.
|
|
@@ -49,7 +49,7 @@ def _apply_proxy_id_rewrites(
|
|
|
49
49
|
proxy_id_refs: "dict[str, list[tuple[object, str]]]",
|
|
50
50
|
) -> None:
|
|
51
51
|
"""Walk ``results`` and rewrite registered proxy ids from client UUIDs
|
|
52
|
-
to the real
|
|
52
|
+
to the real DOCX Studio ids the applier echoed back.
|
|
53
53
|
|
|
54
54
|
Shared by the success path in :meth:`CommandBuffer.flush` /
|
|
55
55
|
:meth:`_eager_flush_with` AND by the **partial-failure recovery
|
|
@@ -287,7 +287,7 @@ class CommandBuffer:
|
|
|
287
287
|
|
|
288
288
|
Create* commands defer because the SDK pre-mints a client-side UUID
|
|
289
289
|
(``client_node_id`` / ``client_entity_id``); the applier translates
|
|
290
|
-
the UUID to a real
|
|
290
|
+
the UUID to a real DOCX Studio id in a per-batch ``clientIdMap`` and
|
|
291
291
|
echoes the mapping back so the SDK can rewrite each proxy's
|
|
292
292
|
``_node_id`` on flush.
|
|
293
293
|
"""
|
|
@@ -385,7 +385,7 @@ class CommandBuffer:
|
|
|
385
385
|
def set_user(self, name: str | None, email: str | None = None) -> None:
|
|
386
386
|
"""Set the batch-level user identity.
|
|
387
387
|
|
|
388
|
-
Sent on every commands request envelope.
|
|
388
|
+
Sent on every commands request envelope. DOCX Studio honors the
|
|
389
389
|
identity at session-open time only — subsequent batches against
|
|
390
390
|
a pooled session ignore the value, but the payload is still
|
|
391
391
|
included so a fresh session picks it up.
|
|
@@ -415,7 +415,7 @@ class CommandBuffer:
|
|
|
415
415
|
``client_entity_id`` — appends to the queue, resets the idle
|
|
416
416
|
timer, and returns ``None``. Caller MUST NOT rely on the return
|
|
417
417
|
value of a buffered mutation. For deferred Creates, the
|
|
418
|
-
applier resolves the client UUID to a real
|
|
418
|
+
applier resolves the client UUID to a real DOCX Studio id via
|
|
419
419
|
``clientIdMap`` on flush and the buffer rewrites each registered
|
|
420
420
|
proxy's ``_node_id`` in-place.
|
|
421
421
|
"""
|