athena-python-docx 0.36.0__tar.gz → 0.38.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.36.0 → athena_python_docx-0.38.0}/PKG-INFO +1 -1
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/__init__.py +1 -1
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/commands.py +11 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/table.py +12 -1
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/run.py +109 -26
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/pyproject.toml +1 -1
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_drawing_image.py +56 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_enum_parity.py +14 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_ruby_reads_python_docx_parity.py +18 -2
- athena_python_docx-0.38.0/tests/test_run_break_inner_content.py +254 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_later_runs.py +91 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_mark_inheritance.py +35 -40
- athena_python_docx-0.38.0/tests/test_table_add_row_grid_row.py +65 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/uv.lock +1 -1
- athena_python_docx-0.36.0/tests/test_run_break_inner_content.py +0 -121
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/.gitignore +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/AGENTS.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/CLAUDE.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/DOCX_EXEC_LAB.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/README.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_buffer.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_capabilities.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_citations.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_execution.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_http.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_http_doc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_image_utils.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_postproc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_proxy.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_references.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_run_order.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_timeouts.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_tracked.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/_xml_text.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/api.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/blkcntnr.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/bookmarks.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/charts.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/client.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/comments.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/document.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/drawing/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/base.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/dml.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/section.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/shape.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/style.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/table.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/enum/text.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/errors.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/fields.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/footnotes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/image/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/image/exceptions.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/image/image.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/math.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/opc/coreprops.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/oxml/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/sdt.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/section.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/session.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/settings.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/shape.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/shared.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/styles/_table.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/styles/latent.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/styles/style.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/styles/styles.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/hyperlink.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/pagebreak.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/paragraph.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/parfmt.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/text/tabstops.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/toc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/docx/typing.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/docx_exec_lab.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/dump_wire_fixtures.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/release.sh +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/smoke_test_block_not_found.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/scripts/validate_find_replace_asset.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/METHODOLOGY.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/agent_documents.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/default_style_run_formatting.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/header_footer_pictures.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/less_used_writes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/merged_cell_identity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/paragraph_text_setter.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/picture_runs.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/proxy_equality.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/return_types.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/xml_incompatible_text.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe/zero_and_negative_indents.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/fake_session.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/firm_templates/README.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/firm_templates/_runner.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/firm_templates/extractor.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fixtures/field_reads.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fixtures/note_reference_reads.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fixtures/ruby_reads.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/fixtures/symbol_reads.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/baseline.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/fixture_scripts.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/reader.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/runner.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/sdk_driver.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/stock_driver.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/live/test_live_runner.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/README.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/intentional_deviations.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/reports/gap_report.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/snapshots/athena_latest.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_add_section.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_add_section_extract_items.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_alignment_values.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_athena_extension_creates_session_open.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_athena_extensions_registry.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_batch_chunking.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_battery_cases.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_block_not_found_error.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_add_table_not_supported.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_borders_spec.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_fastpath_runs.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_inner_format_stash.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_inner_run_format_stash.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_inner_run_guard.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_merge.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_nested_tables.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_paragraphs_listed.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_text_plain_fastpath.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_cell_text_replace_semantics.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_citations.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_collapsed_range_format.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_color_format_theme.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_comment_paragraphs.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_comments.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_comments_first_read.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_content_control_value.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_core_properties.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_document_clear.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_document_create.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_document_create_from_template.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_document_factory_validation.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_document_settings_session_open.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_docx_exec_lab.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_empty_hyperlinks.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_execution_scope.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_export_docx_clean.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_export_rescue_anchors.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_field_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_field_refresh.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_field_runs.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_find_replace_session_open.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_flushed_write_failures.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_http_transport.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_hyperlink_coalescing.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_image_url_data_uri.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_inline_page_break.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_inline_shape_alt_text.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_inline_shape_size.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_inline_shape_type.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_inline_shapes_floating.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_latent_style_writes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_line_clear_break.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_list_styles.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_merged_cell_identity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_merged_cell_secondary_slot.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_missing_modules.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_nested_table_refused.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_page_break.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_paragraph_delete.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_paragraph_indent_reads.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_paragraph_runs_hyperlinks.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_paragraph_text_empty_run.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_parfmt_clears.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_parity_misc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_parity_round2.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_pdf_export_and_page_renders.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_phase_a_behavior.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_phase_b_headers_footers.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_positional_cell_id.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_postproc_cell_format_rewrite.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_postproc_ref_restore.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_proxy_equality.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_read_run_ranges.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_rendered_page_breaks.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_repeated_node_read.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_restart_numbering.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_revisions.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_round_trip_smoke_script.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_add_picture_anchor.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_edges.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_formatting_wire.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_identity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_page_number_blocks.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_table_style_objects.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_text_python_docx.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_text_refreshes_paragraph.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_run_unmodeled_toggles.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_sdk_reads_served.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_section_read_lengths.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_enum_section.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_header_footer.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_inline_shape.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_misc.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_parfmt.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_row_col_cell.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_run_style.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_run_style_strict.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_run_text.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_run_underline.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_section_dimensions.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_section_onoff.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_style.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_silent_stub_table_layout.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_delete.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_formatting_writes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_metadata_writes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_names.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_setters_contract.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_tab_stops.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_style_tab_stops_read.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_symbol_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_tab_stop_writes.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_table_anchors.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_table_clears.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_table_direction.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_table_read_reuse.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_table_set_cell_perf.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_table_style_id_resolution.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_text_control_characters.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_tracked_revisions_offsets.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_unmapped_alignment_reads.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_uv_lock_version.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_validate_find_replace_asset_script.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_wire_contract.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_xml_attr_guard.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_xml_incompatible_text.py +0 -0
- {athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_zod_wire_contract.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.38.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>
|
|
@@ -565,10 +565,21 @@ class SetSectionLinkToPrevious(Command):
|
|
|
565
565
|
|
|
566
566
|
@dataclass
|
|
567
567
|
class TablesInsertRow(Command):
|
|
568
|
+
"""``grid_row`` is python-docx's ``Table.add_row()``: the row goes after
|
|
569
|
+
the table's last one, with a cell for each grid column as wide as the
|
|
570
|
+
column, holding one empty paragraph, and nothing of the rows above.
|
|
571
|
+
``copy_format_from`` is the Athena extension
|
|
572
|
+
``Table.add_row(copy_format_from=k)``: the row goes after the table's
|
|
573
|
+
last one, formatted as Word's Insert Row below row ``k`` formats it.
|
|
574
|
+
Without either, the row is Word's Insert Row next to ``row_index``. A
|
|
575
|
+
docx-studio that predates a field ignores it."""
|
|
576
|
+
|
|
568
577
|
node_id: str
|
|
569
578
|
row_index: int
|
|
570
579
|
position: str # "above" | "below"
|
|
571
580
|
count: int = 1
|
|
581
|
+
grid_row: bool | None = None
|
|
582
|
+
copy_format_from: int | None = None
|
|
572
583
|
|
|
573
584
|
|
|
574
585
|
@dataclass
|
|
@@ -1053,6 +1053,11 @@ class Table:
|
|
|
1053
1053
|
}
|
|
1054
1054
|
if source_index is not None:
|
|
1055
1055
|
params["copyFormatFrom"] = source_index
|
|
1056
|
+
else:
|
|
1057
|
+
# python-docx's row: a cell for each grid column, as wide as the
|
|
1058
|
+
# column, and nothing of the last row (its height, grid skips,
|
|
1059
|
+
# header flag or cell formatting).
|
|
1060
|
+
params["gridRow"] = True
|
|
1056
1061
|
run_sync(self._session.doc.tables.insert_row(params))
|
|
1057
1062
|
# Keep the bounds-check cache current so the next ``cell()``
|
|
1058
1063
|
# access still hits the fast path.
|
|
@@ -1235,7 +1240,13 @@ class Table:
|
|
|
1235
1240
|
self._session.doc.tables.get_properties({"nodeId": self._fresh_node_id()}),
|
|
1236
1241
|
)
|
|
1237
1242
|
if isinstance(info, dict):
|
|
1238
|
-
|
|
1243
|
+
raw: object = info.get("alignment")
|
|
1244
|
+
member = WD_PARAGRAPH_ALIGNMENT.from_docx_studio(raw)
|
|
1245
|
+
# python-docx reads `w:jc` through `from_xml`, which raises
|
|
1246
|
+
# ValueError for a value it has no member for (`start`, `end`).
|
|
1247
|
+
if member is None and isinstance(raw, str) and raw:
|
|
1248
|
+
return WD_PARAGRAPH_ALIGNMENT.from_xml(raw)
|
|
1249
|
+
return member
|
|
1239
1250
|
return None
|
|
1240
1251
|
|
|
1241
1252
|
@alignment.setter
|
|
@@ -454,11 +454,16 @@ class Run:
|
|
|
454
454
|
formatting, so the formatting waits for content the run takes. So
|
|
455
455
|
does a break the read says is no node of the paragraph
|
|
456
456
|
(``breakApart``): one only its source run holds, a column-break
|
|
457
|
-
block's, or the page break that opens the paragraph.
|
|
457
|
+
block's, or the page break that opens the paragraph. The paragraph's
|
|
458
|
+
closing page break run (``closingBreak``) is formatted where the
|
|
459
|
+
docx-studio reports ``capabilities.closingBreakRunFormat``, which puts
|
|
460
|
+
its breaks back in the paragraph to take it."""
|
|
458
461
|
if not self._is_collapsed_range or not self._holds_break() or tracking(self._session):
|
|
459
462
|
return None
|
|
460
463
|
if self._inline_snapshot.get("breakApart") is True:
|
|
461
|
-
|
|
464
|
+
closing = self._inline_snapshot.get("closingBreak") is True
|
|
465
|
+
if not closing or not server_takes(self._session, "closingBreakRunFormat"):
|
|
466
|
+
return None
|
|
462
467
|
if self._inline_snapshot.get("break") == "column" and not server_takes(self._session, "inlineColumnBreak"):
|
|
463
468
|
return None
|
|
464
469
|
return self._later_runs()
|
|
@@ -468,14 +473,23 @@ class Run:
|
|
|
468
473
|
and no text (a picture's run, ``drawing``), which a whole-run
|
|
469
474
|
``FormatApply`` of its collapsed range formats, untracked, on a
|
|
470
475
|
docx-studio that reports ``capabilities.pictureRuns``: python-docx
|
|
471
|
-
formats the run's ``w:r``, and docx-studio its picture.
|
|
476
|
+
formats the run's ``w:r``, and docx-studio its picture. A legacy
|
|
477
|
+
picture's or object's run (``w:pict``, ``w:object``: ``drawing.legacy``
|
|
478
|
+
with its ``imageId``) too, on one that reports
|
|
479
|
+
``capabilities.legacyPictureRuns``; not a preserved shape's (a
|
|
480
|
+
``drawing.legacy`` with no ``imageId``), which no picture holds and the
|
|
481
|
+
format cannot reach. Else None."""
|
|
472
482
|
if not self._is_collapsed_range or tracking(self._session):
|
|
473
483
|
return None
|
|
474
484
|
drawing = self._inline_snapshot.get("drawing")
|
|
475
|
-
if not isinstance(drawing, dict)
|
|
485
|
+
if not isinstance(drawing, dict):
|
|
476
486
|
return None
|
|
477
487
|
if not server_takes(self._session, "pictureRuns"):
|
|
478
488
|
return None
|
|
489
|
+
if drawing.get("legacy") is True and (
|
|
490
|
+
not drawing.get("imageId") or not server_takes(self._session, "legacyPictureRuns")
|
|
491
|
+
):
|
|
492
|
+
return None
|
|
479
493
|
return self._later_runs()
|
|
480
494
|
|
|
481
495
|
def _empty_run_identity(self) -> int | None:
|
|
@@ -866,6 +880,15 @@ class Run:
|
|
|
866
880
|
items: list[tuple[int, float, dict, bool]] = [
|
|
867
881
|
(offset, index, info, True) for index, (offset, info) in enumerate(pictures)
|
|
868
882
|
]
|
|
883
|
+
# python-docx yields "" for each stretch of the run that the pictures
|
|
884
|
+
# bound and that holds a page or column break and no text, by how
|
|
885
|
+
# many pictures come before it (``emptyTextAfterPictures``). From a
|
|
886
|
+
# docx-studio that does not say, a run of a break and pictures and
|
|
887
|
+
# no text yields the break's "" before them.
|
|
888
|
+
empty_after = self._empty_text_after_pictures()
|
|
889
|
+
if empty_after is None:
|
|
890
|
+
breaks = not raw and self._inline_snapshot.get("break") in ("page", "column")
|
|
891
|
+
empty_after = {0} if breaks else set()
|
|
869
892
|
rendered = self._rendered_page_breaks()
|
|
870
893
|
for info in rendered:
|
|
871
894
|
offset = int(info.get("offset", 0) or 0)
|
|
@@ -875,15 +898,23 @@ class Run:
|
|
|
875
898
|
items.append((offset, after - 0.5, info, False))
|
|
876
899
|
items.sort(key=lambda item: (item[0], item[1]))
|
|
877
900
|
cut = 0
|
|
901
|
+
pictures_yielded = 0
|
|
878
902
|
for offset, _order, info, is_picture in items:
|
|
879
903
|
at = min(max(offset, cut), len(raw))
|
|
880
904
|
if _word_text(raw[cut:at], font):
|
|
881
905
|
yield _word_text(raw[cut:at], font)
|
|
882
906
|
if not is_picture:
|
|
883
907
|
yield RenderedPageBreak(paragraph=self._page_break_paragraph(), offset=self._range[0] + at, info=info)
|
|
884
|
-
|
|
885
|
-
|
|
908
|
+
else:
|
|
909
|
+
if pictures_yielded in empty_after:
|
|
910
|
+
yield ""
|
|
911
|
+
empty_after.discard(pictures_yielded)
|
|
912
|
+
if info.get("legacy") is not True:
|
|
913
|
+
yield Drawing(session=self._session, info=info)
|
|
914
|
+
pictures_yielded += 1
|
|
886
915
|
cut = at
|
|
916
|
+
if pictures_yielded in empty_after:
|
|
917
|
+
yield ""
|
|
887
918
|
if _word_text(raw[cut:], font):
|
|
888
919
|
yield _word_text(raw[cut:], font)
|
|
889
920
|
return
|
|
@@ -1063,11 +1094,14 @@ class Run:
|
|
|
1063
1094
|
# server keeps its own properties (``w:bCs``, an off toggle) for the
|
|
1064
1095
|
# new text, as python-docx keeps the run's ``w:rPr``. A docx-studio
|
|
1065
1096
|
# from before the field ignores it.
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1097
|
+
command: dict = {"target": self._text_range, "text": value, "wholeRun": True}
|
|
1098
|
+
later = later_runs_at_end(self)
|
|
1099
|
+
if later and server_takes(self._session, "runIdentity"):
|
|
1100
|
+
# A run after this one ends where it does (an empty run, a text
|
|
1101
|
+
# box's or a SmartArt drawing's): docx-studio tells this run's
|
|
1102
|
+
# record from its by the run's identity, and keeps both.
|
|
1103
|
+
command["run"] = {"laterRuns": later}
|
|
1104
|
+
run_sync(self._session.doc.replace(command))
|
|
1071
1105
|
if not tracked:
|
|
1072
1106
|
new_end: int = self._range[0] + len(value)
|
|
1073
1107
|
self._range = (self._range[0], new_end)
|
|
@@ -1237,6 +1271,34 @@ class Run:
|
|
|
1237
1271
|
snapshot.setdefault("break", kind)
|
|
1238
1272
|
if held:
|
|
1239
1273
|
snapshot.pop("breakApart", None)
|
|
1274
|
+
self._note_empty_text_after_pictures()
|
|
1275
|
+
|
|
1276
|
+
def _note_empty_text_after_pictures(self) -> None:
|
|
1277
|
+
"""This run took a page or column break at its end, after its pictures:
|
|
1278
|
+
python-docx yields its ``""`` after the last of them while no text
|
|
1279
|
+
follows it there (``emptyTextAfterPictures``). A picture's run
|
|
1280
|
+
(``drawing``) holds its picture among its pictures (``pictures``) then."""
|
|
1281
|
+
snapshot = self._inline_snapshot
|
|
1282
|
+
alone = snapshot.get("drawing")
|
|
1283
|
+
pictures = self._pictures() or ([(0, alone)] if isinstance(alone, dict) else [])
|
|
1284
|
+
if not pictures or self._raw_text()[pictures[-1][0]:]:
|
|
1285
|
+
return
|
|
1286
|
+
if isinstance(alone, dict):
|
|
1287
|
+
snapshot.pop("drawing")
|
|
1288
|
+
snapshot["pictures"] = [{"offset": 0, "drawing": alone}]
|
|
1289
|
+
places = snapshot.setdefault("emptyTextAfterPictures", [])
|
|
1290
|
+
if isinstance(places, list) and len(pictures) not in places:
|
|
1291
|
+
places.append(len(pictures))
|
|
1292
|
+
|
|
1293
|
+
def _empty_text_after_pictures(self) -> "set[int] | None":
|
|
1294
|
+
"""Where :meth:`iter_inner_content` yields ``""`` among this run's
|
|
1295
|
+
pictures (``emptyTextAfterPictures``): each stretch the pictures bound
|
|
1296
|
+
that holds a page or column break and no text, by how many pictures
|
|
1297
|
+
come before it. None when the read does not say."""
|
|
1298
|
+
places: object = self._inline_snapshot.get("emptyTextAfterPictures")
|
|
1299
|
+
if not isinstance(places, list):
|
|
1300
|
+
return None
|
|
1301
|
+
return {p for p in places if isinstance(p, int) and not isinstance(p, bool)}
|
|
1240
1302
|
|
|
1241
1303
|
def add_break(self, break_type: "WD_BREAK" = WD_BREAK.LINE) -> None:
|
|
1242
1304
|
"""Insert a break at the end of the run.
|
|
@@ -1518,17 +1580,25 @@ class Run:
|
|
|
1518
1580
|
def _hold_picture(self, drawing: dict) -> None:
|
|
1519
1581
|
"""This run took the picture ``drawing`` at its end (``run.add_picture``),
|
|
1520
1582
|
as the next read gives it: a run of a picture alone as a picture's run
|
|
1521
|
-
(``drawing``), else among its pictures (``pictures``) where its text ends.
|
|
1583
|
+
(``drawing``), else among its pictures (``pictures``) where its text ends.
|
|
1584
|
+
A run of a page or column break and no text holds it among its
|
|
1585
|
+
pictures, after the break's ``""`` (``emptyTextAfterPictures``)."""
|
|
1522
1586
|
snapshot = self._inline_snapshot
|
|
1523
1587
|
held = self._pictures()
|
|
1524
1588
|
alone = snapshot.get("drawing")
|
|
1525
|
-
|
|
1589
|
+
raw = self._raw_text()
|
|
1590
|
+
break_first = not held and not raw and not isinstance(alone, dict) and snapshot.get("break") in ("page", "column")
|
|
1591
|
+
if not held and not raw and not isinstance(alone, dict) and not break_first:
|
|
1526
1592
|
snapshot["drawing"] = drawing
|
|
1527
1593
|
return
|
|
1528
1594
|
if isinstance(alone, dict):
|
|
1529
1595
|
held = [(0, snapshot.pop("drawing"))]
|
|
1530
|
-
held.append((len(
|
|
1596
|
+
held.append((len(raw), drawing))
|
|
1531
1597
|
snapshot["pictures"] = [{"offset": offset, "drawing": info} for offset, info in held]
|
|
1598
|
+
if break_first:
|
|
1599
|
+
places = snapshot.setdefault("emptyTextAfterPictures", [])
|
|
1600
|
+
if isinstance(places, list) and 0 not in places:
|
|
1601
|
+
places.append(0)
|
|
1532
1602
|
|
|
1533
1603
|
@athena_extension(
|
|
1534
1604
|
issue=498,
|
|
@@ -1879,15 +1949,19 @@ class Run:
|
|
|
1879
1949
|
|
|
1880
1950
|
# ---- formatting helpers ----
|
|
1881
1951
|
def _formatting_from_snapshot(self) -> dict:
|
|
1882
|
-
"""This run's formatting as a ``format.apply`` inline bag
|
|
1952
|
+
"""This run's own formatting as a ``format.apply`` inline bag: the
|
|
1953
|
+
values the run sets itself, an explicit off toggle (``w:b w:val="0"``)
|
|
1954
|
+
included, as python-docx keeps the run's ``w:rPr`` for its next text.
|
|
1883
1955
|
|
|
1884
1956
|
Only for a snapshot with every formatting key that is set
|
|
1885
|
-
(``_marks_known``)
|
|
1886
|
-
|
|
1887
|
-
|
|
1957
|
+
(``_marks_known``). A toggle the run does not set stays unset: the new
|
|
1958
|
+
text, which docx-studio gives no formatting of its own (no
|
|
1959
|
+
``inheritMarks``), shows what the styles give it, as python-docx's
|
|
1960
|
+
does. Sending it as ``False`` wrote an explicit off, so text written
|
|
1961
|
+
into an emptied heading run lost the heading's bold.
|
|
1888
1962
|
"""
|
|
1889
1963
|
snapshot = self._inline_snapshot
|
|
1890
|
-
out: dict = {
|
|
1964
|
+
out: dict = {}
|
|
1891
1965
|
for key in _RUN_MARK_KEYS:
|
|
1892
1966
|
value = snapshot.get(key)
|
|
1893
1967
|
if value is not None:
|
|
@@ -2002,6 +2076,9 @@ class Run:
|
|
|
2002
2076
|
)
|
|
2003
2077
|
# Its break or picture holds the formatting now, which what it takes next continues.
|
|
2004
2078
|
self._fresh = False
|
|
2079
|
+
# A closing page break run's breaks are the paragraph's now, as the next read gives them.
|
|
2080
|
+
if self._inline_snapshot.pop("closingBreak", None) is True:
|
|
2081
|
+
self._inline_snapshot.pop("breakApart", None)
|
|
2005
2082
|
return
|
|
2006
2083
|
if self._is_collapsed_range:
|
|
2007
2084
|
pending = getattr(self, "_pending_inline", None)
|
|
@@ -2016,17 +2093,23 @@ class Run:
|
|
|
2016
2093
|
{"target": self._text_range, "inline": kwargs, "wholeRun": True},
|
|
2017
2094
|
),
|
|
2018
2095
|
)
|
|
2019
|
-
self._edited_ruby()
|
|
2096
|
+
self._edited_ruby(formatted=True)
|
|
2020
2097
|
|
|
2021
|
-
def _edited_ruby(self) -> None:
|
|
2098
|
+
def _edited_ruby(self, *, formatted: bool = False) -> None:
|
|
2022
2099
|
"""This run's text or formatting changed: docx-studio writes the base
|
|
2023
2100
|
text of each ruby it held as text from then on (it keeps no guide
|
|
2024
|
-
through an edit), so the run reads it as text.
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2101
|
+
through an edit), so the run reads it as text. A docx-studio that
|
|
2102
|
+
reports ``capabilities.rubyThroughFormat`` keeps the ruby through a
|
|
2103
|
+
whole-run format (``formatted``), as python-docx keeps the run's
|
|
2104
|
+
``w:ruby``, so the run goes on reading it as the ruby's. It writes the
|
|
2105
|
+
run's symbol-block characters as a ``w:sym`` in the font the run owns
|
|
2106
|
+
too, so a read's null ``symbolFont`` (a source ``w:t``'s characters)
|
|
2107
|
+
gives way to the run's font (``_symbol_font``)."""
|
|
2028
2108
|
snapshot = getattr(self, "_inline_snapshot", {})
|
|
2029
|
-
|
|
2109
|
+
if "ruby" in snapshot and not (
|
|
2110
|
+
formatted and server_takes(getattr(self, "_session", None), "rubyThroughFormat")
|
|
2111
|
+
):
|
|
2112
|
+
snapshot.pop("ruby", None)
|
|
2030
2113
|
if "symbolFont" in snapshot and snapshot["symbolFont"] is None:
|
|
2031
2114
|
snapshot.pop("symbolFont")
|
|
2032
2115
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "athena-python-docx"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.38.0"
|
|
8
8
|
description = "Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -466,6 +466,62 @@ class TestRunsHoldingPictures:
|
|
|
466
466
|
assert formats == []
|
|
467
467
|
assert picture_run._pending_inline == {"italic": True}
|
|
468
468
|
|
|
469
|
+
@pytest.mark.parametrize(("capability", "sent"), [(True, True), (False, False)])
|
|
470
|
+
def test_formatting_a_legacy_objects_run_formats_it_where_docx_studio_formats_them(
|
|
471
|
+
self, mock_session: Any, fake_sd_methods: Any, capability: bool, sent: bool
|
|
472
|
+
) -> None:
|
|
473
|
+
"""``p.runs[1].italic = True`` of an embedded object's run
|
|
474
|
+
(``<w:r><w:object>…</w:object></w:r>``, read as ``drawing.legacy``):
|
|
475
|
+
python-docx formats its ``w:r``. A docx-studio without
|
|
476
|
+
``capabilities.legacyPictureRuns`` keeps the formatting for the text the
|
|
477
|
+
run takes, as before."""
|
|
478
|
+
fake_sd_methods.scripted_returns["info"] = {
|
|
479
|
+
"capabilities": {"pictureRuns": True, "legacyPictureRuns": capability, "runIdentity": True}
|
|
480
|
+
}
|
|
481
|
+
paragraph = _paragraph(
|
|
482
|
+
mock_session,
|
|
483
|
+
fake_sd_methods,
|
|
484
|
+
[{"run": {"text": "The figures "}}, {"drawing": {"imageId": "p1:0:aa", "legacy": True}}, {"run": {"text": " sit here."}}],
|
|
485
|
+
)
|
|
486
|
+
object_run = paragraph.runs[1]
|
|
487
|
+
|
|
488
|
+
object_run.italic = True
|
|
489
|
+
|
|
490
|
+
formats = [params for op, params in fake_sd_methods.calls if op == "format.apply"]
|
|
491
|
+
if sent:
|
|
492
|
+
assert formats == [
|
|
493
|
+
{
|
|
494
|
+
"target": {"kind": "text", "blockId": "p1", "range": {"start": 12, "end": 12}},
|
|
495
|
+
"inline": {"italic": True},
|
|
496
|
+
"wholeRun": True,
|
|
497
|
+
"run": {"laterRuns": 0},
|
|
498
|
+
}
|
|
499
|
+
]
|
|
500
|
+
else:
|
|
501
|
+
assert formats == []
|
|
502
|
+
assert object_run._pending_inline == {"italic": True}
|
|
503
|
+
|
|
504
|
+
def test_formatting_a_preserved_shapes_run_stays_pending(self, mock_session: Any, fake_sd_methods: Any) -> None:
|
|
505
|
+
"""A shape docx-studio keeps as it was (``mc:AlternateContent``) reads
|
|
506
|
+
as ``drawing.legacy`` with no ``imageId``: no picture holds it, so a
|
|
507
|
+
format of its run would reply ``formatted: false``. Its formatting stays
|
|
508
|
+
pending, as before, also on a docx-studio that reports
|
|
509
|
+
``legacyPictureRuns``."""
|
|
510
|
+
fake_sd_methods.scripted_returns["info"] = {
|
|
511
|
+
"capabilities": {"pictureRuns": True, "legacyPictureRuns": True, "runIdentity": True}
|
|
512
|
+
}
|
|
513
|
+
paragraph = _paragraph(
|
|
514
|
+
mock_session,
|
|
515
|
+
fake_sd_methods,
|
|
516
|
+
[{"run": {"text": "Before "}}, {"drawing": {"imageId": None, "legacy": True}}, {"run": {"text": " after"}}],
|
|
517
|
+
)
|
|
518
|
+
shape_run = paragraph.runs[1]
|
|
519
|
+
|
|
520
|
+
shape_run.italic = True
|
|
521
|
+
|
|
522
|
+
assert [params for op, params in fake_sd_methods.calls if op == "format.apply"] == []
|
|
523
|
+
assert shape_run._pending_inline == {"italic": True}
|
|
524
|
+
|
|
469
525
|
def test_a_pictures_run_reads_its_formatting(self, mock_session: Any, fake_sd_methods: Any) -> None:
|
|
470
526
|
"""python-docx reads a picture's run's ``w:rPr``: docx-studio reads its
|
|
471
527
|
formatting on the picture's inline beside its drawing."""
|
|
@@ -386,6 +386,20 @@ def test_getters_return_int_members(mock_session: Any, fake_sd_methods: Any) ->
|
|
|
386
386
|
assert table.table_direction is True and table.table_direction == WD_TABLE_DIRECTION.RTL
|
|
387
387
|
|
|
388
388
|
|
|
389
|
+
@pytest.mark.parametrize("jc", ["start", "end"])
|
|
390
|
+
def test_a_table_of_start_or_end_justification_raises_as_python_docx_reads_it(
|
|
391
|
+
mock_session: Any, fake_sd_methods: Any, jc: str
|
|
392
|
+
) -> None:
|
|
393
|
+
"""python-docx 1.2.0 reads a table's ``w:jc`` through the paragraph
|
|
394
|
+
``CT_Jc``, whose enum has no member for ``start`` or ``end``."""
|
|
395
|
+
from docx.table import Table
|
|
396
|
+
|
|
397
|
+
fake_sd_methods.scripted_returns["tables.get_properties"] = {"alignment": jc}
|
|
398
|
+
table = Table(session=mock_session, node_id="tbl-1")
|
|
399
|
+
with pytest.raises(ValueError, match=f"WD_PARAGRAPH_ALIGNMENT has no XML mapping for '{jc}'"):
|
|
400
|
+
_ = table.alignment
|
|
401
|
+
|
|
402
|
+
|
|
389
403
|
@pytest.mark.parametrize(
|
|
390
404
|
"assign",
|
|
391
405
|
[
|
{athena_python_docx-0.36.0 → athena_python_docx-0.38.0}/tests/test_ruby_reads_python_docx_parity.py
RENAMED
|
@@ -13,8 +13,10 @@ is installed.
|
|
|
13
13
|
|
|
14
14
|
docx-studio keeps the base text in its run's text, the room it takes in the
|
|
15
15
|
text-address space, and gives its spans as ``ruby``: edits addressed after the
|
|
16
|
-
ruby land after it. Once the run's text
|
|
17
|
-
|
|
16
|
+
ruby land after it. Once the run's text changes, docx-studio writes the base
|
|
17
|
+
text as text, and the run reads it so; so does a format of the run, but on a
|
|
18
|
+
docx-studio that reports ``rubyThroughFormat``, which keeps the ruby through it
|
|
19
|
+
as python-docx does.
|
|
18
20
|
"""
|
|
19
21
|
|
|
20
22
|
from __future__ import annotations
|
|
@@ -190,3 +192,17 @@ def test_an_edit_of_the_rubys_run_reads_its_base_text_as_text(
|
|
|
190
192
|
|
|
191
193
|
assert _writes(fake_sd_methods)
|
|
192
194
|
assert "ruby" not in ruby._inline_snapshot
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_a_format_of_the_rubys_run_keeps_its_ruby_where_docx_studio_keeps_it(
|
|
198
|
+
mock_session: Any, fake_sd_methods: Any
|
|
199
|
+
) -> None:
|
|
200
|
+
# A docx-studio that reports `rubyThroughFormat` keeps the run's `w:ruby`
|
|
201
|
+
# through a whole-run format, as python-docx keeps it: the run still reads "".
|
|
202
|
+
fake_sd_methods.scripted_returns["info"] = {"capabilities": {"rubyThroughFormat": True}}
|
|
203
|
+
ruby = _body(mock_session, fake_sd_methods).runs[1]
|
|
204
|
+
|
|
205
|
+
ruby.bold = True
|
|
206
|
+
|
|
207
|
+
assert ruby._inline_snapshot.get("ruby") == [[0, 1]]
|
|
208
|
+
assert ruby.text == ""
|