Paper Office
paper-pptx

vs python-pptx

High-level changes relative to python-pptx 1.0.2, and why.

paper-pptx is a fork of python-pptx 1.0.2. It keeps the pptx import name and upstream object model while adding guarded APIs for inspection, editing, composition, and verification. Upstream's pytest and behave suites run on every change.

High-level changes

  • Perceive. effective_font() and related functions resolve the values a deck renders through the placeholder, layout, master, and theme chain, and report the source of each value. inspect_text() reads into groups and table cells with structural anchors; inspect_deck() emits a deterministic manifest.
  • Edit. Anchored, formatting-preserving text replacement. Relationship-safe slide clone, delete, move, and reorder. Real bullet markup, autofit normalization, merge-aware table operations, and scoped image and chart-data replacement.
  • Compose. Cross-deck slide import and deck append under explicit fidelity modes (adopt_theme, keep_appearance, bake). Layout rebind with a report of every appearance change. Footer, date, and slide-number fields written as real a:fld elements.
  • Verify. diff_decks() matches slides by permanent ID, so a reorder reports as a move. patch_save() writes byte-minimal saves, so a one-line edit to a sixty-slide deck diffs as one part.
  • Guarded package intake. Opening a .pptx rejects ambiguous or unsafe ZIP archives — duplicate or case-colliding members, noncanonical paths, encryption, unsupported compression — with a PackageLimitError before any editable object exists.
  • Atomic save. Path saves write a sibling temp file and replace the destination after serialization succeeds, preserving permission bits.
  • Distribution identity. import pptx fails when both distributions are installed. pptx.__version__ stays "1.0.2" and pptx.__paper_version__ identifies the fork. Python 3.9+ floor.

At a glance

Capabilitypython-pptxpaper-pptx
Create slides, shapes, charts, tables✅✅ (inherited)
Resolve rendered font/color through the theme chainreturns Noneeffective_font() with sources
See text in nested groups and table cellsmanual recursioninspect_text(), blind regions counted
Replace text preserving run formattingshape.text overwritesreplace_text() / replace_text_at()
Clone / delete / move / reorder slides—Slides.clone/delete/move/reorder, relationship-safe
Real bullets—paragraph.bullet
Autofit made explicitinvisible scale %font_scale, normalize_autofit()
Read notes without side effectsreading creates a partread_notes_text()
Shape lookup by namefirst match wins*_by_name, ambiguity refuses
Merge-aware table row/column operations—insert_row/column, delete_row/column
Isolated image / chart-data replacementshared parts contaminatedreplace_image(), replace_data_safe()
Cross-deck slide import—import_slide(mode=...), append_deck()
Layout rebind with a shift report—rebind_layout()
Footer/date/slide-number fields—apply_footers()
Semantic deck diff—diff_decks()
Byte-minimal savefull rewrite every savepatch_save()
Untrusted-package preflightstraight to zipfiletyped PackageLimitError before parsing
Atomic savein-place writesibling temp file, then replace
Typed, catchable errors—pptx.errors.PaperRefusal hierarchy
Install verification—paper-pptx-doctor

On this page