Skip to content

Commit 07127f2

Browse files
author
Steve Canny
committed
opc: add OpcPackage._core_properties_part
1 parent 5f820f8 commit 07127f2

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

docx/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT
1111
from docx.opc.part import PartFactory
12+
from docx.opc.parts.coreprops import CorePropertiesPart
1213

1314
from docx.parts.document import DocumentPart
1415
from docx.parts.image import ImagePart
@@ -23,8 +24,12 @@ def part_class_selector(content_type, reltype):
2324

2425

2526
PartFactory.part_class_selector = part_class_selector
27+
PartFactory.part_type_for[CT.OPC_CORE_PROPERTIES] = CorePropertiesPart
2628
PartFactory.part_type_for[CT.WML_DOCUMENT_MAIN] = DocumentPart
2729
PartFactory.part_type_for[CT.WML_NUMBERING] = NumberingPart
2830
PartFactory.part_type_for[CT.WML_STYLES] = StylesPart
2931

30-
del CT, DocumentPart, PartFactory, part_class_selector
32+
del (
33+
CT, CorePropertiesPart, DocumentPart, NumberingPart, PartFactory,
34+
StylesPart, part_class_selector
35+
)

docx/opc/package.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .constants import RELATIONSHIP_TYPE as RT
1111
from .packuri import PACKAGE_URI
1212
from .part import PartFactory
13+
from .parts.coreprops import CorePropertiesPart
1314
from .pkgreader import PackageReader
1415
from .pkgwriter import PackageWriter
1516
from .rel import Relationships
@@ -164,7 +165,12 @@ def _core_properties_part(self):
164165
|CorePropertiesPart| object related to this package. Creates
165166
a default core properties part if one is not present (not common).
166167
"""
167-
raise NotImplementedError
168+
try:
169+
return self.part_related_by(RT.CORE_PROPERTIES)
170+
except KeyError:
171+
core_properties_part = CorePropertiesPart.default(self)
172+
self.relate_to(core_properties_part, RT.CORE_PROPERTIES)
173+
return core_properties_part
168174

169175

170176
class Unmarshaller(object):

docx/opc/parts/coreprops.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ class CorePropertiesPart(XmlPart):
1616
Corresponds to part named ``/docProps/core.xml``, containing the core
1717
document properties for this document package.
1818
"""
19+
@classmethod
20+
def default(cls, package):
21+
"""
22+
Return a new |CorePropertiesPart| object initialized with default
23+
values for its base properties.
24+
"""
25+
raise NotImplementedError
26+
1927
@property
2028
def core_properties(self):
2129
"""

tests/opc/test_package.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import pytest
1010

11+
from docx.opc.constants import RELATIONSHIP_TYPE as RT
1112
from docx.opc.coreprops import CoreProperties
1213
from docx.opc.package import OpcPackage, Unmarshaller
1314
from docx.opc.packuri import PACKAGE_URI
@@ -116,6 +117,26 @@ def it_provides_access_to_the_core_properties(self, core_props_fixture):
116117
core_properties = opc_package.core_properties
117118
assert core_properties is core_properties_
118119

120+
def it_provides_access_to_the_core_properties_part_to_help(
121+
self, core_props_part_fixture):
122+
opc_package, core_properties_part_ = core_props_part_fixture
123+
core_properties_part = opc_package._core_properties_part
124+
assert core_properties_part is core_properties_part_
125+
126+
def it_creates_a_default_core_props_part_if_none_present(
127+
self, default_core_props_fixture):
128+
opc_package, CorePropertiesPart_, core_properties_part_ = (
129+
default_core_props_fixture
130+
)
131+
132+
core_properties_part = opc_package._core_properties_part
133+
134+
CorePropertiesPart_.default.assert_called_once_with(opc_package)
135+
opc_package.relate_to.assert_called_once_with(
136+
core_properties_part_, RT.CORE_PROPERTIES
137+
)
138+
assert core_properties_part is core_properties_part_
139+
119140
# fixtures ---------------------------------------------
120141

121142
@pytest.fixture
@@ -127,6 +148,22 @@ def core_props_fixture(
127148
core_properties_part_.core_properties = core_properties_
128149
return opc_package, core_properties_
129150

151+
@pytest.fixture
152+
def core_props_part_fixture(
153+
self, part_related_by_, core_properties_part_):
154+
opc_package = OpcPackage()
155+
part_related_by_.return_value = core_properties_part_
156+
return opc_package, core_properties_part_
157+
158+
@pytest.fixture
159+
def default_core_props_fixture(
160+
self, part_related_by_, CorePropertiesPart_, relate_to_,
161+
core_properties_part_):
162+
opc_package = OpcPackage()
163+
part_related_by_.side_effect = KeyError
164+
CorePropertiesPart_.default.return_value = core_properties_part_
165+
return opc_package, CorePropertiesPart_, core_properties_part_
166+
130167
@pytest.fixture
131168
def relate_to_part_fixture_(self, request, pkg, rels_, reltype):
132169
rId = 'rId99'
@@ -146,6 +183,10 @@ def related_part_fixture_(self, request, rels_, reltype):
146183

147184
# fixture components -----------------------------------
148185

186+
@pytest.fixture
187+
def CorePropertiesPart_(self, request):
188+
return class_mock(request, 'docx.opc.package.CorePropertiesPart')
189+
149190
@pytest.fixture
150191
def core_properties_(self, request):
151192
return instance_mock(request, CoreProperties)
@@ -170,6 +211,10 @@ def PackageWriter_(self, request):
170211
def PartFactory_(self, request):
171212
return class_mock(request, 'docx.opc.package.PartFactory')
172213

214+
@pytest.fixture
215+
def part_related_by_(self, request):
216+
return method_mock(request, OpcPackage, 'part_related_by')
217+
173218
@pytest.fixture
174219
def parts(self, request, parts_):
175220
"""
@@ -214,6 +259,10 @@ def rel_attrs_(self, request):
214259
rId = 'rId99'
215260
return reltype, target_, rId
216261

262+
@pytest.fixture
263+
def relate_to_(self, request):
264+
return method_mock(request, OpcPackage, 'relate_to')
265+
217266
@pytest.fixture
218267
def rels_(self, request):
219268
return instance_mock(request, Relationships)

0 commit comments

Comments
 (0)