Paper Office
paper-docx

vs python-docx

High-level changes relative to python-docx 1.2.0, and why.

paper-docx keeps python-docx 1.2.0's import name and object model, then adds guarded editing and package operations. Upstream's pytest and behave suites run alongside Paper's tests.

High-level changes

  • Distribution safety. Renamed paper-docx, import stays docx. docx.__version__ remains "1.2.0" and docx.__paper_version__ identifies the fork. import docx raises ImportError if both distributions are installed; paper-docx-doctor verifies the environment.
  • Package and save integrity. ZIP preflight on open, relationship validation at load, staged path saves, and patch_save / diff_package / diagnose. Multi-part mutations roll back on late failure, so a caught refusal leaves the document unchanged.
  • Finding and editing real text. Word fragments text across runs, so matching on paragraph.text misses most phrases and assigning it destroys formatting. docx.story traverses body, headers, footers, notes, and comments with revision views and blind-region counts. docx.search matches exact text across fragmentation; Span.replace edits only the matched runs or emits a tracked change.
  • Reviewing changes. Document.revisions enumerates, accepts, and rejects tracked changes, including paired moves and row revisions, transactionally. Comment APIs manage native threads and resolution state.
  • Structured surfaces. Typed operations for content controls, comments, bookmarks, fields, numbering, merge-aware tables, hyperlinks, notes, and picture replacement — each refusing what it cannot do safely.
  • Cross-document workflows. compare() builds a verified redline and refuses differences it cannot represent. docx.composition copies formatted content between documents while reconciling styles, numbering, media, and bookmarks.
  • Compatibility boundaries. compare() redlines text and table rows only; other difference types refuse. Traversal reports blind spots (math, embedded objects, altChunk, hidden text are counted, not read). Protection covers Paper mutators, not access control. Malformed packages and unsafe save destinations can refuse where python-docx would proceed.

At a glance

Capabilitypython-docxpaper-docx
Create documents, paragraphs, tables, styles✅✅ (inherited)
Find text across run fragmentation—docx.search
Replace text preserving untouched formatting—Span.replace
Author tracked changes (w:ins/w:del)—Span.replace(tracked=True), docx.blocks
Enumerate / accept / reject revisions (incl. moves, rows)—Document.revisions
Traverse headers, footers, notes, comments, text boxespartial, manualdocx.story, with blind-spot counts
Fill content controls by type—docx.controls
Comment threads: reply, resolveadd onlydocx.commentops
Table edits by visual grid, merge-awareraw XML indexesdocx.tableops
Create real list numbering—docx.numbering
Dependency-aware bookmarks—docx.bookmarks
Author fields (PAGE, REF, TOC)—docx.fields
Effective formatting with per-value sourcesdirect properties onlydocx.formatting
Respect Restrict-Editing protection—mode-aware docx.protection
Validate malformed ZIP and OPC structures—on open and before delivery
Guarded path save—staged, validated replacement
Preserve unchanged package-part bytes—patch_save
Tracked-changes redline from two versions—compare(), verified both ways
Cross-document composition with reconciliation—docx.composition
Typed, catchable safe refusals—docx.errors, transactions
Install verification—paper-docx-doctor

On this page