athena-python-docx 0.42.1__tar.gz → 0.43.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.42.1 → athena_python_docx-0.43.0}/PKG-INFO +1 -1
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/__init__.py +1 -1
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_http.py +32 -32
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/document.py +9 -2
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/pyproject.toml +1 -1
- athena_python_docx-0.43.0/tests/test_create_workspace.py +82 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_create.py +32 -15
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_create_from_template.py +84 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/uv.lock +1 -1
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/.gitignore +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/AGENTS.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/CLAUDE.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/DOCX_EXEC_LAB.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/README.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_buffer.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_capabilities.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_citations.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_execution.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_http_doc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_image_utils.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_postproc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_proxy.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_references.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_run_order.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_timeouts.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_tracked.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/_xml_text.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/api.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/blkcntnr.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/bookmarks.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/charts.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/client.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/commands.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/comments.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/drawing/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/base.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/dml.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/section.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/shape.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/style.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/table.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/enum/text.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/errors.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/fields.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/footnotes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/image/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/image/exceptions.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/image/image.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/math.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/opc/coreprops.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/oxml/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/sdt.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/section.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/session.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/settings.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/shape.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/shared.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/styles/_table.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/styles/latent.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/styles/style.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/styles/styles.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/table.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/hyperlink.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/pagebreak.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/paragraph.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/parfmt.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/run.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/text/tabstops.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/toc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/docx/typing.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/docx_exec_lab.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/dump_wire_fixtures.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/release.sh +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/smoke_test_block_not_found.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/scripts/validate_find_replace_asset.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/METHODOLOGY.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/agent_documents.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/default_style_run_formatting.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/header_footer_pictures.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/less_used_writes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/merged_cell_identity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/paragraph_text_setter.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/picture_runs.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/proxy_equality.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/return_types.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/xml_incompatible_text.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe/zero_and_negative_indents.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/fake_session.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/firm_templates/README.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/firm_templates/_runner.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/firm_templates/extractor.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fixtures/field_reads.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fixtures/note_reference_reads.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fixtures/ruby_reads.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/fixtures/symbol_reads.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/baseline.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/fixture_scripts.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/reader.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/runner.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/sdk_driver.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/stock_driver.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/live/test_live_runner.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/README.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/intentional_deviations.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/reports/gap_report.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/snapshots/athena_latest.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_add_section.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_add_section_extract_items.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_alignment_values.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_athena_extension_creates_session_open.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_athena_extensions_registry.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_batch_chunking.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_battery_cases.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_block_not_found_error.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_add_table_not_supported.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_borders_spec.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_fastpath_runs.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_inner_format_stash.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_inner_run_format_stash.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_inner_run_guard.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_merge.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_nested_tables.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_paragraphs_listed.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_text_plain_fastpath.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_cell_text_replace_semantics.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_citations.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_collapsed_range_format.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_color_format_theme.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_comment_paragraphs.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_comments.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_comments_first_read.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_content_control_value.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_core_properties.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_clear.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_factory_validation.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_settings_session_open.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_docx_exec_lab.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_drawing_image.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_empty_hyperlinks.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_enum_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_execution_scope.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_export_docx_clean.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_export_rescue_anchors.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_field_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_field_refresh.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_field_runs.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_find_replace_session_open.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_flushed_write_failures.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_http_transport.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_hyperlink_coalescing.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_image_url_data_uri.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_inline_page_break.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_inline_shape_alt_text.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_inline_shape_size.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_inline_shape_type.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_inline_shapes_floating.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_latent_style_writes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_line_clear_break.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_list_styles.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_listed_paragraph_reads.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_literal_no_break_hyphens.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_literal_soft_hyphens.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_merged_cell_identity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_merged_cell_secondary_slot.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_missing_modules.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_nested_table_refused.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_page_break.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_paragraph_delete.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_paragraph_indent_reads.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_paragraph_runs_hyperlinks.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_paragraph_text_empty_run.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_parfmt_clears.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_parity_misc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_parity_round2.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_pdf_export_and_page_renders.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_phase_a_behavior.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_phase_b_headers_footers.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_positional_cell_id.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_postproc_cell_format_rewrite.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_postproc_ref_restore.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_proxy_equality.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_read_run_ranges.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_rendered_page_breaks.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_repeated_node_read.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_restart_numbering.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_revisions.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_round_trip_smoke_script.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_ruby_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_add_picture_anchor.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_break_inner_content.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_edges.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_formatting_wire.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_identity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_later_runs.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_mark_inheritance.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_page_number_blocks.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_table_style_objects.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_text_python_docx.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_text_refreshes_paragraph.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_run_unmodeled_toggles.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_sdk_reads_served.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_section_read_lengths.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_sections_empty_list.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_enum_section.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_header_footer.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_inline_shape.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_misc.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_parfmt.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_row_col_cell.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_run_style.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_run_style_strict.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_run_text.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_run_underline.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_section_dimensions.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_section_onoff.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_style.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_silent_stub_table_layout.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_delete.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_formatting_writes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_metadata_writes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_names.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_resolution.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_setters_contract.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_tab_stops.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_style_tab_stops_read.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_symbol_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_tab_stop_writes.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_add_row_grid_row.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_anchors.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_clears.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_direction.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_length_reads.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_listing_reads.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_read_reuse.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_set_cell_perf.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_table_style_id_resolution.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_text_control_characters.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_tracked_revisions_offsets.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_unmapped_alignment_reads.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_uv_lock_version.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_validate_find_replace_asset_script.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_versioned_read_reuse.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_wire_contract.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_xml_attr_guard.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_xml_incompatible_text.py +0 -0
- {athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_zod_wire_contract.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.43.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>
|
|
@@ -38,6 +38,20 @@ _API_KEY_ENV = "ATHENA_DOCX_API_KEY" # noqa: S105
|
|
|
38
38
|
_AGORA_BASE_URL_ENV = "ATHENA_AGORA_BASE_URL"
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
def _resolve_api_key(api_key: str | None) -> str | None:
|
|
42
|
+
"""The key a create or upload sends: ``api_key``, else the studio key.
|
|
43
|
+
|
|
44
|
+
``ATHENA_DOCX_API_KEY`` comes first, as on every other call this SDK
|
|
45
|
+
makes. Both create paths land outside Athena's public API (docx-studio's
|
|
46
|
+
``/docs/empty``, agora's ``/api/docx-studio/assets``), and inside an Athena
|
|
47
|
+
session VM or computer ``ATHENA_API_KEY`` is a credential only that public
|
|
48
|
+
API (``/api/v0``) accepts. ``ATHENA_API_KEY`` stays the fallback for an
|
|
49
|
+
environment that sets no studio key (local use with one personal key).
|
|
50
|
+
The new document is owned by the user the key belongs to.
|
|
51
|
+
"""
|
|
52
|
+
return api_key or os.environ.get(_API_KEY_ENV) or os.environ.get("ATHENA_API_KEY")
|
|
53
|
+
|
|
54
|
+
|
|
41
55
|
def _derive_agora_base_url(docx_base_url: str) -> str | None:
|
|
42
56
|
"""Best-effort derive an Agora base URL from a docx-studio base URL.
|
|
43
57
|
|
|
@@ -99,11 +113,11 @@ def create_empty_document(
|
|
|
99
113
|
Falls back to ``$ATHENA_DOCX_BASE_URL``.
|
|
100
114
|
api_key: Athena API key (PropelAuth user API key) or PropelAuth
|
|
101
115
|
access token. Sent as ``Authorization: Bearer <api_key>``.
|
|
102
|
-
Falls back to ``$ATHENA_DOCX_API_KEY``.
|
|
116
|
+
Falls back to ``$ATHENA_DOCX_API_KEY``, then ``$ATHENA_API_KEY``.
|
|
103
117
|
name: Optional display title.
|
|
104
118
|
parent_folder_id: Optional parent folder; defaults to workspace root.
|
|
105
|
-
workspace_id: Optional workspace UUID; defaults to
|
|
106
|
-
current workspace.
|
|
119
|
+
workspace_id: Optional workspace UUID; defaults to the sandbox run's
|
|
120
|
+
ATHENA_WORKSPACE_ID, then the caller's current workspace.
|
|
107
121
|
timeout: Request timeout in seconds.
|
|
108
122
|
|
|
109
123
|
Returns:
|
|
@@ -115,17 +129,7 @@ def create_empty_document(
|
|
|
115
129
|
DocxError: any other 4xx/5xx from the server.
|
|
116
130
|
"""
|
|
117
131
|
resolved_base: str | None = base_url or os.environ.get(_BASE_URL_ENV)
|
|
118
|
-
|
|
119
|
-
# is the user, not a service identity. ``ATHENA_API_KEY`` is the canonical
|
|
120
|
-
# per-user Athena key (a local API key in BYO/SSO mode that agora resolves to
|
|
121
|
-
# the real user); the docx-studio studio key (``ATHENA_DOCX_API_KEY``) is a
|
|
122
|
-
# deployment service credential used only for studio access-checks on
|
|
123
|
-
# EXISTING assets, and agora's create gate rejects it (no backing user). So
|
|
124
|
-
# prefer the user key here; only fall back to the studio key for callers that
|
|
125
|
-
# set just that.
|
|
126
|
-
resolved_key: str | None = (
|
|
127
|
-
api_key or os.environ.get("ATHENA_API_KEY") or os.environ.get(_API_KEY_ENV)
|
|
128
|
-
)
|
|
132
|
+
resolved_key: str | None = _resolve_api_key(api_key)
|
|
129
133
|
|
|
130
134
|
if not resolved_base:
|
|
131
135
|
raise SessionError(
|
|
@@ -149,8 +153,9 @@ def create_empty_document(
|
|
|
149
153
|
body["name"] = name
|
|
150
154
|
if parent_folder_id is not None:
|
|
151
155
|
body["parentFolderId"] = parent_folder_id
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
resolved_workspace = workspace_id or os.environ.get("ATHENA_WORKSPACE_ID")
|
|
157
|
+
if resolved_workspace:
|
|
158
|
+
body["workspaceId"] = resolved_workspace
|
|
154
159
|
|
|
155
160
|
# Lazy import — _http is loaded lazily by Document.create(), so the
|
|
156
161
|
# package is fully initialized by the time we reach this code.
|
|
@@ -232,6 +237,7 @@ def upload_document(
|
|
|
232
237
|
name: str | None = None,
|
|
233
238
|
parent_folder_id: str | None = None,
|
|
234
239
|
workspace_id: str | None = None,
|
|
240
|
+
source_asset_id: str | None = None,
|
|
235
241
|
timeout: float = 120.0,
|
|
236
242
|
) -> UploadAssetResult:
|
|
237
243
|
"""Upload a local ``.docx`` to agora and create a new Word document asset.
|
|
@@ -247,11 +253,12 @@ def upload_document(
|
|
|
247
253
|
agora_base_url: Explicit Agora base URL. Falls back to
|
|
248
254
|
``$ATHENA_AGORA_BASE_URL`` and finally to a host substitution
|
|
249
255
|
of ``docx-studio`` → ``agora`` against ``docx_base_url``.
|
|
250
|
-
api_key: Athena API key. Falls back to ``$ATHENA_DOCX_API_KEY
|
|
256
|
+
api_key: Athena API key. Falls back to ``$ATHENA_DOCX_API_KEY``, then
|
|
257
|
+
``$ATHENA_API_KEY``.
|
|
251
258
|
name: Optional asset title (defaults to the file's stem).
|
|
252
259
|
parent_folder_id: Optional parent folder for the new asset.
|
|
253
|
-
workspace_id: Optional workspace UUID; defaults to the
|
|
254
|
-
current workspace
|
|
260
|
+
workspace_id: Optional workspace UUID; defaults to the sandbox run's
|
|
261
|
+
ATHENA_WORKSPACE_ID, then the caller's current workspace in Agora.
|
|
255
262
|
timeout: Request timeout in seconds (uploads can be slow for big
|
|
256
263
|
decks/templates).
|
|
257
264
|
|
|
@@ -267,17 +274,7 @@ def upload_document(
|
|
|
267
274
|
import os
|
|
268
275
|
|
|
269
276
|
resolved_docx_base: str | None = docx_base_url or os.environ.get(_BASE_URL_ENV)
|
|
270
|
-
|
|
271
|
-
# is the user, not a service identity. ``ATHENA_API_KEY`` is the canonical
|
|
272
|
-
# per-user Athena key (a local API key in BYO/SSO mode that agora resolves to
|
|
273
|
-
# the real user); the docx-studio studio key (``ATHENA_DOCX_API_KEY``) is a
|
|
274
|
-
# deployment service credential used only for studio access-checks on
|
|
275
|
-
# EXISTING assets, and agora's create gate rejects it (no backing user). So
|
|
276
|
-
# prefer the user key here; only fall back to the studio key for callers that
|
|
277
|
-
# set just that.
|
|
278
|
-
resolved_key: str | None = (
|
|
279
|
-
api_key or os.environ.get("ATHENA_API_KEY") or os.environ.get(_API_KEY_ENV)
|
|
280
|
-
)
|
|
277
|
+
resolved_key: str | None = _resolve_api_key(api_key)
|
|
281
278
|
resolved_agora_base: str | None = (
|
|
282
279
|
agora_base_url
|
|
283
280
|
or os.environ.get(_AGORA_BASE_URL_ENV)
|
|
@@ -323,10 +320,13 @@ def upload_document(
|
|
|
323
320
|
"seed_author": "requester",
|
|
324
321
|
"seed_template": False,
|
|
325
322
|
}
|
|
323
|
+
if source_asset_id is not None:
|
|
324
|
+
create_body["source_asset_id"] = source_asset_id
|
|
326
325
|
if parent_folder_id is not None:
|
|
327
326
|
create_body["parent_folder_id"] = parent_folder_id
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
resolved_workspace = workspace_id or os.environ.get("ATHENA_WORKSPACE_ID")
|
|
328
|
+
if resolved_workspace:
|
|
329
|
+
create_body["workspace_id"] = resolved_workspace
|
|
330
330
|
|
|
331
331
|
create_url: str = resolved_agora_base.rstrip("/") + "/api/docx-studio/assets"
|
|
332
332
|
|
|
@@ -259,6 +259,7 @@ class Document:
|
|
|
259
259
|
track_revisions: bool = False,
|
|
260
260
|
docx: str | None = None,
|
|
261
261
|
agora_base_url: str | None = None,
|
|
262
|
+
source_asset_id: str | None = None,
|
|
262
263
|
) -> "Document":
|
|
263
264
|
"""Create a new Word document asset and return an opened Document.
|
|
264
265
|
|
|
@@ -279,9 +280,14 @@ class Document:
|
|
|
279
280
|
base_url: docx-studio API base URL. Falls back to
|
|
280
281
|
``$ATHENA_DOCX_BASE_URL``.
|
|
281
282
|
api_key: Athena API key (PropelAuth user API key) or
|
|
282
|
-
access token. Falls back to ``$ATHENA_DOCX_API_KEY
|
|
283
|
+
access token. Falls back to ``$ATHENA_DOCX_API_KEY``, then
|
|
284
|
+
``$ATHENA_API_KEY``, as every other call does; the upload path
|
|
285
|
+
(``docx=``) sends the same key to agora.
|
|
283
286
|
parent_folder_id: Optional parent folder; defaults to
|
|
284
|
-
|
|
287
|
+
the source document's folder when source_asset_id is set,
|
|
288
|
+
otherwise workspace root.
|
|
289
|
+
source_asset_id: Original asset when creating a copy from an export.
|
|
290
|
+
Agora checks source access and destination edit permission.
|
|
285
291
|
workspace_id: Optional workspace UUID; defaults to the
|
|
286
292
|
caller's current workspace as resolved by Agora.
|
|
287
293
|
docx: Optional path to a local ``.docx`` file. When provided,
|
|
@@ -325,6 +331,7 @@ class Document:
|
|
|
325
331
|
name=name,
|
|
326
332
|
parent_folder_id=parent_folder_id,
|
|
327
333
|
workspace_id=workspace_id,
|
|
334
|
+
source_asset_id=source_asset_id,
|
|
328
335
|
)
|
|
329
336
|
asset_id = upload_result["asset_id"]
|
|
330
337
|
else:
|
|
@@ -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.43.0"
|
|
8
8
|
description = "Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""A sandbox create carries its run's workspace through both HTTP paths."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import io
|
|
6
|
+
import json
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from unittest.mock import patch
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
from docx._http import create_empty_document, upload_document
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.mark.parametrize("upload", [False, True])
|
|
16
|
+
@pytest.mark.parametrize(
|
|
17
|
+
("run_workspace", "explicit_workspace", "expected_workspace"),
|
|
18
|
+
[
|
|
19
|
+
("workspace_A", None, "workspace_A"),
|
|
20
|
+
("workspace_A", "", "workspace_A"),
|
|
21
|
+
("workspace_A", "workspace_explicit", "workspace_explicit"),
|
|
22
|
+
(None, None, None),
|
|
23
|
+
("", None, None),
|
|
24
|
+
],
|
|
25
|
+
)
|
|
26
|
+
def test_create_workspace(
|
|
27
|
+
*,
|
|
28
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
29
|
+
tmp_path: Path,
|
|
30
|
+
upload: bool,
|
|
31
|
+
run_workspace: str | None,
|
|
32
|
+
explicit_workspace: str | None,
|
|
33
|
+
expected_workspace: str | None,
|
|
34
|
+
) -> None:
|
|
35
|
+
if run_workspace is None:
|
|
36
|
+
monkeypatch.delenv("ATHENA_WORKSPACE_ID", raising=False)
|
|
37
|
+
else:
|
|
38
|
+
monkeypatch.setenv("ATHENA_WORKSPACE_ID", run_workspace)
|
|
39
|
+
created = json.dumps(
|
|
40
|
+
{
|
|
41
|
+
"assetId": "asset_new",
|
|
42
|
+
"asset_id": "asset_new",
|
|
43
|
+
"name": "Memo",
|
|
44
|
+
"workspaceId": "workspace_B",
|
|
45
|
+
}
|
|
46
|
+
).encode()
|
|
47
|
+
with patch(
|
|
48
|
+
"docx._http.urllib.request.urlopen",
|
|
49
|
+
side_effect=[
|
|
50
|
+
io.BytesIO(created),
|
|
51
|
+
io.BytesIO(b'{"asset_id": "asset_new", "seeded": true}'),
|
|
52
|
+
],
|
|
53
|
+
) as urlopen:
|
|
54
|
+
if upload:
|
|
55
|
+
source = tmp_path / "memo.docx"
|
|
56
|
+
source.write_bytes(b"PK\x03\x04template")
|
|
57
|
+
upload_document(
|
|
58
|
+
docx_path=str(source),
|
|
59
|
+
docx_base_url="https://docx.example",
|
|
60
|
+
agora_base_url="https://api.example",
|
|
61
|
+
api_key="user-key",
|
|
62
|
+
workspace_id=explicit_workspace,
|
|
63
|
+
parent_folder_id="asset_folder_A",
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
create_empty_document(
|
|
67
|
+
base_url="https://docx.example",
|
|
68
|
+
api_key="user-key",
|
|
69
|
+
workspace_id=explicit_workspace,
|
|
70
|
+
parent_folder_id="asset_folder_A",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
request = urlopen.call_args_list[0].args[0]
|
|
74
|
+
body = json.loads(request.data)
|
|
75
|
+
workspace_key = "workspace_id" if upload else "workspaceId"
|
|
76
|
+
folder_key = "parent_folder_id" if upload else "parentFolderId"
|
|
77
|
+
if expected_workspace is None:
|
|
78
|
+
assert workspace_key not in body
|
|
79
|
+
else:
|
|
80
|
+
assert body[workspace_key] == expected_workspace
|
|
81
|
+
assert body[folder_key] == "asset_folder_A"
|
|
82
|
+
assert request.get_header("Authorization") == "Bearer user-key"
|
|
@@ -201,45 +201,45 @@ def test_create_outside_a_run_sends_no_attributions(
|
|
|
201
201
|
assert "x-custom-attributions" not in captured["headers"]
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
def
|
|
204
|
+
def test_create_sends_the_studio_key_not_athena_api_key(
|
|
205
205
|
monkeypatch: pytest.MonkeyPatch,
|
|
206
206
|
) -> None:
|
|
207
|
-
"""create()
|
|
207
|
+
"""create() sends docx-studio its own key, ``ATHENA_DOCX_API_KEY``.
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
(``
|
|
211
|
-
|
|
212
|
-
user — the studio key is a deployment service credential that agora's
|
|
213
|
-
create gate rejects (no backing user).
|
|
209
|
+
Inside an Athena session VM or computer ``ATHENA_API_KEY`` is a credential
|
|
210
|
+
only Athena's public API (``/api/v0``) accepts; docx-studio would refuse
|
|
211
|
+
it. Both keys are set there, and the studio key is the person's own.
|
|
214
212
|
"""
|
|
215
213
|
monkeypatch.setenv(
|
|
216
214
|
"ATHENA_DOCX_BASE_URL",
|
|
217
215
|
"https://docx-studio.stg.athenaintel.com",
|
|
218
216
|
)
|
|
219
|
-
monkeypatch.setenv("ATHENA_DOCX_API_KEY", "studio-
|
|
220
|
-
monkeypatch.setenv("ATHENA_API_KEY", "
|
|
217
|
+
monkeypatch.setenv("ATHENA_DOCX_API_KEY", "studio-key")
|
|
218
|
+
monkeypatch.setenv("ATHENA_API_KEY", "athsvm_public-api-only")
|
|
221
219
|
captured: dict[str, Any] = {}
|
|
222
220
|
|
|
223
221
|
def _capture(req: Any, **_kwargs: Any) -> _FakeResponse:
|
|
222
|
+
captured["url"] = req.full_url
|
|
224
223
|
captured["headers"] = dict(req.headers)
|
|
225
224
|
return _FakeResponse(json.dumps(_FAKE_RESPONSE).encode("utf-8"))
|
|
226
225
|
|
|
227
226
|
with patch("docx._http.urllib.request.urlopen", side_effect=_capture):
|
|
228
227
|
Document.create(name="X")
|
|
229
228
|
|
|
230
|
-
assert captured["
|
|
229
|
+
assert captured["url"] == "https://docx-studio.stg.athenaintel.com/docs/empty"
|
|
230
|
+
assert captured["headers"]["Authorization"] == "Bearer studio-key"
|
|
231
231
|
|
|
232
232
|
|
|
233
|
-
def
|
|
233
|
+
def test_create_falls_back_to_athena_api_key_without_a_studio_key(
|
|
234
234
|
monkeypatch: pytest.MonkeyPatch,
|
|
235
235
|
) -> None:
|
|
236
|
-
"""With only
|
|
236
|
+
"""With only ``ATHENA_API_KEY`` set (local use), create authenticates with it."""
|
|
237
237
|
monkeypatch.setenv(
|
|
238
238
|
"ATHENA_DOCX_BASE_URL",
|
|
239
239
|
"https://docx-studio.stg.athenaintel.com",
|
|
240
240
|
)
|
|
241
|
-
monkeypatch.
|
|
242
|
-
monkeypatch.
|
|
241
|
+
monkeypatch.delenv("ATHENA_DOCX_API_KEY", raising=False)
|
|
242
|
+
monkeypatch.setenv("ATHENA_API_KEY", "personal-key")
|
|
243
243
|
captured: dict[str, Any] = {}
|
|
244
244
|
|
|
245
245
|
def _capture(req: Any, **_kwargs: Any) -> _FakeResponse:
|
|
@@ -249,4 +249,21 @@ def test_create_falls_back_to_studio_key_without_user_key(
|
|
|
249
249
|
with patch("docx._http.urllib.request.urlopen", side_effect=_capture):
|
|
250
250
|
Document.create(name="X")
|
|
251
251
|
|
|
252
|
-
assert captured["headers"]["Authorization"] == "Bearer
|
|
252
|
+
assert captured["headers"]["Authorization"] == "Bearer personal-key"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def test_create_with_an_explicit_api_key_sends_it(
|
|
256
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
257
|
+
) -> None:
|
|
258
|
+
monkeypatch.setenv("ATHENA_DOCX_API_KEY", "studio-key")
|
|
259
|
+
monkeypatch.setenv("ATHENA_API_KEY", "athsvm_public-api-only")
|
|
260
|
+
captured: dict[str, Any] = {}
|
|
261
|
+
|
|
262
|
+
def _capture(req: Any, **_kwargs: Any) -> _FakeResponse:
|
|
263
|
+
captured["headers"] = dict(req.headers)
|
|
264
|
+
return _FakeResponse(json.dumps(_FAKE_RESPONSE).encode("utf-8"))
|
|
265
|
+
|
|
266
|
+
with patch("docx._http.urllib.request.urlopen", side_effect=_capture):
|
|
267
|
+
Document.create(name="X", base_url="https://example.com", api_key="explicit")
|
|
268
|
+
|
|
269
|
+
assert captured["headers"]["Authorization"] == "Bearer explicit"
|
{athena_python_docx-0.42.1 → athena_python_docx-0.43.0}/tests/test_document_create_from_template.py
RENAMED
|
@@ -83,8 +83,10 @@ def test_derive_agora_base_url_returns_none_for_unrelated_hosts() -> None:
|
|
|
83
83
|
assert _derive_agora_base_url("https://unrelated.example.com") is None
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
@pytest.mark.parametrize("parent", [None, "folder_override"])
|
|
86
87
|
def test_upload_document_creates_asset_then_imports_docx(
|
|
87
88
|
monkeypatch: pytest.MonkeyPatch,
|
|
89
|
+
parent: str | None,
|
|
88
90
|
) -> None:
|
|
89
91
|
"""upload_document() should create the asset, then import the .docx bytes."""
|
|
90
92
|
monkeypatch.setenv("ATHENA_DOCX_API_KEY", "bg_test_key")
|
|
@@ -115,6 +117,8 @@ def test_upload_document_creates_asset_then_imports_docx(
|
|
|
115
117
|
docx_path=path,
|
|
116
118
|
name="My Template Seeded Doc",
|
|
117
119
|
workspace_id="ws_explicit",
|
|
120
|
+
source_asset_id="asset_source",
|
|
121
|
+
parent_folder_id=parent,
|
|
118
122
|
)
|
|
119
123
|
finally:
|
|
120
124
|
os.unlink(path)
|
|
@@ -134,6 +138,8 @@ def test_upload_document_creates_asset_then_imports_docx(
|
|
|
134
138
|
"seed_author": "requester",
|
|
135
139
|
"seed_template": False,
|
|
136
140
|
"workspace_id": "ws_explicit",
|
|
141
|
+
"source_asset_id": "asset_source",
|
|
142
|
+
**({"parent_folder_id": parent} if parent is not None else {}),
|
|
137
143
|
}
|
|
138
144
|
assert create_req["attributions"] == "session_id:thread_1"
|
|
139
145
|
assert (
|
|
@@ -198,6 +204,80 @@ def test_upload_document_deletes_created_asset_when_import_fails(
|
|
|
198
204
|
assert captured[-1]["auth"] == "Bearer bg_test_key"
|
|
199
205
|
|
|
200
206
|
|
|
207
|
+
def test_upload_document_sends_the_studio_key_not_athena_api_key(
|
|
208
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
209
|
+
) -> None:
|
|
210
|
+
"""The create, the import and the rollback all send ``ATHENA_DOCX_API_KEY``.
|
|
211
|
+
|
|
212
|
+
They go to agora's ``/api/docx-studio/assets``, outside the public API
|
|
213
|
+
(``/api/v0``) that a session VM's or computer's ``ATHENA_API_KEY`` is
|
|
214
|
+
limited to.
|
|
215
|
+
"""
|
|
216
|
+
monkeypatch.setenv("ATHENA_DOCX_API_KEY", "studio-key")
|
|
217
|
+
monkeypatch.setenv("ATHENA_API_KEY", "athsvm_public-api-only")
|
|
218
|
+
monkeypatch.setenv("ATHENA_AGORA_BASE_URL", "https://api.example.com")
|
|
219
|
+
|
|
220
|
+
captured: list[tuple[str, str, str | None]] = []
|
|
221
|
+
|
|
222
|
+
def _fake_urlopen(req, timeout): # noqa: ANN001, ARG001
|
|
223
|
+
captured.append((req.get_method(), req.full_url, req.get_header("Authorization")))
|
|
224
|
+
if req.get_method() == "DELETE":
|
|
225
|
+
return _FakeResponse(b"")
|
|
226
|
+
if req.full_url.endswith("/api/docx-studio/assets"):
|
|
227
|
+
return _FakeResponse(json.dumps(_FAKE_CREATE_RESPONSE).encode("utf-8"))
|
|
228
|
+
raise urllib.error.HTTPError(
|
|
229
|
+
url=req.full_url,
|
|
230
|
+
code=500,
|
|
231
|
+
msg="Import Failed",
|
|
232
|
+
hdrs=None, # type: ignore[arg-type]
|
|
233
|
+
fp=io.BytesIO(b'{"error":"boom"}'),
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
path = _make_docx_tmpfile()
|
|
237
|
+
try:
|
|
238
|
+
with patch("docx._http.urllib.request.urlopen", side_effect=_fake_urlopen):
|
|
239
|
+
with pytest.raises(DocxError, match="HTTP 500"):
|
|
240
|
+
upload_document(docx_path=path, name="Memo")
|
|
241
|
+
finally:
|
|
242
|
+
os.unlink(path)
|
|
243
|
+
|
|
244
|
+
asset_url = (
|
|
245
|
+
"https://api.example.com/api/docx-studio/assets/"
|
|
246
|
+
"asset_aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
|
247
|
+
)
|
|
248
|
+
assert captured == [
|
|
249
|
+
("POST", "https://api.example.com/api/docx-studio/assets", "Bearer studio-key"),
|
|
250
|
+
("POST", f"{asset_url}/import", "Bearer studio-key"),
|
|
251
|
+
("DELETE", asset_url, "Bearer studio-key"),
|
|
252
|
+
]
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def test_upload_document_falls_back_to_athena_api_key_without_a_studio_key(
|
|
256
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
257
|
+
) -> None:
|
|
258
|
+
"""With only ``ATHENA_API_KEY`` set (local use), the upload authenticates with it."""
|
|
259
|
+
monkeypatch.delenv("ATHENA_DOCX_API_KEY", raising=False)
|
|
260
|
+
monkeypatch.setenv("ATHENA_API_KEY", "personal-key")
|
|
261
|
+
monkeypatch.setenv("ATHENA_AGORA_BASE_URL", "https://api.example.com")
|
|
262
|
+
|
|
263
|
+
auths: list[str | None] = []
|
|
264
|
+
|
|
265
|
+
def _fake_urlopen(req, timeout): # noqa: ANN001, ARG001
|
|
266
|
+
auths.append(req.get_header("Authorization"))
|
|
267
|
+
if req.full_url.endswith("/api/docx-studio/assets"):
|
|
268
|
+
return _FakeResponse(json.dumps(_FAKE_CREATE_RESPONSE).encode("utf-8"))
|
|
269
|
+
return _FakeResponse(json.dumps(_FAKE_IMPORT_RESPONSE).encode("utf-8"))
|
|
270
|
+
|
|
271
|
+
path = _make_docx_tmpfile()
|
|
272
|
+
try:
|
|
273
|
+
with patch("docx._http.urllib.request.urlopen", side_effect=_fake_urlopen):
|
|
274
|
+
upload_document(docx_path=path, name="Memo")
|
|
275
|
+
finally:
|
|
276
|
+
os.unlink(path)
|
|
277
|
+
|
|
278
|
+
assert auths == ["Bearer personal-key", "Bearer personal-key"]
|
|
279
|
+
|
|
280
|
+
|
|
201
281
|
def test_upload_document_rejects_unseeded_import_response(
|
|
202
282
|
monkeypatch: pytest.MonkeyPatch,
|
|
203
283
|
) -> None:
|
|
@@ -400,12 +480,16 @@ def test_document_create_with_docx_passes_workspace_id(
|
|
|
400
480
|
api_key="bg_test_key",
|
|
401
481
|
docx=path,
|
|
402
482
|
workspace_id="ws_other",
|
|
483
|
+
source_asset_id="asset_original",
|
|
484
|
+
parent_folder_id="folder_override",
|
|
403
485
|
)
|
|
404
486
|
finally:
|
|
405
487
|
os.unlink(path)
|
|
406
488
|
|
|
407
489
|
assert doc.asset_id == "asset_new_from_template"
|
|
408
490
|
assert captured["workspace_id"] == "ws_other"
|
|
491
|
+
assert captured["source_asset_id"] == "asset_original"
|
|
492
|
+
assert captured["parent_folder_id"] == "folder_override"
|
|
409
493
|
|
|
410
494
|
|
|
411
495
|
def test_document_create_without_docx_uses_empty_endpoint(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|