athena-python-docx 0.34.0__tar.gz → 0.35.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.34.0 → athena_python_docx-0.35.0}/AGENTS.md +21 -19
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/PKG-INFO +1 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/__init__.py +1 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_buffer.py +6 -0
- athena_python_docx-0.35.0/docx/_proxy.py +85 -0
- athena_python_docx-0.35.0/docx/_xml_text.py +46 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/blkcntnr.py +3 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/document.py +4 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/section.py +3 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/settings.py +15 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/styles/style.py +65 -18
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/styles/styles.py +5 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/table.py +89 -14
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/paragraph.py +33 -3
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/parfmt.py +16 -4
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/run.py +21 -2
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/pyproject.toml +1 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/METHODOLOGY.md +9 -1
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/__init__.py +15 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/default_style_run_formatting.py +25 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/header_footer_pictures.py +28 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/less_used_writes.py +219 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/merged_cell_identity.py +31 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/paragraph_text_setter.py +57 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/proxy_equality.py +41 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/xml_incompatible_text.py +24 -0
- athena_python_docx-0.35.0/tests/fidelity/ab_probe/zero_and_negative_indents.py +26 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/ab_probe_cases.py +196 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/baseline.json +8 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/fixture_scripts.py +17 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/runner.py +25 -16
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/test_live_runner.py +24 -0
- athena_python_docx-0.35.0/tests/test_battery_cases.py +54 -0
- athena_python_docx-0.35.0/tests/test_document_settings_session_open.py +63 -0
- athena_python_docx-0.35.0/tests/test_merged_cell_identity.py +104 -0
- athena_python_docx-0.35.0/tests/test_paragraph_indent_reads.py +60 -0
- athena_python_docx-0.35.0/tests/test_paragraph_text_empty_run.py +44 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_parfmt_clears.py +24 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_parity_misc.py +15 -2
- athena_python_docx-0.35.0/tests/test_proxy_equality.py +179 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_tab_stops.py +42 -0
- athena_python_docx-0.35.0/tests/test_unmapped_alignment_reads.py +95 -0
- athena_python_docx-0.35.0/tests/test_xml_incompatible_text.py +103 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/uv.lock +1 -1
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/.gitignore +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/CLAUDE.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/DOCX_EXEC_LAB.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/README.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_capabilities.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_citations.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_execution.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_http.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_http_doc.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_image_utils.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_postproc.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_references.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_run_order.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_timeouts.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/_tracked.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/api.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/bookmarks.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/charts.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/client.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/commands.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/comments.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/drawing/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/base.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/dml.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/section.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/shape.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/style.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/table.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/enum/text.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/errors.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/fields.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/footnotes.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/image/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/image/exceptions.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/image/image.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/math.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/opc/coreprops.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/oxml/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/sdt.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/session.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/shape.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/shared.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/styles/_table.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/styles/latent.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/hyperlink.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/pagebreak.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/text/tabstops.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/toc.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/docx/typing.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/dump_wire_fixtures.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/release.sh +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/smoke_test_block_not_found.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/scripts/validate_find_replace_asset.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/fake_session.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/README.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/_runner.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/extractor.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fixtures/field_reads.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fixtures/note_reference_reads.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fixtures/ruby_reads.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/fixtures/symbol_reads.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/reader.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/sdk_driver.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/live/stock_driver.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/README.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/intentional_deviations.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/reports/gap_report.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/snapshots/athena_latest.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_add_section.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_add_section_extract_items.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_alignment_values.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_athena_extension_creates_session_open.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_athena_extensions_registry.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_batch_chunking.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_block_not_found_error.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_add_table_not_supported.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_borders_spec.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_fastpath_runs.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_format_stash.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_run_format_stash.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_inner_run_guard.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_merge.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_nested_tables.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_paragraphs_listed.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_text_plain_fastpath.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_cell_text_replace_semantics.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_citations.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_collapsed_range_format.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_color_format_theme.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_comment_paragraphs.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_comments.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_comments_first_read.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_content_control_value.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_core_properties.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_document_clear.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_document_create.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_document_create_from_template.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_document_factory_validation.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_docx_exec_lab.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_drawing_image.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_empty_hyperlinks.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_enum_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_execution_scope.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_export_docx_clean.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_export_rescue_anchors.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_field_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_field_refresh.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_field_runs.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_find_replace_session_open.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_flushed_write_failures.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_http_transport.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_hyperlink_coalescing.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_image_url_data_uri.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_inline_page_break.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_inline_shape_alt_text.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_inline_shape_size.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_inline_shape_type.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_inline_shapes_floating.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_latent_style_writes.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_line_clear_break.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_list_styles.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_merged_cell_secondary_slot.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_missing_modules.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_nested_table_refused.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_page_break.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_paragraph_delete.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_paragraph_runs_hyperlinks.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_parity_round2.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_pdf_export_and_page_renders.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_phase_a_behavior.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_phase_b_headers_footers.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_positional_cell_id.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_postproc_cell_format_rewrite.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_postproc_ref_restore.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_read_run_ranges.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_rendered_page_breaks.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_repeated_node_read.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_restart_numbering.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_revisions.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_round_trip_smoke_script.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_ruby_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_add_picture_anchor.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_break_inner_content.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_edges.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_formatting_wire.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_identity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_later_runs.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_mark_inheritance.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_page_number_blocks.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_table_style_objects.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_text_python_docx.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_text_refreshes_paragraph.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_run_unmodeled_toggles.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_sdk_reads_served.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_section_read_lengths.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_enum_section.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_header_footer.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_inline_shape.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_misc.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_parfmt.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_row_col_cell.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_style.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_style_strict.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_text.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_run_underline.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_section_dimensions.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_section_onoff.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_style.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_silent_stub_table_layout.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_delete.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_formatting_writes.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_metadata_writes.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_names.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_setters_contract.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_style_tab_stops_read.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_symbol_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_tab_stop_writes.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_table_anchors.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_table_clears.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_table_direction.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_table_read_reuse.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_table_set_cell_perf.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_table_style_id_resolution.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_text_control_characters.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_tracked_revisions_offsets.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_uv_lock_version.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_validate_find_replace_asset_script.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_wire_contract.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_xml_attr_guard.py +0 -0
- {athena_python_docx-0.34.0 → athena_python_docx-0.35.0}/tests/test_zod_wire_contract.py +0 -0
|
@@ -1255,31 +1255,33 @@ architecture or a DOCX Studio constraint:
|
|
|
1255
1255
|
exported file. Against a docx-studio that predates `fieldRun` reads, a
|
|
1256
1256
|
field reads as no runs and no text, as before (`tests/test_field_runs.py`).
|
|
1257
1257
|
|
|
1258
|
-
- **A run that holds a page number block refuses
|
|
1259
|
-
page number block (`w:pgNum`) reads as a run with
|
|
1260
|
-
holds text and blocks (or two blocks) reads as
|
|
1261
|
-
whole-run format (`run.bold = True`, `run.font.*`,
|
|
1262
|
-
run) formats every piece of it, as python-docx formats
|
|
1263
|
-
|
|
1264
|
-
has none, and takes both as the run's text does. The first is a tracked
|
|
1265
|
-
format (`track_revisions`), which raises `DocxError` naming
|
|
1266
|
-
`TrackedChangesUnsupported`, because docx-studio records no tracked change
|
|
1267
|
-
on a block. The second is the on/off properties no editor mark holds
|
|
1258
|
+
- **A run that holds a page number block refuses a tracked whole-run format
|
|
1259
|
+
and two text writes.** A page number block (`w:pgNum`) reads as a run with
|
|
1260
|
+
no text, and a run that holds text and blocks (or two blocks) reads as
|
|
1261
|
+
python-docx's one run. A whole-run format (`run.bold = True`, `run.font.*`,
|
|
1262
|
+
a format of a block's run) formats every piece of it, as python-docx formats
|
|
1263
|
+
its `w:rPr`, the on/off properties no editor mark holds included
|
|
1268
1264
|
(`font.no_proof`, `snap_to_grid`, `web_hidden`, `spec_vanish`, `math`,
|
|
1269
|
-
`complex_script`, `cs_bold`, `cs_italic`)
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1265
|
+
`complex_script`, `cs_bold`, `cs_italic`). A tracked format
|
|
1266
|
+
(`track_revisions`) is refused while a block of the run has a node, and
|
|
1267
|
+
raises `DocxError` naming `TrackedChangesUnsupported`, because docx-studio
|
|
1268
|
+
records no tracked change on a block. A link's block has none, and takes it
|
|
1269
|
+
as the run's text does. In a document imported before docx-studio gave a
|
|
1270
|
+
block's node its run's properties (in October 2026, between the release that
|
|
1271
|
+
first read `w:pgNum` and the next), and in a comment, the on/off properties
|
|
1272
|
+
are refused too, in any format that reaches a block, and warn
|
|
1273
|
+
(`DocxUnsupportedCommandWarning`), because there a block keeps its source
|
|
1274
|
+
run's. python-docx writes both into the run's `w:rPr`. Made on the run's
|
|
1275
|
+
text alone, either would leave the run half formatted and split it in two
|
|
1274
1276
|
(`DOCX_STUDIO_LIMITATIONS.md` § 27). `run.text = …` and `clear()` replace
|
|
1275
1277
|
all of such a run, its blocks too, as upstream does: the SDK declares
|
|
1276
1278
|
`wholeRunPieces`, and renumbers the field runs it holds of the paragraph,
|
|
1277
1279
|
since each field after the blocks is numbered one lower for each
|
|
1278
1280
|
(`tests/test_run_page_number_blocks.py`). Two text writes are refused and
|
|
1279
|
-
warn (`DocxUnsupportedCommandWarning`), where upstream replaces the
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1281
|
+
warn (`DocxUnsupportedCommandWarning`), where upstream replaces the blocks:
|
|
1282
|
+
text written to a block's run (a run of blocks alone, or a lone block),
|
|
1283
|
+
which would move the text offsets the SDK keeps, and the text of a link's
|
|
1284
|
+
run that holds a block, which has no node to take out.
|
|
1283
1285
|
|
|
1284
1286
|
- **`Font.name = "…"` also clears the theme fonts of the two slots it
|
|
1285
1287
|
sets.** python-docx writes the name to `w:rFonts`' `w:ascii` and `w:hAnsi`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.35.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>
|
|
@@ -43,6 +43,7 @@ from docx._execution import (
|
|
|
43
43
|
is_stale_execution,
|
|
44
44
|
)
|
|
45
45
|
from docx._timeouts import timeout_for_commands
|
|
46
|
+
from docx._xml_text import check_command_text
|
|
46
47
|
from docx.commands import (
|
|
47
48
|
Command,
|
|
48
49
|
GetNodeById,
|
|
@@ -596,6 +597,11 @@ class CommandBuffer:
|
|
|
596
597
|
proxy's ``_node_id`` in-place.
|
|
597
598
|
"""
|
|
598
599
|
self.ensure_usable()
|
|
600
|
+
# A write whose text holds a character XML does not allow raises
|
|
601
|
+
# python-docx's ValueError here, before anything is sent: every command
|
|
602
|
+
# comes through, a path-proxy op's and a direct ``send_command``'s.
|
|
603
|
+
if not is_query(cmd):
|
|
604
|
+
check_command_text(cmd.to_dict())
|
|
599
605
|
|
|
600
606
|
# A read of the node the last command read, with nothing sent or
|
|
601
607
|
# buffered since and within READ_REUSE_SECONDS of it, answers from
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""python-docx's ``ElementProxy`` equality, for the SDK's proxies of the
|
|
2
|
+
objects python-docx wraps in one: styles, the styles part, settings, a
|
|
3
|
+
paragraph's or a style's paragraph format, a run's or a style's font."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import weakref
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ElementProxyEquality:
|
|
12
|
+
"""python-docx's ``docx.shared.ElementProxy`` equality: two proxies of the
|
|
13
|
+
same element are equal (``paragraph.style == doc.styles["Heading 1"]``),
|
|
14
|
+
a proxy of another element or anything else is not, and, as python-docx
|
|
15
|
+
defines ``__eq__`` there, a proxy is not hashable.
|
|
16
|
+
|
|
17
|
+
The element is :meth:`_proxy_element`: the docx-studio object it stands
|
|
18
|
+
for, named as the XML element python-docx's proxy wraps (a style's
|
|
19
|
+
``w:style``, so a style, its font and its paragraph format are equal, as
|
|
20
|
+
they are in python-docx).
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__slots__ = ()
|
|
24
|
+
|
|
25
|
+
def _proxy_element(self) -> tuple[object, ...]:
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
|
|
28
|
+
def __eq__(self, other: object) -> bool:
|
|
29
|
+
if not isinstance(other, ElementProxyEquality):
|
|
30
|
+
return False
|
|
31
|
+
return self._proxy_element() == other._proxy_element()
|
|
32
|
+
|
|
33
|
+
def __ne__(self, other: object) -> bool:
|
|
34
|
+
return not self.__eq__(other)
|
|
35
|
+
|
|
36
|
+
__hash__ = None # type: ignore[assignment]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Session -> style id -> the style definition that id names in the session's
|
|
40
|
+
# document now (:func:`style_definition`). Held weakly by session, as the
|
|
41
|
+
# run order is (``docx._run_order``); the document stores none of it.
|
|
42
|
+
_STYLE_DEFINITIONS: "weakref.WeakKeyDictionary[Any, dict[str, object]]" = weakref.WeakKeyDictionary()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _definitions(session: object) -> "dict[str, object] | None":
|
|
46
|
+
if session is None:
|
|
47
|
+
return None
|
|
48
|
+
try:
|
|
49
|
+
return _STYLE_DEFINITIONS.setdefault(session, {})
|
|
50
|
+
except TypeError: # a session that takes no weak reference
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def style_definition(session: object, style_id: str) -> object:
|
|
55
|
+
"""The style definition (its ``w:style`` element) that ``style_id`` names in
|
|
56
|
+
``session``'s document now, which a style proxy holds from its first read:
|
|
57
|
+
the same one after a rename (:func:`style_renamed`), another for a style
|
|
58
|
+
made after one of that id was deleted (:func:`style_deleted`)."""
|
|
59
|
+
definitions = _definitions(session)
|
|
60
|
+
if definitions is None:
|
|
61
|
+
return ("w:styleId", style_id)
|
|
62
|
+
return definitions.setdefault(style_id, object())
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def style_renamed(session: object, old: str, new: str) -> None:
|
|
66
|
+
"""``style_id`` renamed the definition ``old`` named to ``new``."""
|
|
67
|
+
definitions = _definitions(session)
|
|
68
|
+
if definitions is not None:
|
|
69
|
+
definitions[new] = definitions.pop(old, None) or object()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def style_deleted(session: object, style_id: str) -> None:
|
|
73
|
+
"""``delete`` removed the definition ``style_id`` named."""
|
|
74
|
+
definitions = _definitions(session)
|
|
75
|
+
if definitions is not None:
|
|
76
|
+
definitions.pop(style_id, None)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def style_element(style: object) -> tuple[object, ...]:
|
|
80
|
+
"""The ``w:style`` element of ``style`` (a ``BaseStyle``): its document and
|
|
81
|
+
its definition (:func:`style_definition`), which a rename keeps."""
|
|
82
|
+
definition = getattr(style, "_definition", None)
|
|
83
|
+
if definition is None:
|
|
84
|
+
definition = ("w:styleId", getattr(style, "_style_id", None))
|
|
85
|
+
return ("w:style", getattr(style, "_session", None), definition)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""What lxml refuses in XML text and attribute values, where python-docx meets it.
|
|
2
|
+
|
|
3
|
+
python-docx writes every string it is given into an lxml element, and lxml
|
|
4
|
+
raises ``ValueError`` for a character XML does not allow: C0 controls other
|
|
5
|
+
than tab, LF and CR, the noncharacters U+FFFE / U+FFFF, and lone surrogates.
|
|
6
|
+
So ``run.text = "a\\x0bb"`` (a vertical tab, Word's line break in its object
|
|
7
|
+
model) raises there, before anything is written. docx-studio would take the
|
|
8
|
+
text, and a part holding it is one Word refuses to open.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import re
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
XML_INCOMPATIBLE_CHARACTER = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\ud800-\udfff]")
|
|
17
|
+
XML_INCOMPATIBLE_MESSAGE = (
|
|
18
|
+
"All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def check_xml_compatible(value: Any) -> None:
|
|
23
|
+
"""Raise python-docx's ``ValueError`` (lxml's) when a string in ``value``,
|
|
24
|
+
a command's params (strings, lists, dicts), holds a character XML does
|
|
25
|
+
not allow."""
|
|
26
|
+
if isinstance(value, str):
|
|
27
|
+
if XML_INCOMPATIBLE_CHARACTER.search(value):
|
|
28
|
+
raise ValueError(XML_INCOMPATIBLE_MESSAGE)
|
|
29
|
+
elif isinstance(value, dict):
|
|
30
|
+
for item in value.values():
|
|
31
|
+
check_xml_compatible(item)
|
|
32
|
+
elif isinstance(value, (list, tuple)):
|
|
33
|
+
for item in value:
|
|
34
|
+
check_xml_compatible(item)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
#: Fields of a write that name text to find, not text to write
|
|
38
|
+
#: (``FindReplace.pattern``): a pattern may match what a document already holds.
|
|
39
|
+
_SEARCH_FIELDS: frozenset[str] = frozenset({"pattern"})
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def check_command_text(command: dict[str, Any]) -> None:
|
|
43
|
+
""":func:`check_xml_compatible` over a write's wire fields (a command's
|
|
44
|
+
``to_dict()``), but for the text it searches for (``_SEARCH_FIELDS``)."""
|
|
45
|
+
check_xml_compatible({key: value for key, value in command.items() if key not in _SEARCH_FIELDS})
|
|
46
|
+
|
|
@@ -9,6 +9,8 @@ docx-studio; ``isinstance(cell, BlockItemContainer)`` holds as in python-docx.
|
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
+
from docx._xml_text import check_xml_compatible
|
|
13
|
+
|
|
12
14
|
from typing import TYPE_CHECKING, Iterator
|
|
13
15
|
|
|
14
16
|
if TYPE_CHECKING:
|
|
@@ -30,6 +32,7 @@ class BlockItemContainer:
|
|
|
30
32
|
self, text: str = "", style: "str | ParagraphStyle | None" = None
|
|
31
33
|
) -> "Paragraph":
|
|
32
34
|
"""Return paragraph newly added to the end of the content in this container."""
|
|
35
|
+
check_xml_compatible(text)
|
|
33
36
|
raise NotImplementedError(f"{type(self).__name__} holds no paragraphs")
|
|
34
37
|
|
|
35
38
|
def add_table(self, rows: int, cols: int, width: "Length") -> "Table":
|
|
@@ -14,6 +14,8 @@ Phase 1 supported methods:
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
from docx._xml_text import check_xml_compatible
|
|
18
|
+
|
|
17
19
|
import base64
|
|
18
20
|
import os
|
|
19
21
|
import re
|
|
@@ -1789,6 +1791,7 @@ class Document:
|
|
|
1789
1791
|
Returns:
|
|
1790
1792
|
The newly-created Paragraph.
|
|
1791
1793
|
"""
|
|
1794
|
+
check_xml_compatible(text)
|
|
1792
1795
|
from docx.styles._table import paragraph_style_name
|
|
1793
1796
|
from docx.styles.style import ParagraphStyle
|
|
1794
1797
|
from docx.text.paragraph import Paragraph
|
|
@@ -2033,6 +2036,7 @@ class Document:
|
|
|
2033
2036
|
level: int = 1,
|
|
2034
2037
|
) -> "Paragraph":
|
|
2035
2038
|
"""Append a heading via DOCX Studio's canonical `doc.create.heading`."""
|
|
2039
|
+
check_xml_compatible(text)
|
|
2036
2040
|
from docx.text.paragraph import Paragraph
|
|
2037
2041
|
|
|
2038
2042
|
self._ensure_open()
|
|
@@ -11,6 +11,8 @@ or twip values depending on the op).
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
from docx._xml_text import check_xml_compatible
|
|
15
|
+
|
|
14
16
|
import warnings
|
|
15
17
|
from collections.abc import Sequence
|
|
16
18
|
from typing import TYPE_CHECKING
|
|
@@ -986,6 +988,7 @@ class _HeaderFooter(BlockItemContainer):
|
|
|
986
988
|
server turns tabs and line breaks in ``text`` into ``<w:tab/>`` /
|
|
987
989
|
``<w:br/>``, as python-docx's ``Run.text`` does.
|
|
988
990
|
"""
|
|
991
|
+
check_xml_compatible(text)
|
|
989
992
|
from docx.styles.style import ParagraphStyle
|
|
990
993
|
|
|
991
994
|
style_str: str | None
|
|
@@ -21,6 +21,7 @@ from __future__ import annotations
|
|
|
21
21
|
from typing import TYPE_CHECKING
|
|
22
22
|
|
|
23
23
|
from docx._batching import run_sync
|
|
24
|
+
from docx._proxy import ElementProxyEquality
|
|
24
25
|
|
|
25
26
|
if TYPE_CHECKING:
|
|
26
27
|
from docx.client import Session
|
|
@@ -38,7 +39,7 @@ class PendingSettingsMutationWarning(UserWarning):
|
|
|
38
39
|
"""
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
class Settings:
|
|
42
|
+
class Settings(ElementProxyEquality):
|
|
42
43
|
def __init__(
|
|
43
44
|
self,
|
|
44
45
|
*,
|
|
@@ -49,12 +50,16 @@ class Settings:
|
|
|
49
50
|
self._document: "Document | None" = document
|
|
50
51
|
self._odd_and_even_pages_header_footer: bool = False
|
|
51
52
|
|
|
53
|
+
def _proxy_element(self) -> tuple[object, ...]:
|
|
54
|
+
return ("w:settings", self._session)
|
|
55
|
+
|
|
52
56
|
@property
|
|
53
57
|
def odd_and_even_pages_header_footer(self) -> bool:
|
|
54
58
|
"""The document's ``w:evenAndOddHeaders`` in ``word/settings.xml``, as
|
|
55
59
|
python-docx reads it (False when absent or off). A docx-studio that
|
|
56
60
|
does not report it (``Info`` without ``settings``) gives the value this
|
|
57
61
|
proxy last set."""
|
|
62
|
+
self._open()
|
|
58
63
|
info: object = run_sync(self._session.doc.info({"includeSettings": True}))
|
|
59
64
|
settings: object = info.get("settings") if isinstance(info, dict) else None
|
|
60
65
|
reported: object = settings.get("evenAndOddHeaders") if isinstance(settings, dict) else None
|
|
@@ -65,6 +70,7 @@ class Settings:
|
|
|
65
70
|
@odd_and_even_pages_header_footer.setter
|
|
66
71
|
def odd_and_even_pages_header_footer(self, value: bool) -> None:
|
|
67
72
|
enabled = bool(value)
|
|
73
|
+
self._open()
|
|
68
74
|
run_sync(
|
|
69
75
|
self._session.doc.sections.set_odd_even_headers_footers(
|
|
70
76
|
{"enabled": enabled},
|
|
@@ -72,6 +78,14 @@ class Settings:
|
|
|
72
78
|
)
|
|
73
79
|
self._odd_and_even_pages_header_footer = enabled
|
|
74
80
|
|
|
81
|
+
def _open(self) -> None:
|
|
82
|
+
"""Open the document's session before a read or write of it, as every
|
|
83
|
+
member of ``Document`` that touches it does (``Document.create()``
|
|
84
|
+
returns before it opens). ``track_revisions`` needs no session: it
|
|
85
|
+
stays a local flag until one opens."""
|
|
86
|
+
if self._document is not None:
|
|
87
|
+
self._document._ensure_open()
|
|
88
|
+
|
|
75
89
|
# --- Track changes alias (Athena: forwards to Document.track_revisions) ---
|
|
76
90
|
|
|
77
91
|
@property
|
|
@@ -33,6 +33,13 @@ from typing import TYPE_CHECKING, Any, Callable
|
|
|
33
33
|
|
|
34
34
|
from docx._batching import run_sync
|
|
35
35
|
from docx._buffer import writes_unapplied
|
|
36
|
+
from docx._proxy import (
|
|
37
|
+
ElementProxyEquality,
|
|
38
|
+
style_definition,
|
|
39
|
+
style_deleted,
|
|
40
|
+
style_element,
|
|
41
|
+
style_renamed,
|
|
42
|
+
)
|
|
36
43
|
from docx.enum.style import WD_STYLE_TYPE
|
|
37
44
|
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING, WD_TAB_ALIGNMENT, WD_TAB_LEADER
|
|
38
45
|
from docx.shared import Emu, Length, Pt, Twips
|
|
@@ -151,7 +158,7 @@ def _style_by_id(session: Any, style_id: object) -> "BaseStyle | None":
|
|
|
151
158
|
return _style_of_record(record, session) if record is not None else None
|
|
152
159
|
|
|
153
160
|
|
|
154
|
-
class BaseStyle:
|
|
161
|
+
class BaseStyle(ElementProxyEquality):
|
|
155
162
|
"""Base for all style kinds. Matches python-docx.styles.style.BaseStyle."""
|
|
156
163
|
|
|
157
164
|
def __init__(
|
|
@@ -168,6 +175,8 @@ class BaseStyle:
|
|
|
168
175
|
self._style_id: str = style_id or name
|
|
169
176
|
self._type: "WD_STYLE_TYPE" = style_type
|
|
170
177
|
self._session: "Session | None" = session
|
|
178
|
+
# The definition this proxy stands for, which a rename keeps (equality).
|
|
179
|
+
self._definition: object = style_definition(session, self._style_id)
|
|
171
180
|
# Writes docx-studio does not take, kept for read-back (see module docstring).
|
|
172
181
|
self._overrides: dict[str, Any] = {}
|
|
173
182
|
|
|
@@ -215,6 +224,9 @@ class BaseStyle:
|
|
|
215
224
|
self._set_metadata("name", value, name=value)
|
|
216
225
|
|
|
217
226
|
# ---- style_id ----
|
|
227
|
+
def _proxy_element(self) -> tuple[object, ...]:
|
|
228
|
+
return style_element(self)
|
|
229
|
+
|
|
218
230
|
@property
|
|
219
231
|
def style_id(self) -> str:
|
|
220
232
|
return self._overrides.get("style_id", self._style_id)
|
|
@@ -239,6 +251,7 @@ class BaseStyle:
|
|
|
239
251
|
and server_takes(self._session, "styleIdWrites")
|
|
240
252
|
):
|
|
241
253
|
self._set_metadata("style_id", value, id=value)
|
|
254
|
+
style_renamed(self._session, self._style_id, value)
|
|
242
255
|
self._style_id = value
|
|
243
256
|
self._overrides.pop("style_id", None)
|
|
244
257
|
return
|
|
@@ -353,6 +366,7 @@ class BaseStyle:
|
|
|
353
366
|
return
|
|
354
367
|
# Its id as the document holds it: `style_id` may hold a value only this process set.
|
|
355
368
|
run_sync(self._session.doc.styles.delete({"styleId": self._style_id, "styleType": style_type}))
|
|
369
|
+
style_deleted(self._session, self._style_id)
|
|
356
370
|
forget_style_table(self._session)
|
|
357
371
|
|
|
358
372
|
|
|
@@ -638,6 +652,16 @@ _MULTIPLE_LINES: dict[WD_LINE_SPACING, int] = {
|
|
|
638
652
|
}
|
|
639
653
|
|
|
640
654
|
|
|
655
|
+
def _alignment_of_jc(jc: object) -> WD_ALIGN_PARAGRAPH | None:
|
|
656
|
+
"""The member of a style's own ``w:jc``, as python-docx reads it: None for
|
|
657
|
+
none, and ``ValueError`` for a value it has no member for (``start``,
|
|
658
|
+
``end``, ``numTab``)."""
|
|
659
|
+
if not isinstance(jc, str) or not jc:
|
|
660
|
+
return None
|
|
661
|
+
member = _ALIGNMENT_OF_JC.get(jc)
|
|
662
|
+
return member if member is not None else WD_ALIGN_PARAGRAPH.from_xml(jc)
|
|
663
|
+
|
|
664
|
+
|
|
641
665
|
def _alignment_of(value: object) -> WD_ALIGN_PARAGRAPH:
|
|
642
666
|
"""``value`` as a ``WD_ALIGN_PARAGRAPH`` member, as ``Paragraph.alignment`` takes it."""
|
|
643
667
|
if not isinstance(value, (int, str)):
|
|
@@ -675,7 +699,7 @@ def _line_rule_of(own: dict[str, Any]) -> str | None:
|
|
|
675
699
|
return "auto" if own.get("lineSpacing") is not None else None
|
|
676
700
|
|
|
677
701
|
|
|
678
|
-
class _StyleParagraphFormat:
|
|
702
|
+
class _StyleParagraphFormat(ElementProxyEquality):
|
|
679
703
|
"""``ParagraphStyle.paragraph_format``: python-docx's ``ParagraphFormat``
|
|
680
704
|
over a style's own ``w:pPr``.
|
|
681
705
|
|
|
@@ -694,6 +718,9 @@ class _StyleParagraphFormat:
|
|
|
694
718
|
def __init__(self, style: "BaseStyle") -> None:
|
|
695
719
|
self._style: "BaseStyle" = style
|
|
696
720
|
|
|
721
|
+
def _proxy_element(self) -> tuple[object, ...]:
|
|
722
|
+
return style_element(self._style)
|
|
723
|
+
|
|
697
724
|
def _own(self) -> dict[str, Any] | None:
|
|
698
725
|
"""The style's own paragraph properties from the style table; None
|
|
699
726
|
when the table carries none (an older docx-studio)."""
|
|
@@ -727,7 +754,7 @@ class _StyleParagraphFormat:
|
|
|
727
754
|
# ---- alignment ----
|
|
728
755
|
@property
|
|
729
756
|
def alignment(self) -> Any:
|
|
730
|
-
return self._get("alignment", "alignment",
|
|
757
|
+
return self._get("alignment", "alignment", _alignment_of_jc)
|
|
731
758
|
|
|
732
759
|
@alignment.setter
|
|
733
760
|
def alignment(self, value: Any) -> None:
|
|
@@ -891,6 +918,13 @@ _LIVE_TAB_STOPS: "weakref.WeakKeyDictionary[Any, dict[str, weakref.WeakSet[_Styl
|
|
|
891
918
|
weakref.WeakKeyDictionary()
|
|
892
919
|
)
|
|
893
920
|
|
|
921
|
+
# Why a tab stop is out of its style, as python-docx's ``w:tab`` is: taken out
|
|
922
|
+
# of the ``w:tabs`` (``del``, another object of it given a new position), so a
|
|
923
|
+
# new position finds no list to go back into; or in the ``w:tabs`` that
|
|
924
|
+
# ``clear_all`` took out, where a new position still goes.
|
|
925
|
+
_REMOVED = "removed"
|
|
926
|
+
_CLEARED = "cleared"
|
|
927
|
+
|
|
894
928
|
|
|
895
929
|
class _StyleTabStop:
|
|
896
930
|
"""One tab stop of a style's ``w:tabs``, as python-docx's ``TabStop``
|
|
@@ -912,7 +946,7 @@ class _StyleTabStop:
|
|
|
912
946
|
self._entry: dict[str, Any] = entry
|
|
913
947
|
self._owner: "_StyleTabStops | None" = owner
|
|
914
948
|
self._index: int | None = index
|
|
915
|
-
self._detached =
|
|
949
|
+
self._detached: str | None = None
|
|
916
950
|
if owner is not None and index is not None:
|
|
917
951
|
owner._track(self)
|
|
918
952
|
|
|
@@ -928,8 +962,9 @@ class _StyleTabStop:
|
|
|
928
962
|
def _change(self, prop: str, entry: dict[str, Any], *, reorder: bool = False) -> None:
|
|
929
963
|
if self._detached:
|
|
930
964
|
# python-docx's removed w:tab takes a value (the document does
|
|
931
|
-
# not); a new position finds no w:tabs to go back into
|
|
932
|
-
|
|
965
|
+
# not); a new position finds no w:tabs to go back into, but one
|
|
966
|
+
# clear_all took out goes back into the w:tabs it took out.
|
|
967
|
+
if reorder and self._detached != _CLEARED:
|
|
933
968
|
raise AttributeError("this tab stop is no longer one of the style's")
|
|
934
969
|
self._entry = entry
|
|
935
970
|
return
|
|
@@ -1019,10 +1054,17 @@ class _StyleTabStops:
|
|
|
1019
1054
|
return
|
|
1020
1055
|
styles.setdefault(self._style.style_id, weakref.WeakSet()).add(stop)
|
|
1021
1056
|
|
|
1022
|
-
def _moved(
|
|
1057
|
+
def _moved(
|
|
1058
|
+
self,
|
|
1059
|
+
place: Callable[[int], int | None],
|
|
1060
|
+
entries: dict[int, dict[str, Any]] | None = None,
|
|
1061
|
+
*,
|
|
1062
|
+
why: str = _REMOVED,
|
|
1063
|
+
) -> None:
|
|
1023
1064
|
"""After a write: each live tab stop of the style at its new place
|
|
1024
1065
|
(``place`` of its old one), with its new value where ``entries`` (by
|
|
1025
|
-
new place) gives one, or out of the style where ``place``
|
|
1066
|
+
new place) gives one, or out of the style (``why``) where ``place``
|
|
1067
|
+
gives none."""
|
|
1026
1068
|
try:
|
|
1027
1069
|
live = (_LIVE_TAB_STOPS.get(self._style._session) or {}).get(self._style.style_id)
|
|
1028
1070
|
except TypeError:
|
|
@@ -1032,7 +1074,7 @@ class _StyleTabStops:
|
|
|
1032
1074
|
continue
|
|
1033
1075
|
new = place(stop._index)
|
|
1034
1076
|
if new is None:
|
|
1035
|
-
stop._detached =
|
|
1077
|
+
stop._detached = why
|
|
1036
1078
|
continue
|
|
1037
1079
|
stop._index = new
|
|
1038
1080
|
if entries and new in entries:
|
|
@@ -1056,19 +1098,24 @@ class _StyleTabStops:
|
|
|
1056
1098
|
|
|
1057
1099
|
def _replace(self, stop: "_StyleTabStop", entry: dict[str, Any], *, reorder: bool) -> None:
|
|
1058
1100
|
"""Write the style's tab stops with ``stop`` changed to ``entry``: in
|
|
1059
|
-
place, or for a new position (``reorder``)
|
|
1060
|
-
|
|
1061
|
-
|
|
1101
|
+
place, or for a new position (``reorder``) inserted where
|
|
1102
|
+
``insert_tab_in_order`` puts a new one (``stop`` still listed) and
|
|
1103
|
+
taken out of its old place, as python-docx's ``TabStop.position`` does
|
|
1104
|
+
(a new ``w:tab``, so another object of the old one is out of the
|
|
1105
|
+
style); a list out of position order keeps its order around it."""
|
|
1062
1106
|
stops = list(self._stops())
|
|
1063
1107
|
at = stop._index
|
|
1064
1108
|
if at is None or not 0 <= at < len(stops):
|
|
1065
1109
|
raise ValueError("this tab stop is no longer one of the style's")
|
|
1066
1110
|
changed = _StyleTabStop(entry, self)
|
|
1067
|
-
del stops[at]
|
|
1068
|
-
to = at
|
|
1069
1111
|
if reorder:
|
|
1070
|
-
to = next((index for index, kept in enumerate(stops) if
|
|
1071
|
-
|
|
1112
|
+
to = next((index for index, kept in enumerate(stops) if changed.position < kept.position), len(stops))
|
|
1113
|
+
stops.insert(to, changed)
|
|
1114
|
+
del stops[at if at < to else at + 1]
|
|
1115
|
+
to = to - 1 if at < to else to
|
|
1116
|
+
else:
|
|
1117
|
+
stops[at] = changed
|
|
1118
|
+
to = at
|
|
1072
1119
|
self._write(stops)
|
|
1073
1120
|
|
|
1074
1121
|
def place(index: int) -> int | None:
|
|
@@ -1078,7 +1125,7 @@ class _StyleTabStops:
|
|
|
1078
1125
|
return index + (index >= to)
|
|
1079
1126
|
|
|
1080
1127
|
self._moved(place, {to: entry})
|
|
1081
|
-
stop._detached =
|
|
1128
|
+
stop._detached = None
|
|
1082
1129
|
stop._index = to
|
|
1083
1130
|
stop._entry = entry
|
|
1084
1131
|
|
|
@@ -1127,7 +1174,7 @@ class _StyleTabStops:
|
|
|
1127
1174
|
"""Remove all of the style's tab stops (its ``w:tabs``), as python-docx does."""
|
|
1128
1175
|
if self._writes():
|
|
1129
1176
|
self._write([])
|
|
1130
|
-
self._moved(lambda index: None)
|
|
1177
|
+
self._moved(lambda index: None, why=_CLEARED)
|
|
1131
1178
|
return
|
|
1132
1179
|
_warn_unwritten(
|
|
1133
1180
|
"ParagraphStyle.paragraph_format.tab_stops.clear_all",
|
|
@@ -13,6 +13,7 @@ import warnings
|
|
|
13
13
|
from typing import TYPE_CHECKING
|
|
14
14
|
|
|
15
15
|
from docx._batching import run_sync
|
|
16
|
+
from docx._proxy import ElementProxyEquality
|
|
16
17
|
from docx.enum.style import WD_STYLE_TYPE
|
|
17
18
|
from docx.styles import BabelFish
|
|
18
19
|
from docx.styles.latent import LatentStyles, PendingLatentStylesReadWarning
|
|
@@ -110,13 +111,16 @@ def _style_id_from_name(name: str) -> str:
|
|
|
110
111
|
return _SPECIAL_STYLE_IDS.get(name, name.replace(" ", ""))
|
|
111
112
|
|
|
112
113
|
|
|
113
|
-
class Styles:
|
|
114
|
+
class Styles(ElementProxyEquality):
|
|
114
115
|
"""Collection of styles. Iterable, len, __getitem__."""
|
|
115
116
|
|
|
116
117
|
def __init__(self, *, session: "Session") -> None:
|
|
117
118
|
self._session: "Session" = session
|
|
118
119
|
self._added: dict[str, BaseStyle] = {}
|
|
119
120
|
|
|
121
|
+
def _proxy_element(self) -> tuple[object, ...]:
|
|
122
|
+
return ("w:styles", self._session)
|
|
123
|
+
|
|
120
124
|
def _all(self) -> list[BaseStyle]:
|
|
121
125
|
from docx._table_styles import BUILTIN_TABLE_STYLE_IDS
|
|
122
126
|
from docx.styles._table import builtin_style_id, builtin_style_name, style_table
|