athena-python-docx 0.5.3__tar.gz → 0.6.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.5.3 → athena_python_docx-0.6.0}/PKG-INFO +1 -1
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/__init__.py +1 -1
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/enum/text.py +46 -2
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/parfmt.py +89 -5
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/tabstops.py +61 -20
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/pyproject.toml +1 -1
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/reports/GAP_ANALYSIS.md +27 -2
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/reports/gap_report.json +1650 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/snapshots/athena_latest.json +1037 -133
- athena_python_docx-0.6.0/tests/test_silent_stub_parfmt.py +367 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/.gitignore +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/CLAUDE.md +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/README.md +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/_buffer.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/_http.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/_http_doc.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/_image_utils.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/api.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/client.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/commands.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/comments.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/document.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/enum/section.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/enum/style.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/enum/table.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/errors.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/opc/coreprops.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/section.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/settings.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/shape.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/shared.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/styles/style.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/styles/styles.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/table.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/hyperlink.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/pagebreak.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/paragraph.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/text/run.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/docx/typing.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/scripts/publish.sh +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/scripts/release.sh +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/METHODOLOGY.md +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/ab_probe_cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/fake_session.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/103_cell_tables_enumeration.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/23_nested_table.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/51_nested_tables_deep.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex01_five_levels_deep_tables.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw14_nested_cell_table.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/runner.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/README.md +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/intentional_deviations.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_comments.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_document_create.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_http_transport.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_parity_misc.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_parity_round2.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_phase_a_behavior.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_phase_b_headers_footers.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_revisions.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_header_footer.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_misc.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_style.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_style_setters_contract.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_wire_contract.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/tests/test_zod_wire_contract.py +0 -0
- {athena_python_docx-0.5.3 → athena_python_docx-0.6.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Drop-in replacement for python-docx that connects to Athena's Superdoc/Keryx collaborative document stack
|
|
5
5
|
Project-URL: Homepage, https://athenaintelligence.ai
|
|
6
6
|
Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
|
|
@@ -2,14 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
Values map to Superdoc primitives where supported; unmapped values
|
|
4
4
|
(e.g. Thai/Arabic justification variants) still parse but serialize to
|
|
5
|
-
their best Superdoc equivalent
|
|
5
|
+
their best Superdoc equivalent and emit
|
|
6
|
+
:class:`PendingEnumCoercionWarning` so the caller knows the wire-level
|
|
7
|
+
intent was downgraded.
|
|
6
8
|
"""
|
|
7
9
|
|
|
8
10
|
from __future__ import annotations
|
|
9
11
|
|
|
12
|
+
import warnings
|
|
10
13
|
from enum import Enum
|
|
11
14
|
|
|
12
15
|
|
|
16
|
+
class PendingEnumCoercionWarning(UserWarning):
|
|
17
|
+
"""Emitted when an enum member's :meth:`to_superdoc` collapses the
|
|
18
|
+
value to a different SuperDoc-supported primitive.
|
|
19
|
+
|
|
20
|
+
Examples:
|
|
21
|
+
- ``WD_ALIGN_PARAGRAPH.THAI_JUSTIFY.to_superdoc()`` returns
|
|
22
|
+
``"justify"`` because SuperDoc 1.8's ``set_alignment`` rejects
|
|
23
|
+
``thaiJustify``.
|
|
24
|
+
- ``WD_TAB_ALIGNMENT.CLEAR.to_superdoc()`` returns ``"left"``
|
|
25
|
+
because SuperDoc has no equivalent clear/end/num/start tab
|
|
26
|
+
vocabulary.
|
|
27
|
+
|
|
28
|
+
Tracked in ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md``. Pin so a
|
|
29
|
+
future SuperDoc that lands the full vocabulary can flip the
|
|
30
|
+
coercion off and these warnings disappear.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _warn_enum_coercion(enum_member: object, fallback: str) -> None:
|
|
35
|
+
"""Emit a single warning identifying which enum member got
|
|
36
|
+
coerced to which SuperDoc primitive."""
|
|
37
|
+
warnings.warn(
|
|
38
|
+
f"{enum_member!r}.to_superdoc() returns {fallback!r} — "
|
|
39
|
+
f"SuperDoc 1.8 doesn't surface this value, so the wire ships "
|
|
40
|
+
f"the closest supported primitive. The visual result may "
|
|
41
|
+
f"differ from python-docx. Tracked in "
|
|
42
|
+
f"docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md.",
|
|
43
|
+
PendingEnumCoercionWarning,
|
|
44
|
+
stacklevel=3,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
13
48
|
class WD_ALIGN_PARAGRAPH(Enum):
|
|
14
49
|
"""Paragraph alignment (justification)."""
|
|
15
50
|
|
|
@@ -26,7 +61,10 @@ class WD_ALIGN_PARAGRAPH(Enum):
|
|
|
26
61
|
def to_superdoc(self) -> str:
|
|
27
62
|
# Superdoc only supports left/center/right/justify; coerce the
|
|
28
63
|
# distributed/thai variants to "justify" so set_alignment doesn't
|
|
29
|
-
# reject them.
|
|
64
|
+
# reject them. Emit PendingEnumCoercionWarning so the caller
|
|
65
|
+
# learns the wire-level intent was downgraded (silently shipping
|
|
66
|
+
# "justify" when the user asked for thaiJustify is the silent
|
|
67
|
+
# stub the parity loop is hunting).
|
|
30
68
|
if self in (
|
|
31
69
|
WD_ALIGN_PARAGRAPH.DISTRIBUTE,
|
|
32
70
|
WD_ALIGN_PARAGRAPH.JUSTIFY_MED,
|
|
@@ -34,6 +72,7 @@ class WD_ALIGN_PARAGRAPH(Enum):
|
|
|
34
72
|
WD_ALIGN_PARAGRAPH.JUSTIFY_LOW,
|
|
35
73
|
WD_ALIGN_PARAGRAPH.THAI_JUSTIFY,
|
|
36
74
|
):
|
|
75
|
+
_warn_enum_coercion(self, "justify")
|
|
37
76
|
return "justify"
|
|
38
77
|
return self.value
|
|
39
78
|
|
|
@@ -82,6 +121,10 @@ class WD_TAB_ALIGNMENT(Enum):
|
|
|
82
121
|
START = "start"
|
|
83
122
|
|
|
84
123
|
def to_superdoc(self) -> str:
|
|
124
|
+
# Superdoc only supports left/center/right/decimal/bar for tab
|
|
125
|
+
# alignment. ``LIST`` / ``CLEAR`` / ``END`` / ``NUM`` / ``START``
|
|
126
|
+
# are upstream-only — emit PendingEnumCoercionWarning so callers
|
|
127
|
+
# learn the wire-level intent was downgraded to ``"left"``.
|
|
85
128
|
if self in (
|
|
86
129
|
WD_TAB_ALIGNMENT.LIST,
|
|
87
130
|
WD_TAB_ALIGNMENT.CLEAR,
|
|
@@ -89,6 +132,7 @@ class WD_TAB_ALIGNMENT(Enum):
|
|
|
89
132
|
WD_TAB_ALIGNMENT.NUM,
|
|
90
133
|
WD_TAB_ALIGNMENT.START,
|
|
91
134
|
):
|
|
135
|
+
_warn_enum_coercion(self, "left")
|
|
92
136
|
return "left"
|
|
93
137
|
return self.value
|
|
94
138
|
|
|
@@ -11,6 +11,7 @@ Setters accept:
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
import warnings
|
|
14
15
|
from typing import TYPE_CHECKING
|
|
15
16
|
|
|
16
17
|
from docx._batching import run_sync
|
|
@@ -22,6 +23,49 @@ if TYPE_CHECKING:
|
|
|
22
23
|
from docx.text.tabstops import TabStops
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
class PendingParfmtClearWarning(UserWarning):
|
|
27
|
+
"""Emitted when a ``ParagraphFormat`` setter is asked to clear a
|
|
28
|
+
trivalent (None/True/False) property whose SuperDoc wire op
|
|
29
|
+
doesn't expose a clear primitive.
|
|
30
|
+
|
|
31
|
+
Behavior pinned for parity with python-docx 1.x semantics
|
|
32
|
+
(``None`` means "inherit from style") even though SuperDoc 1.8 can
|
|
33
|
+
only set explicit values. The setter is a no-op at the wire level
|
|
34
|
+
but emits this warning so silent inheritance-vs-set divergence
|
|
35
|
+
surfaces during agent runs. Tracked in
|
|
36
|
+
``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md``.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _warn_parfmt_clear(prop: str) -> None:
|
|
41
|
+
warnings.warn(
|
|
42
|
+
f"ParagraphFormat.{prop} = None was IGNORED — SuperDoc 1.8 "
|
|
43
|
+
f"has no clear-op for this trivalent attribute. The value "
|
|
44
|
+
f"stays whatever it was last set to (or inherited from the "
|
|
45
|
+
f"paragraph style). Tracked in "
|
|
46
|
+
f"docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md.",
|
|
47
|
+
PendingParfmtClearWarning,
|
|
48
|
+
stacklevel=3,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _require_bool(prop: str, value: object) -> bool:
|
|
53
|
+
"""Reject non-bool input for trivalent on/off properties.
|
|
54
|
+
|
|
55
|
+
``bool`` is a Python ``int`` subclass, so a bare ``True``/``False``
|
|
56
|
+
would otherwise hit any ``isinstance(value, int)`` branch first
|
|
57
|
+
and produce surprising semantics (e.g. ``line_spacing = True``
|
|
58
|
+
setting a 1× multiplier). Callers must pass real bools.
|
|
59
|
+
"""
|
|
60
|
+
if not isinstance(value, bool):
|
|
61
|
+
raise TypeError(
|
|
62
|
+
f"ParagraphFormat.{prop} requires bool (True/False/None); "
|
|
63
|
+
f"got {type(value).__name__} {value!r}. python-docx 1.x "
|
|
64
|
+
f"rejects truthy non-bool input here too.",
|
|
65
|
+
)
|
|
66
|
+
return value
|
|
67
|
+
|
|
68
|
+
|
|
25
69
|
def _to_twips(value: object) -> int:
|
|
26
70
|
"""Coerce a length-ish input to twips (int)."""
|
|
27
71
|
if value is None:
|
|
@@ -223,6 +267,16 @@ class ParagraphFormat:
|
|
|
223
267
|
if value is None:
|
|
224
268
|
self._clear_spacing()
|
|
225
269
|
return
|
|
270
|
+
# ``bool`` is a subclass of ``int`` in Python, so ``True``/``False``
|
|
271
|
+
# would otherwise silently hit the ``1 <= value <= 4`` branch
|
|
272
|
+
# (1× multiplier) or the EMU fallthrough (0). Reject upfront —
|
|
273
|
+
# python-docx 1.x raises ``TypeError`` for non-Length/numeric.
|
|
274
|
+
if isinstance(value, bool):
|
|
275
|
+
raise TypeError(
|
|
276
|
+
f"line_spacing requires float/int/Length, not bool; "
|
|
277
|
+
f"got {value!r}. Pass 1.0 / 1.5 / 2.0 for "
|
|
278
|
+
f"single/1.5×/double, or a Length for exact spacing.",
|
|
279
|
+
)
|
|
226
280
|
if isinstance(value, Length):
|
|
227
281
|
self._set_spacing(line=value.twips, lineRule="exact")
|
|
228
282
|
return
|
|
@@ -268,7 +322,13 @@ class ParagraphFormat:
|
|
|
268
322
|
from docx.enum.text import WD_LINE_SPACING
|
|
269
323
|
|
|
270
324
|
if value is None:
|
|
325
|
+
self._clear_spacing()
|
|
271
326
|
return
|
|
327
|
+
if not isinstance(value, WD_LINE_SPACING):
|
|
328
|
+
raise ValueError(
|
|
329
|
+
f"line_spacing_rule: expected WD_LINE_SPACING, got "
|
|
330
|
+
f"{type(value).__name__} {value!r}",
|
|
331
|
+
)
|
|
272
332
|
if value == WD_LINE_SPACING.SINGLE:
|
|
273
333
|
self._set_spacing(line=240, lineRule="auto")
|
|
274
334
|
elif value == WD_LINE_SPACING.ONE_POINT_FIVE:
|
|
@@ -279,6 +339,22 @@ class ParagraphFormat:
|
|
|
279
339
|
self._set_spacing(line=240, lineRule="exact")
|
|
280
340
|
elif value == WD_LINE_SPACING.AT_LEAST:
|
|
281
341
|
self._set_spacing(line=240, lineRule="atLeast")
|
|
342
|
+
elif value == WD_LINE_SPACING.MULTIPLE:
|
|
343
|
+
# MULTIPLE without an explicit numeric value is meaningless;
|
|
344
|
+
# python-docx 1.x raises ``ValueError`` for the same reason.
|
|
345
|
+
raise ValueError(
|
|
346
|
+
"line_spacing_rule = WD_LINE_SPACING.MULTIPLE is not "
|
|
347
|
+
"settable on its own — set line_spacing to a float "
|
|
348
|
+
"multiplier (e.g. 1.5) instead, which implicitly uses "
|
|
349
|
+
"the MULTIPLE rule via lineRule='auto'.",
|
|
350
|
+
)
|
|
351
|
+
else:
|
|
352
|
+
# Defensive: any new enum member we haven't mapped to a wire
|
|
353
|
+
# primitive should surface as ValueError, not silently no-op.
|
|
354
|
+
raise ValueError(
|
|
355
|
+
f"line_spacing_rule: unsupported WD_LINE_SPACING "
|
|
356
|
+
f"member {value!r} — no wire mapping in athena-python-docx.",
|
|
357
|
+
)
|
|
282
358
|
|
|
283
359
|
# ---- keep / widow ----
|
|
284
360
|
@property
|
|
@@ -290,8 +366,9 @@ class ParagraphFormat:
|
|
|
290
366
|
@keep_together.setter
|
|
291
367
|
def keep_together(self, value: bool | None) -> None:
|
|
292
368
|
if value is None:
|
|
369
|
+
_warn_parfmt_clear("keep_together")
|
|
293
370
|
return
|
|
294
|
-
self._set_keep(keepLines=
|
|
371
|
+
self._set_keep(keepLines=_require_bool("keep_together", value))
|
|
295
372
|
|
|
296
373
|
@property
|
|
297
374
|
def keep_with_next(self) -> bool | None:
|
|
@@ -302,8 +379,9 @@ class ParagraphFormat:
|
|
|
302
379
|
@keep_with_next.setter
|
|
303
380
|
def keep_with_next(self, value: bool | None) -> None:
|
|
304
381
|
if value is None:
|
|
382
|
+
_warn_parfmt_clear("keep_with_next")
|
|
305
383
|
return
|
|
306
|
-
self._set_keep(keepNext=
|
|
384
|
+
self._set_keep(keepNext=_require_bool("keep_with_next", value))
|
|
307
385
|
|
|
308
386
|
@property
|
|
309
387
|
def widow_control(self) -> bool | None:
|
|
@@ -314,8 +392,9 @@ class ParagraphFormat:
|
|
|
314
392
|
@widow_control.setter
|
|
315
393
|
def widow_control(self, value: bool | None) -> None:
|
|
316
394
|
if value is None:
|
|
395
|
+
_warn_parfmt_clear("widow_control")
|
|
317
396
|
return
|
|
318
|
-
self._set_keep(widowControl=
|
|
397
|
+
self._set_keep(widowControl=_require_bool("widow_control", value))
|
|
319
398
|
|
|
320
399
|
@property
|
|
321
400
|
def page_break_before(self) -> bool | None:
|
|
@@ -326,11 +405,16 @@ class ParagraphFormat:
|
|
|
326
405
|
@page_break_before.setter
|
|
327
406
|
def page_break_before(self, value: bool | None) -> None:
|
|
328
407
|
if value is None:
|
|
408
|
+
_warn_parfmt_clear("page_break_before")
|
|
329
409
|
return
|
|
330
|
-
# Superdoc's setFlowOptions handles pageBreakBefore
|
|
410
|
+
# Superdoc's setFlowOptions handles pageBreakBefore.
|
|
411
|
+
# Reject non-bool to keep parity with python-docx 1.x's strict
|
|
412
|
+
# ``_OnOff`` handling — ``bool(non_bool_value)`` silently coerces
|
|
413
|
+
# garbage to True.
|
|
414
|
+
coerced: bool = _require_bool("page_break_before", value)
|
|
331
415
|
run_sync(
|
|
332
416
|
self._paragraph._session.doc.format.paragraph.set_flow_options(
|
|
333
|
-
{"target": self._target(), "pageBreakBefore":
|
|
417
|
+
{"target": self._target(), "pageBreakBefore": coerced},
|
|
334
418
|
),
|
|
335
419
|
)
|
|
336
420
|
|
|
@@ -23,6 +23,59 @@ if TYPE_CHECKING:
|
|
|
23
23
|
from docx.text.parfmt import ParagraphFormat
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def _coerce_alignment(value: object) -> str:
|
|
27
|
+
"""Coerce ``WD_TAB_ALIGNMENT`` or its string form to the SuperDoc
|
|
28
|
+
wire value, rejecting anything else.
|
|
29
|
+
|
|
30
|
+
Previously the setter / factory accepted ``str(value)`` for any
|
|
31
|
+
input, shipping bogus alignment strings to the wire (SuperDoc
|
|
32
|
+
silently fell back to ``left``). python-docx 1.x validates against
|
|
33
|
+
the enum at the XML serialization layer.
|
|
34
|
+
"""
|
|
35
|
+
if isinstance(value, WD_TAB_ALIGNMENT):
|
|
36
|
+
return value.to_superdoc()
|
|
37
|
+
if isinstance(value, str):
|
|
38
|
+
try:
|
|
39
|
+
return WD_TAB_ALIGNMENT(value).to_superdoc()
|
|
40
|
+
except ValueError as e:
|
|
41
|
+
raise ValueError(
|
|
42
|
+
f"Tab stop alignment {value!r} is not a valid "
|
|
43
|
+
f"WD_TAB_ALIGNMENT value. Expected one of "
|
|
44
|
+
f"{[m.value for m in WD_TAB_ALIGNMENT]} or a "
|
|
45
|
+
f"WD_TAB_ALIGNMENT enum member.",
|
|
46
|
+
) from e
|
|
47
|
+
raise TypeError(
|
|
48
|
+
f"Tab stop alignment must be WD_TAB_ALIGNMENT or str; "
|
|
49
|
+
f"got {type(value).__name__} {value!r}",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _coerce_leader(value: object) -> str:
|
|
54
|
+
"""Coerce ``WD_TAB_LEADER`` or its string form to the SuperDoc
|
|
55
|
+
wire value, rejecting anything else.
|
|
56
|
+
|
|
57
|
+
Same rationale as :func:`_coerce_alignment` — the prior
|
|
58
|
+
``str(value)`` accept-anything path silently shipped bogus leader
|
|
59
|
+
values that SuperDoc swallowed.
|
|
60
|
+
"""
|
|
61
|
+
if isinstance(value, WD_TAB_LEADER):
|
|
62
|
+
return value.to_superdoc()
|
|
63
|
+
if isinstance(value, str):
|
|
64
|
+
try:
|
|
65
|
+
return WD_TAB_LEADER(value).to_superdoc()
|
|
66
|
+
except ValueError as e:
|
|
67
|
+
raise ValueError(
|
|
68
|
+
f"Tab stop leader {value!r} is not a valid "
|
|
69
|
+
f"WD_TAB_LEADER value. Expected one of "
|
|
70
|
+
f"{[m.value for m in WD_TAB_LEADER]} or a "
|
|
71
|
+
f"WD_TAB_LEADER enum member.",
|
|
72
|
+
) from e
|
|
73
|
+
raise TypeError(
|
|
74
|
+
f"Tab stop leader must be WD_TAB_LEADER or str; "
|
|
75
|
+
f"got {type(value).__name__} {value!r}",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
26
79
|
class TabStop:
|
|
27
80
|
"""A single tab stop entry. Returned by :class:`TabStops` iteration
|
|
28
81
|
and by :meth:`TabStops.add_tab_stop`.
|
|
@@ -63,12 +116,7 @@ class TabStop:
|
|
|
63
116
|
|
|
64
117
|
@alignment.setter
|
|
65
118
|
def alignment(self, value: "WD_TAB_ALIGNMENT | str") -> None:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if isinstance(value, WD_TAB_ALIGNMENT):
|
|
69
|
-
self._data["alignment"] = value.to_superdoc()
|
|
70
|
-
else:
|
|
71
|
-
self._data["alignment"] = str(value)
|
|
119
|
+
self._data["alignment"] = _coerce_alignment(value)
|
|
72
120
|
self._parent._rewrite_from_data([s._data for s in self._parent._stops()])
|
|
73
121
|
|
|
74
122
|
@property
|
|
@@ -83,12 +131,7 @@ class TabStop:
|
|
|
83
131
|
|
|
84
132
|
@leader.setter
|
|
85
133
|
def leader(self, value: "WD_TAB_LEADER | str") -> None:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if isinstance(value, WD_TAB_LEADER):
|
|
89
|
-
self._data["leader"] = value.to_superdoc()
|
|
90
|
-
else:
|
|
91
|
-
self._data["leader"] = str(value)
|
|
134
|
+
self._data["leader"] = _coerce_leader(value)
|
|
92
135
|
self._parent._rewrite_from_data([s._data for s in self._parent._stops()])
|
|
93
136
|
|
|
94
137
|
|
|
@@ -170,15 +213,13 @@ class TabStops:
|
|
|
170
213
|
|
|
171
214
|
``alignment`` defaults to ``WD_TAB_ALIGNMENT.LEFT``, ``leader``
|
|
172
215
|
defaults to ``WD_TAB_LEADER.SPACES`` — matching python-docx.
|
|
216
|
+
Bogus enum-equivalent strings now raise ``ValueError``; a
|
|
217
|
+
non-enum/non-str input raises ``TypeError``. Previously any
|
|
218
|
+
``str(value)`` was shipped to the wire and SuperDoc silently
|
|
219
|
+
fell back to defaults.
|
|
173
220
|
"""
|
|
174
|
-
align_val: str = (
|
|
175
|
-
|
|
176
|
-
if isinstance(alignment, WD_TAB_ALIGNMENT)
|
|
177
|
-
else str(alignment)
|
|
178
|
-
)
|
|
179
|
-
leader_val: str = (
|
|
180
|
-
leader.to_superdoc() if isinstance(leader, WD_TAB_LEADER) else str(leader)
|
|
181
|
-
)
|
|
221
|
+
align_val: str = _coerce_alignment(alignment)
|
|
222
|
+
leader_val: str = _coerce_leader(leader)
|
|
182
223
|
pos_twips: int = _to_twips(position)
|
|
183
224
|
run_sync(
|
|
184
225
|
self._parfmt._paragraph._session.doc.format.paragraph.set_tab_stop(
|
|
@@ -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.6.0"
|
|
8
8
|
description = "Drop-in replacement for python-docx that connects to Athena's Superdoc/Keryx collaborative document stack"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -10,10 +10,10 @@ Comparing **athena-python-docx 0.5.2** (39 modules) against **python-docx 1.2.0*
|
|
|
10
10
|
| `class_missing` | 201 | 0 | 201 |
|
|
11
11
|
| `member_missing` | 71 | 0 | 71 |
|
|
12
12
|
| `member_kind_drift` | 0 | 0 | 0 |
|
|
13
|
-
| `ctor_signature_drift` |
|
|
13
|
+
| `ctor_signature_drift` | 57 | 0 | 57 |
|
|
14
14
|
| `signature_drift` | 1 | 0 | 1 |
|
|
15
15
|
| `return_annotation_drift` | 0 | 0 | 0 |
|
|
16
|
-
| **TOTAL** | **
|
|
16
|
+
| **TOTAL** | **397** | **0** | **397** |
|
|
17
17
|
|
|
18
18
|
## Intentional deviations (filtered out)
|
|
19
19
|
|
|
@@ -22,6 +22,31 @@ These are documented as intentional in `tests/parity/intentional_deviations.json
|
|
|
22
22
|
- `docx.comments.Comment` (ctor_signature_drift)
|
|
23
23
|
- `docx.comments.Comments` (ctor_signature_drift)
|
|
24
24
|
- `docx.document.Document` (ctor_signature_drift)
|
|
25
|
+
- `docx.enum.section.WD_HEADER_FOOTER` (ctor_signature_drift)
|
|
26
|
+
- `docx.enum.section.WD_HEADER_FOOTER_INDEX` (ctor_signature_drift)
|
|
27
|
+
- `docx.enum.section.WD_ORIENT` (ctor_signature_drift)
|
|
28
|
+
- `docx.enum.section.WD_ORIENTATION` (ctor_signature_drift)
|
|
29
|
+
- `docx.enum.section.WD_SECTION` (ctor_signature_drift)
|
|
30
|
+
- `docx.enum.section.WD_SECTION_START` (ctor_signature_drift)
|
|
31
|
+
- `docx.enum.style.WD_BUILTIN_STYLE` (ctor_signature_drift)
|
|
32
|
+
- `docx.enum.style.WD_STYLE` (ctor_signature_drift)
|
|
33
|
+
- `docx.enum.style.WD_STYLE_TYPE` (ctor_signature_drift)
|
|
34
|
+
- `docx.enum.table.WD_ALIGN_VERTICAL` (ctor_signature_drift)
|
|
35
|
+
- `docx.enum.table.WD_CELL_VERTICAL_ALIGNMENT` (ctor_signature_drift)
|
|
36
|
+
- `docx.enum.table.WD_ROW_HEIGHT` (ctor_signature_drift)
|
|
37
|
+
- `docx.enum.table.WD_ROW_HEIGHT_RULE` (ctor_signature_drift)
|
|
38
|
+
- `docx.enum.table.WD_TABLE_ALIGNMENT` (ctor_signature_drift)
|
|
39
|
+
- `docx.enum.table.WD_TABLE_DIRECTION` (ctor_signature_drift)
|
|
40
|
+
- `docx.enum.text.WD_ALIGN_PARAGRAPH` (ctor_signature_drift)
|
|
41
|
+
- `docx.enum.text.WD_BREAK` (ctor_signature_drift)
|
|
42
|
+
- `docx.enum.text.WD_BREAK_TYPE` (ctor_signature_drift)
|
|
43
|
+
- `docx.enum.text.WD_COLOR` (ctor_signature_drift)
|
|
44
|
+
- `docx.enum.text.WD_COLOR_INDEX` (ctor_signature_drift)
|
|
45
|
+
- `docx.enum.text.WD_LINE_SPACING` (ctor_signature_drift)
|
|
46
|
+
- `docx.enum.text.WD_PARAGRAPH_ALIGNMENT` (ctor_signature_drift)
|
|
47
|
+
- `docx.enum.text.WD_TAB_ALIGNMENT` (ctor_signature_drift)
|
|
48
|
+
- `docx.enum.text.WD_TAB_LEADER` (ctor_signature_drift)
|
|
49
|
+
- `docx.enum.text.WD_UNDERLINE` (ctor_signature_drift)
|
|
25
50
|
- `docx.opc.coreprops.CoreProperties` (ctor_signature_drift)
|
|
26
51
|
- `docx.section.Section` (ctor_signature_drift)
|
|
27
52
|
- `docx.section.Sections` (ctor_signature_drift)
|