Skip to content

Commit e84b60c

Browse files
author
Steve Canny
committed
num: add NumberingPart
1 parent b0adbe6 commit e84b60c

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed

docx/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from docx.parts.document import DocumentPart
1414
from docx.parts.image import ImagePart
15+
from docx.parts.numbering import NumberingPart
1516

1617

1718
def part_class_selector(content_type, reltype):
@@ -22,5 +23,6 @@ def part_class_selector(content_type, reltype):
2223

2324
PartFactory.part_class_selector = part_class_selector
2425
PartFactory.part_type_for[CT.WML_DOCUMENT_MAIN] = DocumentPart
26+
PartFactory.part_type_for[CT.WML_NUMBERING] = NumberingPart
2527

2628
del CT, DocumentPart, PartFactory, part_class_selector

docx/oxml/parts/numbering.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# encoding: utf-8
2+
3+
"""
4+
Custom element classes related to the numbering part
5+
"""
6+
7+
from docx.oxml.shared import OxmlBaseElement
8+
9+
10+
class CT_Numbering(OxmlBaseElement):
11+
"""
12+
``<w:numbering>`` element, the root element of a numbering part, i.e.
13+
numbering.xml
14+
"""

docx/parts/numbering.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,29 @@
99
)
1010

1111
from ..opc.package import Part
12+
from ..oxml.shared import oxml_fromstring
1213

1314

1415
class NumberingPart(Part):
1516
"""
1617
Proxy for the numbering.xml part containing numbering definitions for
1718
a document or glossary.
1819
"""
20+
def __init__(self, partname, content_type, element, package):
21+
super(NumberingPart, self).__init__(
22+
partname, content_type, element=element, package=package
23+
)
24+
25+
@classmethod
26+
def load(cls, partname, content_type, blob, package):
27+
"""
28+
Provides PartFactory interface for loading a numbering part from
29+
a WML package.
30+
"""
31+
numbering_elm = oxml_fromstring(blob)
32+
numbering_part = cls(partname, content_type, numbering_elm, package)
33+
return numbering_part
34+
1935
@classmethod
2036
def new(cls):
2137
"""

tests/parts/test_numbering.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# encoding: utf-8
2+
3+
"""
4+
Test suite for the docx.parts.numbering module
5+
"""
6+
7+
from __future__ import absolute_import, print_function, unicode_literals
8+
9+
import pytest
10+
11+
from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT
12+
from docx.opc.package import PartFactory
13+
from docx.opc.packuri import PackURI
14+
from docx.oxml.parts.numbering import CT_Numbering
15+
from docx.package import Package
16+
from docx.parts.numbering import NumberingPart
17+
18+
from ..unitutil import (
19+
function_mock, initializer_mock, instance_mock, method_mock
20+
)
21+
22+
23+
class DescribeNumberingPart(object):
24+
25+
def it_is_used_by_PartFactory_to_construct_numbering_part(
26+
self, load_fixture):
27+
# fixture ----------------------
28+
numbering_part_load_, partname_, blob_, package_, numbering_part_ = (
29+
load_fixture
30+
)
31+
content_type, reltype = CT.WML_NUMBERING, RT.NUMBERING
32+
# exercise ---------------------
33+
part = PartFactory(partname_, content_type, reltype, blob_, package_)
34+
# verify -----------------------
35+
numbering_part_load_.assert_called_once_with(
36+
partname_, content_type, blob_, package_
37+
)
38+
assert part is numbering_part_
39+
40+
def it_can_be_constructed_by_opc_part_factory(self, construct_fixture):
41+
(partname_, content_type_, blob_, package_, oxml_fromstring_,
42+
init__, numbering_elm_) = construct_fixture
43+
# exercise ---------------------
44+
numbering_part = NumberingPart.load(
45+
partname_, content_type_, blob_, package_
46+
)
47+
# verify -----------------------
48+
oxml_fromstring_.assert_called_once_with(blob_)
49+
init__.assert_called_once_with(
50+
partname_, content_type_, numbering_elm_, package_
51+
)
52+
assert isinstance(numbering_part, NumberingPart)
53+
54+
# fixtures -------------------------------------------------------
55+
56+
@pytest.fixture
57+
def blob_(self, request):
58+
return instance_mock(request, bytes)
59+
60+
@pytest.fixture
61+
def construct_fixture(
62+
self, partname_, content_type_, blob_, package_,
63+
oxml_fromstring_, init__, numbering_elm_):
64+
return (
65+
partname_, content_type_, blob_, package_, oxml_fromstring_,
66+
init__, numbering_elm_
67+
)
68+
69+
@pytest.fixture
70+
def content_type_(self, request):
71+
return instance_mock(request, str)
72+
73+
@pytest.fixture
74+
def init__(self, request):
75+
return initializer_mock(request, NumberingPart)
76+
77+
@pytest.fixture
78+
def load_fixture(
79+
self, numbering_part_load_, partname_, blob_, package_,
80+
numbering_part_):
81+
numbering_part_load_.return_value = numbering_part_
82+
return (
83+
numbering_part_load_, partname_, blob_, package_, numbering_part_
84+
)
85+
86+
@pytest.fixture
87+
def numbering_elm_(self, request):
88+
return instance_mock(request, CT_Numbering)
89+
90+
@pytest.fixture
91+
def numbering_part_(self, request):
92+
return instance_mock(request, NumberingPart)
93+
94+
@pytest.fixture
95+
def numbering_part_load_(self, request):
96+
return method_mock(request, NumberingPart, 'load')
97+
98+
@pytest.fixture
99+
def oxml_fromstring_(self, request, numbering_elm_):
100+
return function_mock(
101+
request, 'docx.parts.numbering.oxml_fromstring',
102+
return_value=numbering_elm_
103+
)
104+
105+
@pytest.fixture
106+
def package_(self, request):
107+
return instance_mock(request, Package)
108+
109+
@pytest.fixture
110+
def partname_(self, request):
111+
return instance_mock(request, PackURI)

0 commit comments

Comments
 (0)