python-docx drops the template thumbnail unconditionally so the saved package never ships a stale preview image.
Library verdicts: python-docx: — docxjs: —
| Feature id | docx/package-thumbnail-dropped |
|---|---|
| Format | docx |
| Category | packaging |
| Spec | ecma-376-5-part-2 § 10.1.10 |
| ID / part | Predicate | XPath | python-docx | docxjs |
|---|---|---|---|---|
thumbnail-part-absent | absent`docProps/thumbnail.jpeg` MUST NOT appear in the output package. The default-docx-template ships one; python-docx drops it on save via `_drop_unused_package_rels`. | — | — |
No render assertions declared.
scripts/gen_package_thumbnail_dropped.py
#!/usr/bin/env python3
"""Generate ``fixtures/docx/package-thumbnail-dropped.docx``.
The python-docx default template carries a rendered JPEG thumbnail at
``docProps/thumbnail.jpeg`` and a corresponding package-level rel of
type ``.../metadata/thumbnail``. That thumbnail is a render of the
template's placeholder content — it is stale the instant the document
changes. python-docx 2026.05 drops the thumbnail rel (and the part
falls out of the rels graph) unconditionally on save, matching Word's
behaviour of only writing a thumbnail on explicit File->Info
rendering.
This fixture proves the drop: we save a minimal document and verify
(via the assertion in ``features/docx/package-thumbnail-dropped.json``)
that ``docProps/thumbnail.jpeg`` is absent from the output package.
"""
from __future__ import annotations
from pathlib import Path
from docx import Document
_REPO_ROOT = Path(__file__).resolve().parent.parent
_OUT = _REPO_ROOT / "fixtures" / "docx" / "package-thumbnail-dropped.docx"
def main() -> int:
doc = Document()
doc.add_paragraph("Package-thumbnail-drop check.")
_OUT.parent.mkdir(parents=True, exist_ok=True)
doc.save(_OUT, reproducible=True)
print(_OUT)
return 0
if __name__ == "__main__":
raise SystemExit(main())
{
"$schema": "../manifest.schema.json",
"id": "docx/package-thumbnail-dropped",
"title": "Package thumbnail dropped on save",
"format": "docx",
"category": "packaging",
"summary": "python-docx drops the template thumbnail unconditionally so the saved package never ships a stale preview image.",
"roles": [
"authoring"
],
"spec": {
"source": "ecma-376-5-part-2",
"clause": "10.1.10",
"notes": "`docProps/thumbnail.jpeg` is an OPC-level relationship of type `http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail` pointing at a rendered JPEG preview. The python-docx default template (src/docx/templates/default-docx-template/) carries a bundled thumbnail that shows placeholder text, so the instant the caller edits anything the thumbnail is lying. python-docx 2026.05 addresses this by dropping the thumbnail rel (and transitively the part) on every save. This matches Word's behaviour — Word only re-renders a thumbnail when the user hits File->Info, not as a side-effect of Save. The assertion is therefore NEGATIVE: a library-authored .docx MUST NOT contain `docProps/thumbnail.jpeg`."
},
"fixtures": {
"machine": "docx/package-thumbnail-dropped"
},
"generator": {
"python": "scripts/gen_package_thumbnail_dropped.py"
},
"assertions": [
{
"id": "thumbnail-part-absent",
"kind": "zip_contains_path",
"path": "docProps/thumbnail.jpeg",
"must": "absent",
"description": "`docProps/thumbnail.jpeg` MUST NOT appear in the output package. The default-docx-template ships one; python-docx drops it on save via `_drop_unused_package_rels`."
}
]
}
No rendered reference is available for this case.