X Tutup
Skip to content

Commit 71e0a41

Browse files
author
Steve Canny
committed
opc: add reltype to _SerializedPart
1 parent c79684c commit 71e0a41

File tree

2 files changed

+93
-64
lines changed

2 files changed

+93
-64
lines changed

docx/opc/pkgreader.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ def _load_serialized_parts(phys_reader, pkg_srels, content_types):
6464
"""
6565
sparts = []
6666
part_walker = PackageReader._walk_phys_parts(phys_reader, pkg_srels)
67-
for partname, blob, srels in part_walker:
67+
for partname, blob, reltype, srels in part_walker:
6868
content_type = content_types[partname]
69-
spart = _SerializedPart(partname, content_type, blob, srels)
69+
spart = _SerializedPart(
70+
partname, content_type, reltype, blob, srels
71+
)
7072
sparts.append(spart)
7173
return tuple(sparts)
7274

@@ -83,8 +85,9 @@ def _srels_for(phys_reader, source_uri):
8385
@staticmethod
8486
def _walk_phys_parts(phys_reader, srels, visited_partnames=None):
8587
"""
86-
Generate a 3-tuple `(partname, blob, srels)` for each of the parts in
87-
*phys_reader* by walking the relationship graph rooted at srels.
88+
Generate a 4-tuple `(partname, blob, reltype, srels)` for each of the
89+
parts in *phys_reader* by walking the relationship graph rooted at
90+
srels.
8891
"""
8992
if visited_partnames is None:
9093
visited_partnames = []
@@ -95,12 +98,15 @@ def _walk_phys_parts(phys_reader, srels, visited_partnames=None):
9598
if partname in visited_partnames:
9699
continue
97100
visited_partnames.append(partname)
101+
reltype = srel.reltype
98102
part_srels = PackageReader._srels_for(phys_reader, partname)
99103
blob = phys_reader.blob_for(partname)
100-
yield (partname, blob, part_srels)
101-
for partname, blob, srels in PackageReader._walk_phys_parts(
102-
phys_reader, part_srels, visited_partnames):
103-
yield (partname, blob, srels)
104+
yield (partname, blob, reltype, part_srels)
105+
next_walker = PackageReader._walk_phys_parts(
106+
phys_reader, part_srels, visited_partnames
107+
)
108+
for partname, blob, reltype, srels in next_walker:
109+
yield (partname, blob, reltype, srels)
104110

105111

106112
class _ContentTypeMap(object):
@@ -149,10 +155,11 @@ class _SerializedPart(object):
149155
Value object for an OPC package part. Provides access to the partname,
150156
content type, blob, and serialized relationships for the part.
151157
"""
152-
def __init__(self, partname, content_type, blob, srels):
158+
def __init__(self, partname, content_type, reltype, blob, srels):
153159
super(_SerializedPart, self).__init__()
154160
self._partname = partname
155161
self._content_type = content_type
162+
self._reltype = reltype
156163
self._blob = blob
157164
self._srels = srels
158165

@@ -168,6 +175,13 @@ def content_type(self):
168175
def blob(self):
169176
return self._blob
170177

178+
@property
179+
def reltype(self):
180+
"""
181+
The referring relationship type of this part.
182+
"""
183+
return self._reltype
184+
171185
@property
172186
def srels(self):
173187
return self._srels

tests/opc/test_pkgreader.py

Lines changed: 70 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,44 +28,6 @@ def oxml_fromstring(request):
2828

2929
class DescribePackageReader(object):
3030

31-
@pytest.fixture
32-
def from_xml(self, request):
33-
return method_mock(request, _ContentTypeMap, 'from_xml')
34-
35-
@pytest.fixture
36-
def init(self, request):
37-
return initializer_mock(request, PackageReader)
38-
39-
@pytest.fixture
40-
def _load_serialized_parts(self, request):
41-
return method_mock(request, PackageReader, '_load_serialized_parts')
42-
43-
@pytest.fixture
44-
def PhysPkgReader_(self, request):
45-
_patch = patch(
46-
'docx.opc.pkgreader.PhysPkgReader', spec_set=_ZipPkgReader
47-
)
48-
request.addfinalizer(_patch.stop)
49-
return _patch.start()
50-
51-
@pytest.fixture
52-
def _SerializedPart_(self, request):
53-
return class_mock(request, 'docx.opc.pkgreader._SerializedPart')
54-
55-
@pytest.fixture
56-
def _SerializedRelationshipCollection_(self, request):
57-
return class_mock(
58-
request, 'docx.opc.pkgreader._SerializedRelationshipCollection'
59-
)
60-
61-
@pytest.fixture
62-
def _srels_for(self, request):
63-
return method_mock(request, PackageReader, '_srels_for')
64-
65-
@pytest.fixture
66-
def _walk_phys_parts(self, request):
67-
return method_mock(request, PackageReader, '_walk_phys_parts')
68-
6931
def it_can_construct_from_pkg_file(self, init, PhysPkgReader_, from_xml,
7032
_srels_for, _load_serialized_parts):
7133
# mockery ----------------------
@@ -125,10 +87,12 @@ def it_can_iterate_over_all_the_srels(self):
12587
def it_can_load_serialized_parts(self, _SerializedPart_, _walk_phys_parts):
12688
# test data --------------------
12789
test_data = (
128-
('/part/name1.xml', 'app/vnd.type_1', '<Part_1/>', 'srels_1'),
129-
('/part/name2.xml', 'app/vnd.type_2', '<Part_2/>', 'srels_2'),
90+
('/part/name1.xml', 'app/vnd.type_1', 'reltype1', '<Part_1/>',
91+
'srels_1'),
92+
('/part/name2.xml', 'app/vnd.type_2', 'reltype2', '<Part_2/>',
93+
'srels_2'),
13094
)
131-
iter_vals = [(t[0], t[2], t[3]) for t in test_data]
95+
iter_vals = [(t[0], t[2], t[3], t[4]) for t in test_data]
13296
content_types = dict((t[0], t[1]) for t in test_data)
13397
# mockery ----------------------
13498
phys_reader = Mock(name='phys_reader')
@@ -138,12 +102,15 @@ def it_can_load_serialized_parts(self, _SerializedPart_, _walk_phys_parts):
138102
Mock(name='spart_1'), Mock(name='spart_2')
139103
)
140104
# exercise ---------------------
141-
retval = PackageReader._load_serialized_parts(phys_reader, pkg_srels,
142-
content_types)
105+
retval = PackageReader._load_serialized_parts(
106+
phys_reader, pkg_srels, content_types
107+
)
143108
# verify -----------------------
144109
expected_calls = [
145-
call('/part/name1.xml', 'app/vnd.type_1', '<Part_1/>', 'srels_1'),
146-
call('/part/name2.xml', 'app/vnd.type_2', '<Part_2/>', 'srels_2'),
110+
call('/part/name1.xml', 'app/vnd.type_1', '<Part_1/>',
111+
'reltype1', 'srels_1'),
112+
call('/part/name2.xml', 'app/vnd.type_2', '<Part_2/>',
113+
'reltype2', 'srels_2'),
147114
]
148115
assert _SerializedPart_.call_args_list == expected_calls
149116
assert retval == expected_sparts
@@ -164,12 +131,17 @@ def it_can_walk_phys_pkg_parts(self, _srels_for):
164131
part_1_blob, part_2_blob, part_3_blob = (
165132
'<Part_1/>', '<Part_2/>', '<Part_3/>'
166133
)
134+
reltype1, reltype2, reltype3 = ('reltype1', 'reltype2', 'reltype3')
167135
srels = [
168136
Mock(name='rId1', is_external=True),
169-
Mock(name='rId2', is_external=False, target_partname=partname_1),
170-
Mock(name='rId3', is_external=False, target_partname=partname_2),
171-
Mock(name='rId4', is_external=False, target_partname=partname_1),
172-
Mock(name='rId5', is_external=False, target_partname=partname_3),
137+
Mock(name='rId2', is_external=False, reltype=reltype1,
138+
target_partname=partname_1),
139+
Mock(name='rId3', is_external=False, reltype=reltype2,
140+
target_partname=partname_2),
141+
Mock(name='rId4', is_external=False, reltype=reltype1,
142+
target_partname=partname_1),
143+
Mock(name='rId5', is_external=False, reltype=reltype3,
144+
target_partname=partname_3),
173145
]
174146
pkg_srels = srels[:2]
175147
part_1_srels = srels[2:3]
@@ -182,13 +154,14 @@ def it_can_walk_phys_pkg_parts(self, _srels_for):
182154
part_1_blob, part_2_blob, part_3_blob
183155
]
184156
# exercise ---------------------
185-
generated_tuples = [t for t in PackageReader._walk_phys_parts(
186-
phys_reader, pkg_srels)]
157+
generated_tuples = list(
158+
PackageReader._walk_phys_parts(phys_reader, pkg_srels)
159+
)
187160
# verify -----------------------
188161
expected_tuples = [
189-
(partname_1, part_1_blob, part_1_srels),
190-
(partname_2, part_2_blob, part_2_srels),
191-
(partname_3, part_3_blob, part_3_srels),
162+
(partname_1, part_1_blob, reltype1, part_1_srels),
163+
(partname_2, part_2_blob, reltype2, part_2_srels),
164+
(partname_3, part_3_blob, reltype3, part_3_srels),
192165
]
193166
assert generated_tuples == expected_tuples
194167

@@ -207,6 +180,46 @@ def it_can_retrieve_srels_for_a_source_uri(
207180
load_from_xml.assert_called_once_with(source_uri.baseURI, rels_xml)
208181
assert retval == srels
209182

183+
# fixtures -------------------------------------------------------
184+
185+
@pytest.fixture
186+
def from_xml(self, request):
187+
return method_mock(request, _ContentTypeMap, 'from_xml')
188+
189+
@pytest.fixture
190+
def init(self, request):
191+
return initializer_mock(request, PackageReader)
192+
193+
@pytest.fixture
194+
def _load_serialized_parts(self, request):
195+
return method_mock(request, PackageReader, '_load_serialized_parts')
196+
197+
@pytest.fixture
198+
def PhysPkgReader_(self, request):
199+
_patch = patch(
200+
'docx.opc.pkgreader.PhysPkgReader', spec_set=_ZipPkgReader
201+
)
202+
request.addfinalizer(_patch.stop)
203+
return _patch.start()
204+
205+
@pytest.fixture
206+
def _SerializedPart_(self, request):
207+
return class_mock(request, 'docx.opc.pkgreader._SerializedPart')
208+
209+
@pytest.fixture
210+
def _SerializedRelationshipCollection_(self, request):
211+
return class_mock(
212+
request, 'docx.opc.pkgreader._SerializedRelationshipCollection'
213+
)
214+
215+
@pytest.fixture
216+
def _srels_for(self, request):
217+
return method_mock(request, PackageReader, '_srels_for')
218+
219+
@pytest.fixture
220+
def _walk_phys_parts(self, request):
221+
return method_mock(request, PackageReader, '_walk_phys_parts')
222+
210223

211224
class Describe_ContentTypeMap(object):
212225

@@ -284,13 +297,15 @@ def it_remembers_construction_values(self):
284297
# test data --------------------
285298
partname = '/part/name.xml'
286299
content_type = 'app/vnd.type'
300+
reltype = 'http://rel/type'
287301
blob = '<Part/>'
288302
srels = 'srels proxy'
289303
# exercise ---------------------
290-
spart = _SerializedPart(partname, content_type, blob, srels)
304+
spart = _SerializedPart(partname, content_type, reltype, blob, srels)
291305
# verify -----------------------
292306
assert spart.partname == partname
293307
assert spart.content_type == content_type
308+
assert spart.reltype == reltype
294309
assert spart.blob == blob
295310
assert spart.srels == srels
296311

0 commit comments

Comments
 (0)
X Tutup