Skip to content

Implement NumberingPart.new() to auto-create an empty numbering part - #1607

Draft
xtaypp wants to merge 2 commits into
python-openxml:masterfrom
xtaypp:numbering-new
Draft

Implement NumberingPart.new() to auto-create an empty numbering part#1607
xtaypp wants to merge 2 commits into
python-openxml:masterfrom
xtaypp:numbering-new

Conversation

@xtaypp

@xtaypp xtaypp commented Sep 8, 2026

Copy link
Copy Markdown

Summary

DocumentPart.numbering_part is documented to "create an empty numbering part if one is not present", but NumberingPart.new() raised NotImplementedError. Opening a .docx that has no numbering part (no word/numbering.xml / no numbering relationship) and then accessing the numbering part therefore failed instead of auto-creating it.

Root cause

NumberingPart.new() was an unimplemented stub. Unlike the sibling part factories (StylesPart.default(), SettingsPart.default(), CommentsPart.default()), it never constructed a part, and there was no default template for an empty numbering part.

Changes

  • Add src/docx/templates/default-numbering.xml — a minimal numbering part containing only the root <w:numbering> element.
  • Implement NumberingPart.new(package) mirroring the other part factories: partname /word/numbering.xml, content type CT.WML_NUMBERING, root element parsed from the new default template.
  • DocumentPart.numbering_part: pass self.package to NumberingPart.new() on the auto-create path.

The template is already covered by MANIFEST.in (graft src/docx/templates), so it ships in the package like the other default parts.

Validation

  • Change applies cleanly onto current master.
  • Opening a .docx without a numbering part and accessing numbering_part now returns a NumberingPart whose root is CT_Numbering (0 definitions); saving persists word/numbering.xml with the registered content type and relationship, and reopening reads it back.
  • Documents that already have a numbering part still return the existing related part (no rebuild).
  • Open/save/reopen smoke across the repository fixture .docx files (forcing the auto-create path) passed with no failures.

This adds no new public API; it fulfills behavior the property already documents.

DocumentPart.numbering_part documents that it creates an empty numbering
part when one is not present, but NumberingPart.new() raised
NotImplementedError, so opening a .docx without a numbering part and
accessing the numbering part failed. Implement NumberingPart.new(package)
mirroring the StylesPart/SettingsPart/CommentsPart factories, backed by a
new minimal default-numbering.xml template, and pass the package from
DocumentPart.numbering_part.
NumberingPart.new() takes the owning package, mirroring the package-taking
factories SettingsPart.default / CommentsPart.default / StylesPart.default.
Update the DocumentPart.numbering_part test to assert NumberingPart.new is
called with the package, and add a NumberingPart.new() construction test
mirroring the default-part tests in test_settings/test_comments/test_styles
(partname, content type, package, w:numbering root element, empty content).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant