athena-python-docx 0.25.0__tar.gz → 0.27.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.25.0 → athena_python_docx-0.27.0}/AGENTS.md +274 -76
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/PKG-INFO +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/__init__.py +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_http_doc.py +23 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_image_utils.py +95 -22
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_postproc.py +102 -141
- athena_python_docx-0.27.0/docx/blkcntnr.py +58 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/client.py +3 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/commands.py +157 -12
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/comments.py +135 -53
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/document.py +82 -88
- athena_python_docx-0.27.0/docx/drawing/__init__.py +60 -0
- athena_python_docx-0.27.0/docx/enum/base.py +151 -0
- athena_python_docx-0.27.0/docx/enum/dml.py +42 -0
- athena_python_docx-0.27.0/docx/enum/section.py +59 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/enum/style.py +13 -23
- athena_python_docx-0.27.0/docx/enum/table.py +68 -0
- athena_python_docx-0.27.0/docx/enum/text.py +241 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/errors.py +18 -0
- athena_python_docx-0.27.0/docx/image/__init__.py +5 -0
- athena_python_docx-0.27.0/docx/image/exceptions.py +13 -0
- athena_python_docx-0.27.0/docx/image/image.py +153 -0
- athena_python_docx-0.27.0/docx/opc/coreprops.py +253 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/section.py +224 -193
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/shape.py +62 -66
- athena_python_docx-0.27.0/docx/styles/_table.py +596 -0
- athena_python_docx-0.27.0/docx/styles/latent.py +220 -0
- athena_python_docx-0.27.0/docx/styles/style.py +923 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/styles/styles.py +78 -93
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/table.py +238 -262
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/hyperlink.py +9 -3
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/paragraph.py +344 -81
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/parfmt.py +12 -7
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/run.py +414 -204
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/tabstops.py +18 -65
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/pyproject.toml +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/release.sh +2 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/fake_session.py +82 -15
- athena_python_docx-0.27.0/tests/fidelity/op_snapshots/104_core_properties_datetime.json +21 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/17_table_basic.json +1 -0
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/45_cell_text_round_trip.json → athena_python_docx-0.27.0/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +1 -0
- athena_python_docx-0.27.0/tests/fidelity/op_snapshots/28_section_add_new.json +3 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +2 -1
- athena_python_docx-0.27.0/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +8 -0
- athena_python_docx-0.27.0/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +5 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -4
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +2 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -5
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -8
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/68_invoice.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/69_newsletter.json +2 -5
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -4
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +1 -0
- athena_python_docx-0.27.0/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +12 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +15 -120
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +1 -0
- athena_python_docx-0.27.0/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +35 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +12 -24
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw11_header_text.json +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +2 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +2 -0
- athena_python_docx-0.27.0/tests/fixtures/field_reads.json +863 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/README.md +4 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/intentional_deviations.json +14 -24
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/test_parity_gap.py +32 -11
- athena_python_docx-0.27.0/tests/test_add_section.py +206 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_athena_extensions_registry.py +1 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_fastpath_runs.py +35 -3
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_format_stash.py +8 -0
- athena_python_docx-0.27.0/tests/test_cell_merge.py +443 -0
- athena_python_docx-0.27.0/tests/test_cell_paragraphs_listed.py +234 -0
- athena_python_docx-0.27.0/tests/test_cell_text_replace_semantics.py +76 -0
- athena_python_docx-0.27.0/tests/test_color_format_theme.py +134 -0
- athena_python_docx-0.27.0/tests/test_comments.py +436 -0
- athena_python_docx-0.27.0/tests/test_core_properties.py +191 -0
- athena_python_docx-0.27.0/tests/test_drawing_image.py +267 -0
- athena_python_docx-0.27.0/tests/test_enum_parity.py +449 -0
- athena_python_docx-0.27.0/tests/test_field_reads_python_docx_parity.py +105 -0
- athena_python_docx-0.27.0/tests/test_field_runs.py +386 -0
- athena_python_docx-0.27.0/tests/test_inline_shape_size.py +58 -0
- athena_python_docx-0.27.0/tests/test_missing_modules.py +238 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_page_break.py +31 -0
- athena_python_docx-0.27.0/tests/test_paragraph_runs_hyperlinks.py +85 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_parity_round2.py +54 -36
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_phase_a_behavior.py +10 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_phase_b_headers_footers.py +282 -3
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_postproc_cell_format_rewrite.py +75 -154
- athena_python_docx-0.27.0/tests/test_restart_numbering.py +207 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_revisions.py +38 -0
- athena_python_docx-0.27.0/tests/test_run_formatting_wire.py +154 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_run_identity.py +8 -2
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_run_mark_inheritance.py +52 -13
- athena_python_docx-0.27.0/tests/test_run_table_style_objects.py +329 -0
- athena_python_docx-0.27.0/tests/test_run_text_python_docx.py +190 -0
- athena_python_docx-0.27.0/tests/test_run_text_refreshes_paragraph.py +60 -0
- athena_python_docx-0.27.0/tests/test_sdk_reads_served.py +191 -0
- athena_python_docx-0.27.0/tests/test_section_read_lengths.py +91 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_add_picture.py +9 -11
- athena_python_docx-0.27.0/tests/test_silent_stub_enum_section.py +54 -0
- athena_python_docx-0.27.0/tests/test_silent_stub_inline_shape.py +73 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_misc.py +7 -14
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_paragraph_strict.py +13 -9
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_parfmt.py +44 -13
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_row_col_cell.py +3 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_underline.py +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_section_dimensions.py +43 -8
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_style.py +13 -11
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_audit.py +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_layout.py +1 -1
- athena_python_docx-0.27.0/tests/test_style_formatting_writes.py +290 -0
- athena_python_docx-0.27.0/tests/test_style_metadata_writes.py +276 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_names.py +85 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_setters_contract.py +11 -14
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_table_style_id_resolution.py +4 -2
- athena_python_docx-0.27.0/tests/test_text_control_characters.py +233 -0
- athena_python_docx-0.27.0/tests/test_uv_lock_version.py +23 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_wire_contract.py +121 -10
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/uv.lock +1 -1
- athena_python_docx-0.25.0/docx/enum/section.py +0 -72
- athena_python_docx-0.25.0/docx/enum/table.py +0 -52
- athena_python_docx-0.25.0/docx/enum/text.py +0 -258
- athena_python_docx-0.25.0/docx/opc/coreprops.py +0 -248
- athena_python_docx-0.25.0/docx/styles/_table.py +0 -303
- athena_python_docx-0.25.0/docx/styles/style.py +0 -611
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -1
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -9
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/28_section_add_new.json +0 -5
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -1
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -32
- athena_python_docx-0.25.0/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -34
- athena_python_docx-0.25.0/tests/test_cell_text_replace_semantics.py +0 -116
- athena_python_docx-0.25.0/tests/test_comments.py +0 -238
- athena_python_docx-0.25.0/tests/test_silent_stub_enum_section.py +0 -83
- athena_python_docx-0.25.0/tests/test_silent_stub_inline_shape.py +0 -105
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/.gitignore +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/CLAUDE.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/DOCX_EXEC_LAB.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/README.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_buffer.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_citations.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_execution.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_http.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_references.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_run_order.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/_timeouts.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/api.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/bookmarks.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/charts.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/enum/shape.py +1 -1
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/fields.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/footnotes.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/math.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/oxml/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/sdt.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/session.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/settings.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/shared.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/text/pagebreak.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/toc.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/docx/typing.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/dump_wire_fixtures.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/smoke_test_block_not_found.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/scripts/validate_find_replace_asset.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/METHODOLOGY.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/ab_probe_cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/README.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/_runner.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/extractor.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/reports/gap_report.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/snapshots/athena_latest.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_add_section_extract_items.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_athena_extension_creates_session_open.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_block_not_found_error.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_add_table_not_supported.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_borders_spec.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_run_format_stash.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_inner_run_guard.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_cell_text_plain_fastpath.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_citations.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_collapsed_range_format.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_clear.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_create.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_create_from_template.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_document_factory_validation.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_docx_exec_lab.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_execution_scope.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_find_replace_session_open.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_http_transport.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_hyperlink_coalescing.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_image_url_data_uri.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_inline_shape_alt_text.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_list_styles.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_merged_cell_secondary_slot.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_parity_misc.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_pdf_export_and_page_renders.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_positional_cell_id.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_postproc_ref_restore.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_run_add_picture_anchor.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_header_footer.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_style.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_style_strict.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_run_text.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_section_onoff.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_table_set_cell_perf.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_validate_find_replace_asset_script.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_xml_attr_guard.py +0 -0
- {athena_python_docx-0.25.0 → athena_python_docx-0.27.0}/tests/test_zod_wire_contract.py +0 -0
|
@@ -31,14 +31,14 @@ 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
|
-
- `Document.core_properties.last_modified_by` — we use Keryx attribution instead
|
|
35
34
|
- `Document.settings` — Word app settings (not surfaced by DOCX Studio)
|
|
36
35
|
- `InlineShape.chart` — charts are not currently surfaced by the SDK.
|
|
37
36
|
- `Comment.add_paragraph` / `Comment.add_table` /
|
|
38
37
|
`Comment.iter_inner_content` / `Comment.paragraphs` /
|
|
39
|
-
`Comment.tables` — DOCX Studio models a comment as a single text body
|
|
40
|
-
|
|
41
|
-
paragraph/table-bearing surface raises
|
|
38
|
+
`Comment.tables` — DOCX Studio models a comment as a single text body.
|
|
39
|
+
`Comment` is a `docx.blkcntnr.BlockItemContainer`, as `_Cell` and the
|
|
40
|
+
header/footer proxies are, but its paragraph/table-bearing surface raises
|
|
41
|
+
`CommentsNotImplementedError`. Use `Comment.text` instead.
|
|
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
|
|
@@ -71,18 +71,41 @@ runtime, pending additional docx-editor command support. Behavior should be
|
|
|
71
71
|
pinned by focused tests and documented in
|
|
72
72
|
`docx-studio/DOCX_STUDIO_LIMITATIONS.md`.
|
|
73
73
|
|
|
74
|
-
- **
|
|
75
|
-
(`name`, `
|
|
76
|
-
`unhide_when_used`, `base_style`,
|
|
77
|
-
`
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
`
|
|
85
|
-
|
|
74
|
+
- **Style setters on `BaseStyle` / `CharacterStyle` / `ParagraphStyle`.**
|
|
75
|
+
The metadata setters (`name`, `hidden`, `locked`, `priority`,
|
|
76
|
+
`quick_style`, `unhide_when_used`, `base_style`,
|
|
77
|
+
`next_paragraph_style`) write the style's definition
|
|
78
|
+
(`SetStyleMetadata`), `Styles.add_style` adds one (`CreateStyle`), and
|
|
79
|
+
a paragraph or character style's formatting (`style.font.*`,
|
|
80
|
+
`style.paragraph_format.*`) is written too (`SetStyleFormatting`); each
|
|
81
|
+
reads back from the style table, whose `metadata` / `font` /
|
|
82
|
+
`paragraphFormat` entries are the capability signal
|
|
83
|
+
(`tests/test_style_metadata_writes.py`,
|
|
84
|
+
`tests/test_style_formatting_writes.py`). `style_id`, `delete()`, a
|
|
85
|
+
table style's formatting and base, a style's tab stops, and every style write on
|
|
86
|
+
a docx-studio without that signal emit `PendingStyleMutationWarning`
|
|
87
|
+
(or its paragraph-format / registry variant) and stash on
|
|
88
|
+
`_overrides` (`tests/test_style_setters_contract.py`).
|
|
89
|
+
- **A picture is a run, and `Run.iter_inner_content()` yields its
|
|
90
|
+
`docx.drawing.Drawing`.** As python-docx reads a `w:r` holding a
|
|
91
|
+
`w:drawing`, `Paragraph.runs` and `iter_inner_content()` hold a run with
|
|
92
|
+
text `""` for each picture (docx-studio reports it as a
|
|
93
|
+
`{drawing: {imageId}}` inline), and a linked picture is a run of its
|
|
94
|
+
`Hyperlink`. `run.text = ...` and `run.clear()` on a picture run remove the
|
|
95
|
+
picture with its text (`Replace` with `removePictures`). The drawing's
|
|
96
|
+
`has_picture` is True and its `image` is a `docx.image.image.Image` read
|
|
97
|
+
through `ImagesGet` (python-docx's `blob`, `content_type`, `px_width`,
|
|
98
|
+
`horz_dpi`, `width`, `scaled_dimensions`, …). A picture in a table cell or
|
|
99
|
+
a header has no id to read its image by, so `.image` raises `ValueError`;
|
|
100
|
+
an older docx-studio does not report pictures, so they are not runs there.
|
|
101
|
+
- **`Styles.latent_styles`** (`docx.styles.latent.LatentStyles`) reads
|
|
102
|
+
the document's `<w:latentStyles>` (defaults and each `w:lsdException`)
|
|
103
|
+
from docx-studio's `Info` (`includeStyles` → `latentStyles`), as python-docx
|
|
104
|
+
reads them. Writing them is not supported: a setter, `add_latent_style`
|
|
105
|
+
and `_LatentStyle.delete` emit `PendingLatentStylesWriteWarning` and
|
|
106
|
+
change nothing. A docx-studio that predates the read (or a document
|
|
107
|
+
without a source copy) reads as empty, with
|
|
108
|
+
`PendingLatentStylesReadWarning`.
|
|
86
109
|
|
|
87
110
|
### Intentional deviations (additions / different semantics)
|
|
88
111
|
|
|
@@ -100,31 +123,36 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
100
123
|
URIs. Local paths and file-like streams behave exactly as upstream.
|
|
101
124
|
The dispatch lives in ``docx._image_utils.load_image_bytes``; a failed
|
|
102
125
|
fetch/decode raises a ``ValueError`` at the call site rather than a
|
|
103
|
-
bare transport error.
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
bare transport error. The resulting bytes go through the same
|
|
127
|
+
signature check as upstream: a stream that is no PNG, JPEG, GIF, BMP or
|
|
128
|
+
TIFF (nor, beyond python-docx, WebP or SVG) raises
|
|
129
|
+
``docx.image.exceptions.UnrecognizedImageError`` whatever its file name,
|
|
130
|
+
where it used to land as a 6" x 4.5" guess
|
|
131
|
+
(``docx._image_utils.image_content_type``).
|
|
106
132
|
|
|
107
133
|
- **Built-in table style friendly names resolve to OOXML styleIds.**
|
|
108
134
|
Word's ``styles.xml`` ships built-in table styles whose styleIds
|
|
109
135
|
(``LightGrid-Accent1``, ``MediumShading1-Accent2``, …) differ from
|
|
110
|
-
their display names (``"Light Grid Accent 1"``, …).
|
|
111
|
-
|
|
112
|
-
document's
|
|
113
|
-
``
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
their display names (``"Light Grid Accent 1"``, …). Like python-docx,
|
|
137
|
+
``Document.add_table(style=...)`` / the ``Table.style`` setter resolve
|
|
138
|
+
a name through the document's style table (docx-studio ``Info``) and
|
|
139
|
+
raise ``KeyError`` for a name it lacks — except a Word built-in table
|
|
140
|
+
style docx-studio holds Word's definition of (python-docx's default
|
|
141
|
+
template: Table Grid, Light Shading … Colorful Grid and their accents),
|
|
142
|
+
which resolves through an in-process map
|
|
143
|
+
(``docx._table_styles.BUILTIN_TABLE_STYLE_IDS``) when the document does
|
|
144
|
+
not define it: the editor draws it from that definition and the export
|
|
145
|
+
adds the definition to ``styles.xml``, as Word does when the style is
|
|
146
|
+
applied. A Word 2013+ table style (Grid Table, List Table, Plain Table)
|
|
147
|
+
the document lacks raises ``KeyError``, as in python-docx, whose
|
|
148
|
+
template defines none. Against a docx-studio that sends no table every
|
|
149
|
+
built-in name (Word 2007 and 2013+, 204 entries) is sent as its id, and
|
|
150
|
+
custom names pass through unchanged. ``Document.add_table`` with no
|
|
151
|
+
style keeps Athena's brand table look (direct cell borders and zebra
|
|
152
|
+
fill, no ``w:tblStyle``) where python-docx's table has none; a style
|
|
153
|
+
set on the table replaces that look, and borders and fills set on its
|
|
154
|
+
cells stay. ``table.style = None`` removes an existing table's style as
|
|
155
|
+
python-docx does (``DOCX_STUDIO_LIMITATIONS.md`` § 25).
|
|
128
156
|
|
|
129
157
|
- **`Document.create(name=, base_url=, api_key=, parent_folder_id=, workspace_id=, docx=, agora_base_url=)`**
|
|
130
158
|
classmethod. Stock python-docx returns a blank in-memory document
|
|
@@ -185,10 +213,10 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
185
213
|
|
|
186
214
|
- **`Document.user_name: str | None` / `Document.user_email: str |
|
|
187
215
|
None`** — author identity threaded through to DOCX Studio on session-
|
|
188
|
-
open for tracked-change attribution
|
|
189
|
-
`Document.core_properties.last_modified_by
|
|
190
|
-
|
|
191
|
-
|
|
216
|
+
open for tracked-change attribution; DOCX Studio bakes them into the
|
|
217
|
+
change records. Separate from `Document.core_properties.last_modified_by`,
|
|
218
|
+
the `docProps/core.xml` metadata the SDK reads and writes as python-docx
|
|
219
|
+
does.
|
|
192
220
|
|
|
193
221
|
- **`Document.revisions: Revisions`** — collection of tracked changes
|
|
194
222
|
with iteration, `get(id)`, `accept_all()`, `reject_all()`,
|
|
@@ -196,6 +224,26 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
196
224
|
`Revision.reject()` resolve a single change. python-docx upstream
|
|
197
225
|
has zero track-changes API, so this entire surface is an Athena
|
|
198
226
|
extension wired to DOCX Studio's `doc.trackChanges.{list,get,decide}`.
|
|
227
|
+
A run's tracked formatting change (`w:rPrChange`) and a paragraph's
|
|
228
|
+
(`w:pPrChange`) are `"format"` revisions; `reject()` gives the run or
|
|
229
|
+
paragraph exactly the earlier properties the change recorded
|
|
230
|
+
(`tests/test_revisions.py`, docx-studio's
|
|
231
|
+
`tracked-run-property-changes.test.ts`).
|
|
232
|
+
|
|
233
|
+
- **Style writes refuse what would write a broken document.** python-docx
|
|
234
|
+
writes these into `styles.xml`; the SDK raises before anything is sent,
|
|
235
|
+
because the result would be a document Word cannot resolve
|
|
236
|
+
(`tests/test_style_metadata_writes.py`):
|
|
237
|
+
- `Styles.add_style` raises `ValueError` for a style id the document
|
|
238
|
+
already has (a name without the space, `"Heading1"`, derives the id
|
|
239
|
+
of the existing Heading 1), where python-docx appends a second
|
|
240
|
+
definition of that id;
|
|
241
|
+
- `base_style = ` a style whose `basedOn` chain reaches this one (itself
|
|
242
|
+
included) raises `ValueError`, where python-docx writes a chain Word
|
|
243
|
+
refuses;
|
|
244
|
+
- `priority = True` raises `TypeError`, where python-docx (to which a
|
|
245
|
+
`bool` is an `int`) writes `w:uiPriority w:val="True"`, not a
|
|
246
|
+
number; any other non-`int` raises `TypeError` in both.
|
|
199
247
|
|
|
200
248
|
### Athena extensions for most-requested upstream features (v0.11.0+)
|
|
201
249
|
|
|
@@ -287,7 +335,10 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
287
335
|
python-docx surfaces `_Cell.grid_span` (horizontal) but the
|
|
288
336
|
vertical merge state and master detection are issue #1312, #1434,
|
|
289
337
|
#1458. Pure derived properties from existing `tables.getCells`
|
|
290
|
-
data
|
|
338
|
+
data: docx-studio reports `vMerge` for the grid position asked
|
|
339
|
+
about (`"restart"` on the merged cell's first row, `"continue"`
|
|
340
|
+
below it), while `text`, `grid_span` and writes resolve to the
|
|
341
|
+
merged cell from any position it covers.
|
|
291
342
|
|
|
292
343
|
- **`Table.add_row(*, copy_format_from=None)`** — when `copy_format_from`
|
|
293
344
|
is provided (int row index or `_Row`), the new row inherits height,
|
|
@@ -373,6 +424,30 @@ Issue numbers reference `python-openxml/python-docx`.
|
|
|
373
424
|
numbering reads. python-docx issue #471 (13 👍) demands access to
|
|
374
425
|
list metadata. Routes through `NumberingGet`.
|
|
375
426
|
|
|
427
|
+
- **`Paragraph.restart_numbering(start=1)`** (0.26.0+) — restart the
|
|
428
|
+
paragraph's numbered list at `start`, as Word's "Restart at 1" does
|
|
429
|
+
("Set Numbering Value" for another start). All `"List Number"`
|
|
430
|
+
paragraphs share one numbering, as in Word and python-docx, so a list
|
|
431
|
+
after a heading or table counts on (3, 4) until restarted. python-docx
|
|
432
|
+
has no way to restart a list: issue #25, open since 2014. Routes
|
|
433
|
+
through `ListsSplit` (`restartNumbering: true`, `start`), sent in a
|
|
434
|
+
request of its own after the buffered edits. docx-studio adds a `w:num`
|
|
435
|
+
on the list's `w:abstractNum` whose
|
|
436
|
+
`<w:lvlOverride w:ilvl="N"><w:startOverride w:val="start"/>` (ECMA-376
|
|
437
|
+
§17.9.27) starts the paragraph's level, and points the paragraph and the
|
|
438
|
+
later items of its `w:num` at it: up to the next item of a shallower
|
|
439
|
+
level, the next list restarted on its own, or the end of the document.
|
|
440
|
+
Headings, tables, body text and other lists between the items do not
|
|
441
|
+
end the list, because Word counts across them. A header or footer
|
|
442
|
+
paragraph restarts within its part, whose paragraphs count on their own.
|
|
443
|
+
The same restart again changes nothing. A paragraph that takes no number (plain, heading,
|
|
444
|
+
bullet) raises `docx.errors.NotNumberedListItemError` (a `ValueError`);
|
|
445
|
+
`start` outside 0..32767 raises `ValueError`; a docx-studio API without
|
|
446
|
+
the handler raises `DocxUnsupportedCommandError`. The new `w:num` lives
|
|
447
|
+
in the source package, so each restart stores the package again (one
|
|
448
|
+
copy in the room's history) until #41656 item 7's writers store it by
|
|
449
|
+
reference.
|
|
450
|
+
|
|
376
451
|
- **`Document.to_pdf(*, quality=None, destination=None,
|
|
377
452
|
include_revisions=False) -> bytes`** — render to PDF. python-docx
|
|
378
453
|
issue #113 was closed as
|
|
@@ -752,28 +827,35 @@ gaps. The items below are the **residual intentional deviations** that
|
|
|
752
827
|
remain because matching upstream would break the asset-backed/HTTP
|
|
753
828
|
architecture or a DOCX Studio constraint:
|
|
754
829
|
|
|
755
|
-
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
`
|
|
760
|
-
`
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
830
|
+
- **Enum-typed setters also take the member's DOCX Studio string.** The
|
|
831
|
+
`WD_*` / `MSO_*` enums are python-docx's (`docx.enum.base.BaseEnum` /
|
|
832
|
+
`BaseXmlEnum`): every member is its MS API int
|
|
833
|
+
(`WD_ALIGN_PARAGRAPH.CENTER == 1`, `str()` is `"CENTER (1)"`), XML
|
|
834
|
+
enums carry `xml_value` and `from_xml`/`to_xml`, and the aliases are
|
|
835
|
+
upstream's (`WD_ALIGN_PARAGRAPH is WD_PARAGRAPH_ALIGNMENT`,
|
|
836
|
+
`WD_BREAK.TEXT_WRAPPING is WD_BREAK.LINE_CLEAR_ALL`). Setters take a
|
|
837
|
+
member or its int value as upstream does; they additionally accept the
|
|
838
|
+
string DOCX Studio's commands carry for a member (`"center"`, `"wavy"`,
|
|
839
|
+
the `w:` XML value, …) where upstream rejects strings. The SDK sends
|
|
840
|
+
`member.to_docx_studio()` and reads with `from_docx_studio()`, never
|
|
841
|
+
`.value`. Members DOCX Studio can't apply are sent as their closest
|
|
842
|
+
value with `PendingEnumCoercionWarning` (distributed / kashida / Thai
|
|
843
|
+
justification → `"justify"`; `LIST`/`CLEAR`/`END`/`NUM`/`START` tabs →
|
|
844
|
+
`"left"`); `WD_ALIGN_VERTICAL.BOTH` goes as `"center"`. `INHERITED`
|
|
845
|
+
raises `ValueError` ("has no XML representation") as upstream's
|
|
846
|
+
`to_xml` does, and a bool is its int value (`True` is the member valued
|
|
847
|
+
1), as upstream reads it. `Table.alignment`
|
|
848
|
+
reads as `WD_TABLE_ALIGNMENT` and takes its three members (upstream
|
|
849
|
+
reads the equal `WD_PARAGRAPH_ALIGNMENT` member and takes any of its
|
|
850
|
+
values), and `Table.table_direction` reads as `WD_TABLE_DIRECTION`
|
|
851
|
+
(upstream: the equal bool). `WD_BUILTIN_STYLE` members carry no
|
|
852
|
+
per-member docstring.
|
|
765
853
|
|
|
766
854
|
- **`RGBColor.from_string` additionally accepts a leading `#`.** Upstream
|
|
767
855
|
rejects `"#FF0000"`; agents routinely pass it, so a single `#` is
|
|
768
856
|
stripped before the (otherwise byte-identical) upstream slice parse.
|
|
769
857
|
A strict superset — every value upstream accepts parses identically.
|
|
770
858
|
|
|
771
|
-
- **`_Cell.vertical_alignment` setter accepts the four DOCX Studio wire
|
|
772
|
-
tokens** (`"top"`/`"center"`/`"bottom"`/`"both"`) in addition to
|
|
773
|
-
`WD_ALIGN_VERTICAL` members. Upstream rejects all plain strings; this
|
|
774
|
-
is an ergonomic superset (typos like `"middle"` still raise
|
|
775
|
-
`ValueError`).
|
|
776
|
-
|
|
777
859
|
- **`Table.cell(row, col)` bounds-checks each axis independently** and
|
|
778
860
|
raises `IndexError` for an out-of-range row or column. Upstream
|
|
779
861
|
indexes a single flat row-major `_cells` list, so a column overflow
|
|
@@ -783,35 +865,151 @@ architecture or a DOCX Studio constraint:
|
|
|
783
865
|
cheaply enumerate every cell. `(0,0)` and in-range negative indices
|
|
784
866
|
behave identically to upstream.
|
|
785
867
|
|
|
786
|
-
- **Unknown paragraph style names raise only when
|
|
787
|
-
|
|
788
|
-
name (`"Heading 1"`), `.style_id` the id (`"Heading1"`), read from
|
|
789
|
-
document's style table (docx-studio `Info` with `includeStyles`,
|
|
790
|
-
once per session in `docx/styles/_table.py`). A style set by name
|
|
791
|
-
is sent as the document's id, and an unstyled paragraph reads as the
|
|
868
|
+
- **Unknown paragraph style names raise only when docx-studio has no
|
|
869
|
+
definition for them.** Style names and ids follow python-docx: `.name` is
|
|
870
|
+
the UI name (`"Heading 1"`), `.style_id` the id (`"Heading1"`), read from
|
|
871
|
+
the document's style table (docx-studio `Info` with `includeStyles`,
|
|
872
|
+
fetched once per session in `docx/styles/_table.py`). A style set by name
|
|
873
|
+
or id is sent as the document's id, and an unstyled paragraph reads as the
|
|
792
874
|
default paragraph style. `paragraph.style = …` raises `KeyError` for a
|
|
793
|
-
name the document defines no style for, like python-docx — except
|
|
794
|
-
built-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
875
|
+
name the document defines no style for, like python-docx — except the
|
|
876
|
+
Word built-ins docx-studio holds a definition of
|
|
877
|
+
(`BUILTIN_PARAGRAPH_STYLE_NAMES`: `"Heading 4"`, `"List Bullet"`,
|
|
878
|
+
`"Footnote Text"`, `"TOC 1"`…), which many templates never write into
|
|
879
|
+
`styles.xml` until used. Those are sent by their Word id; the paragraph
|
|
880
|
+
holds `w:pStyle` alone, the editor paints it from that definition and
|
|
881
|
+
the export adds the definition (with a list of the document's own for a
|
|
882
|
+
numbered list style), as Word does when the style is applied. Heading 1–9,
|
|
883
|
+
Title, Subtitle, Quote, Intense Quote, List Paragraph, No Spacing and
|
|
884
|
+
Caption are defined by hand to current Word's definitions
|
|
885
|
+
(`packages/core/src/prosemirror/styles/latentBuiltInStyles.ts`); the
|
|
886
|
+
others are python-docx's default template's, and docx4j's
|
|
887
|
+
`KnownStyles.xml` (Word 2007) for the ones it lacks
|
|
888
|
+
(`packages/core/src/docx/builtInStyles.generated.ts`). `"List Bullet 4"`/
|
|
889
|
+
`"5"` and `"List Number 4"`/`"5"` raise `KeyError`: python-docx's template
|
|
890
|
+
holds no numbering for them. Against an older docx-studio (no style table)
|
|
891
|
+
a built-in name is sent as its id and anything else as given.
|
|
892
|
+
`Run.style` follows the same rule for character styles: it returns a
|
|
893
|
+
`CharacterStyle` (Default Paragraph Font for a run naming none), and a
|
|
894
|
+
name the document lacks raises `KeyError` unless docx-studio holds Word's
|
|
895
|
+
definition of it (`BUILTIN_CHARACTER_STYLE_NAMES` in
|
|
896
|
+
`docx/styles/_table.py`: `"Strong"`, `"Intense Emphasis"`, `"Book Title"`…).
|
|
897
|
+
`Document.add_table(style=)` and `Paragraph.add_run(style=)` resolve the
|
|
898
|
+
style before creating anything, so a rejected style leaves the document
|
|
899
|
+
untouched; python-docx raises after adding the table or run to its
|
|
900
|
+
in-memory tree, but an edit here is live.
|
|
799
901
|
|
|
800
902
|
- **`Document.add_table(rows, cols)` requires `rows >= 1` and
|
|
801
903
|
`cols >= 1`.** Upstream allows a 0-row/0-col grid you later populate,
|
|
802
904
|
but DOCX Studio's ProseMirror table node can't represent one; the SDK
|
|
803
905
|
raises eagerly rather than failing opaquely on the wire.
|
|
804
906
|
|
|
907
|
+
- **`_Cell.merge` raises `InvalidSpanError` for every span that would cut
|
|
908
|
+
through a merged cell.** It merges what python-docx merges and refuses
|
|
909
|
+
what python-docx refuses (an L- or T-shaped pair of corners), but where
|
|
910
|
+
a cell inside the rectangle crosses its edge python-docx sometimes
|
|
911
|
+
raises `ValueError` (no `w:tc` at the rectangle's left edge) or writes a
|
|
912
|
+
vertical merge Word reads as broken. docx-studio applies the merge, so
|
|
913
|
+
`merge()` sends a request of its own and raises at the call.
|
|
914
|
+
|
|
915
|
+
- **`core_properties.modified` follows saves that change the package.**
|
|
916
|
+
`doc.core_properties` reads and writes `docProps/core.xml` as python-docx
|
|
917
|
+
does (docx-studio `Info` with `includeCoreProperties`, `SetCoreProperties`;
|
|
918
|
+
`DOCX_STUDIO_LIMITATIONS.md` § 8), but docx-studio stamps `modified` with
|
|
919
|
+
the time of a save that changes the package, a core property included, as
|
|
920
|
+
Word does, where python-docx never stamps it. A `modified` the script sets
|
|
921
|
+
wins in the save that writes it (a later save in the same batch stamps
|
|
922
|
+
again). Every read asks docx-studio, which saves the batch's edits before it
|
|
923
|
+
answers, so a read sees the stamp, and a collaborator's save. A package
|
|
924
|
+
without `docProps/core.xml` reads
|
|
925
|
+
every property as missing, where python-docx adds its own default part
|
|
926
|
+
(title "Word Document", last modified by "python-docx").
|
|
927
|
+
|
|
805
928
|
- **`Comment.comment_id` returns `str`, not `int`.** DOCX Studio uses
|
|
806
929
|
non-numeric entity ids (`"c-42"`), so the upstream `int` contract
|
|
807
930
|
can't be honored. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
|
|
808
931
|
|
|
809
|
-
- **`
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
the
|
|
814
|
-
|
|
932
|
+
- **`add_comment` without an `author` stores the session's name, not
|
|
933
|
+
`""`.** `Document.add_comment` / `Comments.add_comment` send `author`
|
|
934
|
+
and `initials` and docx-studio stores them as `w:author` /
|
|
935
|
+
`w:initials`, as python-docx does; with none (python-docx's default
|
|
936
|
+
`""`) the author is `Document.user_name`, else `"Athena"`, and no
|
|
937
|
+
initials are stored (`initials` then reads `None`). The SDK raises
|
|
938
|
+
`ValueError` for what lxml refuses in an attribute, as python-docx
|
|
939
|
+
does, and also past docx-studio's caps (255 UTF-16 code units for an
|
|
940
|
+
author, 32 for initials); docx-studio turns tabs, line breaks and other
|
|
941
|
+
control characters into spaces. The author is display text only:
|
|
942
|
+
Keryx attributes the edit to the signed-in user (and agent), and
|
|
943
|
+
nothing reads a comment's author as identity.
|
|
944
|
+
|
|
945
|
+
- **`ParagraphFormat.line_spacing_rule = None` warns-and-preserves on a
|
|
946
|
+
clear** rather than raising (upstream accepts `None` to clear, but DOCX
|
|
947
|
+
Studio's merging mutation ops have no single-attribute clear). It emits a
|
|
948
|
+
`Pending…ClearWarning` and leaves the value intact instead of
|
|
949
|
+
destructively clearing the whole block. The `Section` dimension setters
|
|
950
|
+
remove the attribute for `None`, as upstream does (`null` on the wire),
|
|
951
|
+
on a docx-studio whose section read reports `clearsDimensions`; on an
|
|
952
|
+
older one they warn (`PendingSectionDimensionClearWarning`) and keep the
|
|
953
|
+
value. Tracked in `DOCX_STUDIO_LIMITATIONS.md`.
|
|
954
|
+
|
|
955
|
+
- **`Run.text` / `Paragraph.text` read Word's run elements as upstream
|
|
956
|
+
does** (`-` for a non-breaking hyphen, nothing for a soft hyphen or a
|
|
957
|
+
symbol; `\t` for a `w:ptab` in a room that holds it as a tab), but a tab or
|
|
958
|
+
break of an imported run can read as a run of its own. Writes keep text as
|
|
959
|
+
given. `Run.add_tab()` and `Run.add_break()` take the run's formatting, as
|
|
960
|
+
upstream appends them to the run's `w:r`; `Run.add_break(WD_BREAK.COLUMN)`
|
|
961
|
+
sends a column break (`breakType: "column"`), which docx-studio writes after
|
|
962
|
+
the paragraph's content. `DOCX_STUDIO_LIMITATIONS.md` §26.
|
|
963
|
+
|
|
964
|
+
- **Tracked changes read as Word's final view.** `Paragraph.text`, `runs`,
|
|
965
|
+
`iter_inner_content()`, `Hyperlink.text` / `runs` and `_Cell.text` include
|
|
966
|
+
the runs of a tracked insertion (`w:ins`) and leave out a deletion's
|
|
967
|
+
(`w:del`); upstream omits both, as it reads only a `w:p`'s direct `w:r` and
|
|
968
|
+
`w:hyperlink` children. Upstream cannot write tracked changes, so it has no
|
|
969
|
+
write-then-read case to match; with `track_revisions` on (the Athena
|
|
970
|
+
extension), `with doc.tracked_revisions(): p.text = "Updated forecast"`
|
|
971
|
+
deletes the old text and inserts the new, and upstream's omission would
|
|
972
|
+
read the paragraph back as `""`. Word's default views (Simple Markup, No
|
|
973
|
+
Markup) show insertions and hide deletions, as these reads do.
|
|
974
|
+
`doc.revisions` lists every change (`tests/test_run_text_python_docx.py`).
|
|
975
|
+
|
|
976
|
+
- **A field's runs read as python-docx reads them; some writes to them
|
|
977
|
+
differ.** `Paragraph.text` includes a complex field's displayed result and
|
|
978
|
+
`Paragraph.runs` holds its begin, field code, separate, result and end runs
|
|
979
|
+
(each with its own formatting), as python-docx reads the `w:r` children of
|
|
980
|
+
a `w:p`; a simple field (`w:fldSimple`) reads as nothing, and a field in a
|
|
981
|
+
link is the link's, as in python-docx. Each paragraph of a field that spans
|
|
982
|
+
paragraphs (a table of contents) holds the field character runs it has
|
|
983
|
+
(`tests/test_field_reads_python_docx_parity.py`, against stock python-docx
|
|
984
|
+
on the same `.docx`; `DOCX_STUDIO_LIMITATIONS.md` § 27). A field takes no
|
|
985
|
+
room in the text-address space, so its runs stand at one offset. Writes:
|
|
986
|
+
- setting a result run's `.text` changes the field's displayed result,
|
|
987
|
+
as in python-docx (`Replace` with a `field` target), but the export
|
|
988
|
+
writes a changed result of several runs as one run, in the first run's
|
|
989
|
+
formatting, and a result run read before the field's result changed
|
|
990
|
+
(through another read's run, or by a collaborator) raises
|
|
991
|
+
`FieldRunWriteError` rather than write over that change, where
|
|
992
|
+
python-docx's run is live;
|
|
993
|
+
- formatting a result run formats the field's whole result (`FormatApply`
|
|
994
|
+
with a `field` target), from its source formatting, where python-docx
|
|
995
|
+
formats that run alone;
|
|
996
|
+
- `.text` (and `clear()`) on a field character or field code run raises
|
|
997
|
+
`docx.errors.FieldRunWriteError` naming the field: python-docx replaces
|
|
998
|
+
the run's `w:fldChar` or `w:instrText` with the text, which breaks the
|
|
999
|
+
field;
|
|
1000
|
+
- formatting set on a field character or field code run is not applied and
|
|
1001
|
+
emits `PendingFieldRunFormatWarning` (those runs show nothing; docx-studio
|
|
1002
|
+
has no command that writes their own `w:rPr`), where python-docx writes
|
|
1003
|
+
it, so `for run in p.runs: run.bold = True` formats the text and the
|
|
1004
|
+
field's result and warns for the rest;
|
|
1005
|
+
- `add_text`, `add_tab`, `add_break`, `add_picture`, `add_field`,
|
|
1006
|
+
`add_footnote`, `add_endnote`, `add_math` and `add_cross_reference` on
|
|
1007
|
+
any of a field's runs raise `FieldRunWriteError`; python-docx appends to
|
|
1008
|
+
that `w:r`.
|
|
1009
|
+
A field that `Run.add_field` adds is a simple field, so it reads as no
|
|
1010
|
+
runs and no text, though docx-studio's export writes it as a complex field.
|
|
1011
|
+
Against a docx-studio that predates `fieldRun` reads, a field reads as no
|
|
1012
|
+
runs and no text, as before (`tests/test_field_runs.py`).
|
|
815
1013
|
|
|
816
1014
|
### If you need a deviation
|
|
817
1015
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack
|
|
5
5
|
Project-URL: Homepage, https://athenaintelligence.ai
|
|
6
6
|
Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
|
|
@@ -76,6 +76,7 @@ from docx.commands import (
|
|
|
76
76
|
CreateMath,
|
|
77
77
|
CreateParagraph,
|
|
78
78
|
CreateSectionBreak,
|
|
79
|
+
CreateStyle,
|
|
79
80
|
CreateTable,
|
|
80
81
|
CreateTOC,
|
|
81
82
|
CreateWatermark,
|
|
@@ -132,6 +133,7 @@ from docx.commands import (
|
|
|
132
133
|
SetCellShading,
|
|
133
134
|
SetChartData,
|
|
134
135
|
SetChartType,
|
|
136
|
+
SetCoreProperties,
|
|
135
137
|
SetImageAltText,
|
|
136
138
|
SetImageAnchor,
|
|
137
139
|
SetImageDecorative,
|
|
@@ -151,6 +153,8 @@ from docx.commands import (
|
|
|
151
153
|
SetSectionPageSetup,
|
|
152
154
|
SetSectionTitlePage,
|
|
153
155
|
SetSectionsOddEvenHeadersFooters,
|
|
156
|
+
SetStyleFormatting,
|
|
157
|
+
SetStyleMetadata,
|
|
154
158
|
SetTableBorders,
|
|
155
159
|
TablesGet,
|
|
156
160
|
TablesGetCells,
|
|
@@ -177,9 +181,11 @@ from docx.errors import (
|
|
|
177
181
|
DocxStudioTemporarilyUnavailable,
|
|
178
182
|
DocxUnsupportedCommandWarning,
|
|
179
183
|
NotFoundError,
|
|
184
|
+
NotNumberedListItemError,
|
|
180
185
|
SessionError,
|
|
181
186
|
_missing_block_id,
|
|
182
187
|
)
|
|
188
|
+
from docx.exceptions import InvalidSpanError
|
|
183
189
|
|
|
184
190
|
|
|
185
191
|
_NOT_FOUND_ERROR_NAMES: frozenset[str] = frozenset(
|
|
@@ -632,6 +638,17 @@ def _http_post_json(
|
|
|
632
638
|
err_obj = parsed.get("error") if isinstance(parsed, dict) else None
|
|
633
639
|
if isinstance(err_obj, dict):
|
|
634
640
|
base_msg = f"docx-studio batch reported a partial failure: {parsed!r}"
|
|
641
|
+
# A merge python-docx refuses (``_Cell.merge``) raises python-docx's
|
|
642
|
+
# own exception.
|
|
643
|
+
if err_obj.get("error") == "InvalidSpanError":
|
|
644
|
+
raise InvalidSpanError(
|
|
645
|
+
str(err_obj.get("message") or base_msg),
|
|
646
|
+
).with_partial_applied(partial_applied)
|
|
647
|
+
# ``Paragraph.restart_numbering`` on a paragraph that takes no number.
|
|
648
|
+
if err_obj.get("error") == "NotNumberedListItem":
|
|
649
|
+
raise NotNumberedListItemError(
|
|
650
|
+
str(err_obj.get("message") or base_msg),
|
|
651
|
+
).with_partial_applied(partial_applied)
|
|
635
652
|
# ``BlockNotFoundError`` is the narrower miss — caller is most
|
|
636
653
|
# likely targeting a cell-inner paragraph or stale-session
|
|
637
654
|
# block id. Surface the typed exception plus an agent-readable
|
|
@@ -1011,6 +1028,10 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
|
|
|
1011
1028
|
"format.paragraph.set_tab_stop": SetParagraphTabStop,
|
|
1012
1029
|
"format.paragraph.clear_all_tab_stops": ClearParagraphTabStops,
|
|
1013
1030
|
"styles.paragraph.set_style": SetParagraphStyle,
|
|
1031
|
+
"styles.set_formatting": SetStyleFormatting,
|
|
1032
|
+
"styles.set_metadata": SetStyleMetadata,
|
|
1033
|
+
"styles.create": CreateStyle,
|
|
1034
|
+
"core_properties.set": SetCoreProperties,
|
|
1014
1035
|
# Sections
|
|
1015
1036
|
"sections.set_page_margins": SetSectionPageMargins,
|
|
1016
1037
|
"sections.set_page_setup": SetSectionPageSetup,
|
|
@@ -1069,8 +1090,8 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
|
|
|
1069
1090
|
# consumed internally by ``Document.add_paragraph`` to make
|
|
1070
1091
|
# ``style="List Bullet" | "List Number"`` produce real list
|
|
1071
1092
|
# structure (not just a style attribute on a flat paragraph).
|
|
1072
|
-
# ``lists.
|
|
1073
|
-
#
|
|
1093
|
+
# ``lists.split`` backs the Athena extension
|
|
1094
|
+
# ``Paragraph.restart_numbering``; ``lists.merge`` stays typed-bus-only.
|
|
1074
1095
|
"lists.create": ListsCreate,
|
|
1075
1096
|
"lists.attach": ListsAttach,
|
|
1076
1097
|
"lists.merge": ListsMerge,
|