Guidance for AI coding agents (and humans) working in this repository.
docx_plus is an OOXML-level extension layer for python-docx.
It reaches the parts of the .docx format python-docx does not expose — the
style cascade, content controls, fields, anchored comments, layout, bookmarks,
footnotes/endnotes, publishing (TOC/captions), tracked changes, and document
protection — while leaving the underlying Document object fully usable.
- Scope discipline: keep this a lean python-docx extension. It is not a document-authoring framework and does not do live Word automation. Adjacent ideas belong in sibling projects, not here.
- Authoritative API contract:
SPEC.md(original design) +ROADMAP.md(live shipped/deferred status).CHANGELOG.mdis the per-release record.
This project uses uv for everything. Never call bare python or pip.
uv sync --extra dev # install package + dev deps (single source: pyproject [project.optional-dependencies] dev)
uv run pytest # run the test suite (configured in [tool.pytest.ini_options])
uv run pytest tests/test_foo.py -k name # one file / one test
uv run mypy # strict type-check (files = ["docx_plus"])
uv run ruff check # lint (rules: E,F,W,I,B,UP,D — Google docstrings)
uv run ruff format # format (line-length 100)
uv run mkdocs serve # preview docs locally
uv run mkdocs build --strict # docs must build link-cleanPre-commit mirrors the CI lint gate: uv run pre-commit run --all-files.
Run an example: uv run python -m docx_plus.examples.<name> (e.g. track_changes).
Run the CLI: uv run docx-plus inspect FILE or uv run python -m docx_plus.cli.
Layered, one-way dependencies:
core/— foundation:DocxPlusError(base of every typed error), namespace map (ns), OOXML element helpers (oxml), id allocation (ids), separate OOXML parts (parts). Depends on nothing above it.- Capability modules —
styles/,controls/,fields/,comments/,layout/,bookmarks/,notes/,publishing/,revisions/,protection/. Each builds oncore/and is largely independent of its siblings. cli/— argparse console entry point (docx-plus) that composes the capability modules. This is the one layer that legitimately imports across capabilities.examples/,_testing/— runnable examples and test-only OOXML assertions; excluded from coverage and the public API.
Each subpackage's __init__.py __all__ is the authoritative public surface
for that module. docs/concepts/ has the full module-by-module breakdown
(one page per topic), docs/guides/ is the task-oriented layer above it.
- Errors: every public exception subclasses
core.DocxPlusError; dual-inherit a stdlib type where it aidsexceptergonomics (e.g.RevisionNotFoundError(DocxPlusError, KeyError)). - Typing: mypy
strict = Truemust pass with zero ignores.warn_unused_ignoresis on. Public APIs are fully typed (Typing :: Typed). - Docstrings: Google convention (ruff
D). Tests,_testing/, andexamples/are exempt fromD. - Python: target 3.10+ (
target-version = py310); CI tests 3.10–3.13. - Coverage:
fail_under = 90. New code needs tests.
- xpath:
BaseOxmlElement.xpath()does NOT accept anamespaces=kwarg. Useetree.XPath(expr, namespaces=NSMAP)(node)instead. - Examples must be cp1252-safe: print ASCII only to stdout so
python -m docx_plus.examples.<name>runs on a default Windows console. - Paragraph index base differs by surface: the CLI
inspectcommand numbers paragraphs 1-based; the libraryread_*functions use 0-basedparagraph_index. - Walking a document in order needs
iter_inner_content().doc.paragraphsdrops tables entirely anddoc.tablesdrops the ordering, so neither alone can express "paragraph, table, paragraph".styles/sweep.py_walkis the reference implementation. row.cellsrepeats a merged cell. It returns the same_Cellobject once per grid column a horizontal merge spans, so anything iterating cells double-counts a spanned cell's content. Dedupe onw:tcidentity — seestyles/sweep.py_walk.
uv run bump-my-version bump {major|minor|patch} --dry-run -v # preview first; tree must be cleanBumps pyproject.toml + docx_plus/__init__.py, commits, and tags vX.Y.Z.
CHANGELOG.md is maintained by hand. After a release, re-stamp the prose docs
(README, docs/index.md, docs/API.md, docs/getting-started.md,
docs/concepts/index.md, docs/SKILLS.md)
for the new version — these have historically lagged behind the bump.