WolfSDKWolfXLWolfPPTWolfDocxWolfRender

WolfDocx - section inheritance

Why does python-docx change Link to Previous on headers and footers?

In python-docx, Link to Previous means the section has no definition of its own for that header or footer variant. Editing a linked header changes the inherited source, while setting is_linked_to_previous to False creates an independent definition when one is missing. Unlink before writing section-specific text, and leave the footer linked if only the header should differ.

Inheritance is not a copied header

The python-docx header and footer guide describes recursive inheritance: a section without its own header definition uses the preceding section's definition, looking farther back if necessary. A section.header object exists even when there is no local definition. Merely obtaining that object does not mean the document contains a separate header for the section.

This explains a common surprise. Editing section two's linked header can change section one's visible header because both resolve to the same definition. Unlinking first changes the ownership of subsequent edits. In python-docx a newly created independent definition starts with an empty paragraph; the toggle is not a request to clone every paragraph, table, or image from the previous header.

Give the second section its own header, but keep its footer linked

Install python-docx==1.2.0 for this runnable example. It deliberately uses python-docx, because the public API already handles this task. It creates two sections, changes only the second header, and reopens the output to check both link flags and the visible header text.

from docx import Document
from docx.enum.section import WD_SECTION_START

# Run in a fresh directory. This example creates its own document.
document = Document()
first = document.sections[0]
first.header.paragraphs[0].text = "Shared firm header"
first.footer.paragraphs[0].text = "Confidential"
document.add_paragraph("Engagement terms")
document.add_section(WD_SECTION_START.NEW_PAGE)

# Fetch section objects after adding the section.
first, second = document.sections
assert second.header.is_linked_to_previous
second.header.is_linked_to_previous = False
second.header.paragraphs[0].text = "Schedule A"
# Do not unlink the footer: it should still inherit Confidential.
assert second.footer.is_linked_to_previous
assert first.header.paragraphs[0].text == "Shared firm header"
document.save("section_headers.docx")

reopened = Document("section_headers.docx")
assert not reopened.sections[1].header.is_linked_to_previous
assert reopened.sections[1].footer.is_linked_to_previous
assert reopened.sections[0].header.paragraphs[0].text == "Shared firm header"
assert reopened.sections[1].header.paragraphs[0].text == "Schedule A"

Check the variant and the display settings separately

The default header, first-page header, and even-page header are separate variants, as are the three footer variants. The section API reference exposes them separately. Changing section.header does not configure first_page_header or even_page_header. First-page display is controlled by different_first_page_header_footer; alternating odd and even headers also depend on the document's odd_and_even_pages_header_footer setting.

Setting is_linked_to_previous to True removes that variant's local definition and restores inheritance. Do not use it as a preservation step if the local content still matters. The documentation also notes that accessing editable inherited content can create a definition in the first section when no earlier definition exists. Inspect the link state before materializing or changing content when diagnosing this.

When WolfDocx Commercial is relevant

WolfDocx Commercial's region workflow can discover inherited references and explicitly unlink a section by cloning its active predecessor story into a distinct part. That differs from python-docx's empty new definition. It is useful when the requirement is to retain the existing header content while making its ownership independent. These region APIs are not exported by the MIT wolfdocx 0.1.0 package; do not assume this page's python-docx example requires a WolfDocx subscription.

What it does not do

  • The example does not copy a complex inherited header into a new independent definition.
  • It changes only the default header, not first-page or even-page variants.
  • A link flag is not a rendering result. This sample does not calculate pagination or compare pages with Word.
  • This behavior alone is not evidence of a python-docx corruption bug; inheritance can explain the change.

Related: migration call mapping, edit cells in a named header part, and merge documents with section content.

Get WolfDocx

WolfDocx Community is MIT-licensed and free, including commercial use. It edits existing .docx files in place in pure Python and does not render pages or convert to PDF. WolfDocx Commercial does not change those rights.

pip install wolfdocx

WolfDocx Commercial is an organization-scoped subscription. WolfDocx Community installs from public PyPI with pip install wolfdocx. WolfDocx Commercial installs from the authenticated WolfDocx package index with a per-purchase credential, issued on the checkout success page after payment and reissued through https://wolfxl.com/recover.

Review the scoped before-and-after memo files in the reporting walkthrough, or ask about your document before purchasing if compatibility is uncertain.

Related tasks