Merge lp:~jelmer/brz/python3.8 into lp:brz/3.0

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/python3.8
Merge into: lp:brz/3.0
Diff against target: 606 lines (+140/-127)
15 files modified
breezy/bzr/chk_serializer.py (+9/-9)
breezy/bzr/remote.py (+2/-2)
breezy/bzr/serializer.py (+3/-3)
breezy/bzr/vf_repository.py (+2/-2)
breezy/bzr/xml5.py (+5/-10)
breezy/bzr/xml8.py (+37/-40)
breezy/bzr/xml_serializer.py (+23/-31)
breezy/plugins/weave_fmt/bzrdir.py (+2/-2)
breezy/plugins/weave_fmt/xml4.py (+7/-0)
breezy/tests/__init__.py (+3/-1)
breezy/tests/per_repository_vf/helpers.py (+2/-2)
breezy/tests/test_chk_serializer.py (+2/-2)
breezy/tests/test_remote.py (+2/-2)
breezy/tests/test_xml.py (+39/-19)
tools/testr-run.py (+2/-2)
To merge this branch: bzr merge lp:~jelmer/brz/python3.8
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+378369@code.launchpad.net

Commit message

Add custom XML serializer for revisions to ensure consistent output.

Description of the change

Add custom XML serializer for revisions to ensure consistent output.

The ordering of attributes in the XML output on Python3.8 has changed.

This already exists for inventories, for performance reasons.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/bzr/chk_serializer.py'
2--- breezy/bzr/chk_serializer.py 2018-11-11 04:08:32 +0000
3+++ breezy/bzr/chk_serializer.py 2020-01-31 03:15:26 +0000
4@@ -101,8 +101,8 @@
5 ])
6 return bencode.bencode(ret)
7
8- def write_revision(self, rev, f):
9- f.write(self.write_revision_to_string(rev))
10+ def write_revision_to_lines(self, rev):
11+ return self.write_revision_to_string(rev).splitlines(True)
12
13 def read_revision_from_string(self, text):
14 # TODO: consider writing a Revision decoder, rather than using the
15@@ -223,14 +223,14 @@
16 output = []
17 append = output.append
18 if inv.revision_id is not None:
19- revid1 = b' revision_id="'
20- revid2 = xml_serializer.encode_and_escape(inv.revision_id)
21+ revid = b''.join(
22+ [b' revision_id="',
23+ xml_serializer.encode_and_escape(inv.revision_id), b'"'])
24 else:
25- revid1 = b""
26- revid2 = b""
27- append(b'<inventory format="%s"%s%s>\n' % (
28- self.format_num, revid1, revid2))
29- append(b'<directory file_id="%s name="%s revision="%s />\n' % (
30+ revid = b""
31+ append(b'<inventory format="%s"%s>\n' % (
32+ self.format_num, revid))
33+ append(b'<directory file_id="%s" name="%s" revision="%s" />\n' % (
34 xml_serializer.encode_and_escape(inv.root.file_id),
35 xml_serializer.encode_and_escape(inv.root.name),
36 xml_serializer.encode_and_escape(inv.root.revision)))
37
38=== modified file 'breezy/bzr/remote.py'
39--- breezy/bzr/remote.py 2019-06-16 19:12:23 +0000
40+++ breezy/bzr/remote.py 2020-01-31 03:15:26 +0000
41@@ -2002,11 +2002,11 @@
42 def _add_revision(self, rev):
43 if self._real_repository is not None:
44 return self._real_repository._add_revision(rev)
45- text = self._serializer.write_revision_to_string(rev)
46+ lines = self._serializer.write_revision_to_lines(rev)
47 key = (rev.revision_id,)
48 parents = tuple((parent,) for parent in rev.parent_ids)
49 self._write_group_tokens, missing_keys = self._get_sink().insert_stream(
50- [('revisions', [FulltextContentFactory(key, parents, None, text)])],
51+ [('revisions', [ChunkedContentFactory(key, parents, None, lines, chunks_are_lines=True)])],
52 self._format, self._write_group_tokens)
53
54 def get_inventory(self, revision_id):
55
56=== modified file 'breezy/bzr/serializer.py'
57--- breezy/bzr/serializer.py 2018-11-11 04:08:32 +0000
58+++ breezy/bzr/serializer.py 2020-01-31 03:15:26 +0000
59@@ -75,12 +75,12 @@
60 """See read_inventory_from_string."""
61 raise NotImplementedError(self.read_inventory)
62
63- def write_revision(self, rev, f):
64- raise NotImplementedError(self.write_revision)
65-
66 def write_revision_to_string(self, rev):
67 raise NotImplementedError(self.write_revision_to_string)
68
69+ def write_revision_to_lines(self, rev):
70+ raise NotImplementedError(self.write_revision_to_lines)
71+
72 def read_revision(self, f):
73 raise NotImplementedError(self.read_revision)
74
75
76=== modified file 'breezy/bzr/vf_repository.py'
77--- breezy/bzr/vf_repository.py 2019-02-04 19:39:30 +0000
78+++ breezy/bzr/vf_repository.py 2020-01-31 03:15:26 +0000
79@@ -768,10 +768,10 @@
80 self._add_revision(rev)
81
82 def _add_revision(self, revision):
83- text = self._serializer.write_revision_to_string(revision)
84+ lines = self._serializer.write_revision_to_lines(revision)
85 key = (revision.revision_id,)
86 parents = tuple((parent,) for parent in revision.parent_ids)
87- self.revisions.add_lines(key, parents, osutils.split_lines(text))
88+ self.revisions.add_lines(key, parents, lines)
89
90 def _check_inventories(self, checker):
91 """Check the inventories found from the revision scan.
92
93=== modified file 'breezy/bzr/xml5.py'
94--- breezy/bzr/xml5.py 2018-11-11 15:40:12 +0000
95+++ breezy/bzr/xml5.py 2020-01-31 03:15:26 +0000
96@@ -101,19 +101,14 @@
97 def _append_inventory_root(self, append, inv):
98 """Append the inventory root to output."""
99 if inv.root.file_id not in (None, inventory.ROOT_ID):
100- fileid1 = b' file_id="'
101- fileid2 = encode_and_escape(inv.root.file_id)
102+ fileid = b''.join([b' file_id="', encode_and_escape(inv.root.file_id), b'"'])
103 else:
104- fileid1 = b""
105- fileid2 = b""
106+ fileid = b""
107 if inv.revision_id is not None:
108- revid1 = b' revision_id="'
109- revid2 = encode_and_escape(inv.revision_id)
110+ revid = b''.join([b' revision_id="', encode_and_escape(inv.revision_id), b'"'])
111 else:
112- revid1 = b""
113- revid2 = b""
114- append(b'<inventory%s%s format="5"%s%s>\n' % (
115- fileid1, fileid2, revid1, revid2))
116+ revid = b""
117+ append(b'<inventory%s format="5"%s>\n' % (fileid, revid))
118
119
120 serializer_v5 = Serializer_v5()
121
122=== modified file 'breezy/bzr/xml8.py'
123--- breezy/bzr/xml8.py 2018-11-16 11:37:47 +0000
124+++ breezy/bzr/xml8.py 2020-01-31 03:15:26 +0000
125@@ -169,61 +169,58 @@
126 def _append_inventory_root(self, append, inv):
127 """Append the inventory root to output."""
128 if inv.revision_id is not None:
129- revid1 = b' revision_id="'
130- revid2 = encode_and_escape(inv.revision_id)
131+ revid1 = b''.join(
132+ [b' revision_id="', encode_and_escape(inv.revision_id), b'"'])
133 else:
134 revid1 = b""
135- revid2 = b""
136- append(b'<inventory format="%s"%s%s>\n' % (
137- self.format_num, revid1, revid2))
138- append(b'<directory file_id="%s name="%s revision="%s />\n' % (
139+ append(b'<inventory format="%s"%s>\n' % (
140+ self.format_num, revid1))
141+ append(b'<directory file_id="%s" name="%s" revision="%s" />\n' % (
142 encode_and_escape(inv.root.file_id),
143 encode_and_escape(inv.root.name),
144 encode_and_escape(inv.root.revision)))
145
146- def _pack_revision(self, rev):
147+ def write_revision_to_lines(self, rev):
148 """Revision object -> xml tree"""
149 # For the XML format, we need to write them as Unicode rather than as
150 # utf-8 strings. So that cElementTree can handle properly escaping
151 # them.
152- decode_utf8 = cache_utf8.decode
153- revision_id = rev.revision_id
154- format_num = self.format_num
155- if self.revision_format_num is not None:
156- format_num = self.revision_format_num
157- root = Element('revision',
158- committer=rev.committer,
159- timestamp='%.3f' % rev.timestamp,
160- revision_id=decode_utf8(revision_id),
161- inventory_sha1=rev.inventory_sha1.decode('ascii'),
162- format=format_num.decode(),
163- )
164+ lines = []
165+ el = (b'<revision committer="%s" format="%s" '
166+ b'inventory_sha1="%s" revision_id="%s" '
167+ b'timestamp="%.3f"' % (
168+ encode_and_escape(rev.committer),
169+ self.revision_format_num or self.format_num,
170+ rev.inventory_sha1,
171+ encode_and_escape(cache_utf8.decode(rev.revision_id)),
172+ rev.timestamp))
173 if rev.timezone is not None:
174- root.set('timezone', str(rev.timezone))
175- root.text = '\n'
176- msg = SubElement(root, 'message')
177- msg.text = escape_invalid_chars(rev.message)[0]
178- msg.tail = '\n'
179+ el += b' timezone="%s"' % str(rev.timezone).encode('ascii')
180+ lines.append(el + b'>\n')
181+ message = encode_and_escape(escape_invalid_chars(rev.message)[0])
182+ lines.extend((b'<message>' + message + b'</message>\n').splitlines(True))
183 if rev.parent_ids:
184- pelts = SubElement(root, 'parents')
185- pelts.tail = pelts.text = '\n'
186+ lines.append(b'<parents>\n')
187 for parent_id in rev.parent_ids:
188 _mod_revision.check_not_reserved_id(parent_id)
189- p = SubElement(pelts, 'revision_ref')
190- p.tail = '\n'
191- p.set('revision_id', decode_utf8(parent_id))
192+ lines.append(
193+ b'<revision_ref revision_id="%s" />\n'
194+ % encode_and_escape(cache_utf8.decode(parent_id)))
195+ lines.append(b'</parents>\n')
196 if rev.properties:
197- self._pack_revision_properties(rev, root)
198- return root
199-
200- def _pack_revision_properties(self, rev, under_element):
201- top_elt = SubElement(under_element, 'properties')
202- for prop_name, prop_value in sorted(rev.properties.items()):
203- prop_elt = SubElement(top_elt, 'property')
204- prop_elt.set('name', prop_name)
205- prop_elt.text = prop_value
206- prop_elt.tail = '\n'
207- top_elt.tail = '\n'
208+ preamble = b'<properties>'
209+ for prop_name, prop_value in sorted(rev.properties.items()):
210+ if prop_value:
211+ proplines = (preamble + b'<property name="%s">%s</property>\n' % (
212+ encode_and_escape(prop_name),
213+ encode_and_escape(escape_invalid_chars(prop_value)[0]))).splitlines(True)
214+ else:
215+ proplines = [preamble + b'<property name="%s" />\n' % (encode_and_escape(prop_name), )]
216+ preamble = b''
217+ lines.extend(proplines)
218+ lines.append(b'</properties>\n')
219+ lines.append(b'</revision>\n')
220+ return lines
221
222 def _unpack_entry(self, elt, entry_cache=None, return_from_cache=False):
223 # This is here because it's overridden by xml7
224
225=== modified file 'breezy/bzr/xml_serializer.py'
226--- breezy/bzr/xml_serializer.py 2019-02-14 05:21:21 +0000
227+++ breezy/bzr/xml_serializer.py 2020-01-31 03:15:26 +0000
228@@ -96,11 +96,8 @@
229 except ParseError as e:
230 raise errors.UnexpectedInventoryFormat(str(e))
231
232- def write_revision(self, rev, f):
233- self._write_element(self._pack_revision(rev), f)
234-
235 def write_revision_to_string(self, rev):
236- return tostring(self._pack_revision(rev)) + b'\n'
237+ return b''.join(self.write_revision_to_lines(rev))
238
239 def read_revision(self, f):
240 return self._unpack_revision(self._read_element(f))
241@@ -108,10 +105,6 @@
242 def read_revision_from_string(self, xml_string):
243 return self._unpack_revision(fromstring(xml_string))
244
245- def _write_element(self, elt, f):
246- ElementTree(elt).write(f, 'utf-8')
247- f.write(b'\n')
248-
249 def _read_element(self, f):
250 return ElementTree().parse(f)
251
252@@ -220,12 +213,12 @@
253 # better than entity escapes, but cElementTree seems to do just
254 # fine either way)
255 text = _unicode_re.sub(
256- _unicode_escape_replace, unicode_or_utf8_str).encode() + b'"'
257+ _unicode_escape_replace, unicode_or_utf8_str).encode()
258 else:
259 # Plain strings are considered to already be in utf-8 so we do a
260 # slightly different method for escaping.
261 text = _utf8_re.sub(_utf8_escape_replace,
262- unicode_or_utf8_str) + b'"'
263+ unicode_or_utf8_str)
264 _map[unicode_or_utf8_str] = text
265 return text
266
267@@ -378,70 +371,69 @@
268 root_path, root_ie = next(entries)
269 for path, ie in entries:
270 if ie.parent_id != root_id:
271- parent_str = b' parent_id="'
272- parent_id = encode_and_escape(ie.parent_id)
273+ parent_str = b''.join(
274+ [b' parent_id="', encode_and_escape(ie.parent_id), b'"'])
275 else:
276 parent_str = b''
277- parent_id = b''
278 if ie.kind == 'file':
279 if ie.executable:
280 executable = b' executable="yes"'
281 else:
282 executable = b''
283 if not working:
284- append(b'<file%s file_id="%s name="%s%s%s revision="%s '
285+ append(b'<file%s file_id="%s" name="%s"%s revision="%s" '
286 b'text_sha1="%s" text_size="%d" />\n' % (
287 executable, encode_and_escape(ie.file_id),
288- encode_and_escape(ie.name), parent_str, parent_id,
289+ encode_and_escape(ie.name), parent_str,
290 encode_and_escape(ie.revision), ie.text_sha1,
291 ie.text_size))
292 else:
293- append(b'<file%s file_id="%s name="%s%s%s />\n' % (
294+ append(b'<file%s file_id="%s" name="%s"%s />\n' % (
295 executable, encode_and_escape(ie.file_id),
296- encode_and_escape(ie.name), parent_str, parent_id))
297+ encode_and_escape(ie.name), parent_str))
298 elif ie.kind == 'directory':
299 if not working:
300- append(b'<directory file_id="%s name="%s%s%s revision="%s '
301+ append(b'<directory file_id="%s" name="%s"%s revision="%s" '
302 b'/>\n' % (
303 encode_and_escape(ie.file_id),
304 encode_and_escape(ie.name),
305- parent_str, parent_id,
306+ parent_str,
307 encode_and_escape(ie.revision)))
308 else:
309- append(b'<directory file_id="%s name="%s%s%s />\n' % (
310+ append(b'<directory file_id="%s" name="%s"%s />\n' % (
311 encode_and_escape(ie.file_id),
312 encode_and_escape(ie.name),
313- parent_str, parent_id))
314+ parent_str))
315 elif ie.kind == 'symlink':
316 if not working:
317- append(b'<symlink file_id="%s name="%s%s%s revision="%s '
318- b'symlink_target="%s />\n' % (
319+ append(b'<symlink file_id="%s" name="%s"%s revision="%s" '
320+ b'symlink_target="%s" />\n' % (
321 encode_and_escape(ie.file_id),
322 encode_and_escape(ie.name),
323- parent_str, parent_id,
324+ parent_str,
325 encode_and_escape(ie.revision),
326 encode_and_escape(ie.symlink_target)))
327 else:
328- append(b'<symlink file_id="%s name="%s%s%s />\n' % (
329+ append(b'<symlink file_id="%s" name="%s"%s />\n' % (
330 encode_and_escape(ie.file_id),
331 encode_and_escape(ie.name),
332- parent_str, parent_id))
333+ parent_str))
334 elif ie.kind == 'tree-reference':
335 if ie.kind not in supported_kinds:
336 raise errors.UnsupportedInventoryKind(ie.kind)
337 if not working:
338- append(b'<tree-reference file_id="%s name="%s%s%s '
339- b'revision="%s reference_revision="%s />\n' % (
340+ append(b'<tree-reference file_id="%s" name="%s"%s '
341+ b'revision="%s" reference_revision="%s" />\n' % (
342 encode_and_escape(ie.file_id),
343 encode_and_escape(ie.name),
344- parent_str, parent_id,
345+ parent_str,
346 encode_and_escape(ie.revision),
347 encode_and_escape(ie.reference_revision)))
348 else:
349- append(b'<tree-reference file_id="%s name="%s%s%s />\n' % (
350+ append(b'<tree-reference file_id="%s" name="%s"%s />\n' % (
351 encode_and_escape(ie.file_id),
352 encode_and_escape(ie.name),
353- parent_str, parent_id))
354+ parent_str))
355 else:
356 raise errors.UnsupportedInventoryKind(ie.kind)
357 append(b'</inventory>\n')
358
359=== modified file 'breezy/plugins/weave_fmt/bzrdir.py'
360--- breezy/plugins/weave_fmt/bzrdir.py 2018-11-11 04:08:32 +0000
361+++ breezy/plugins/weave_fmt/bzrdir.py 2020-01-31 03:15:26 +0000
362@@ -352,10 +352,10 @@
363 for i, rev_id in enumerate(self.converted_revs):
364 self.pb.update(gettext('write revision'), i,
365 len(self.converted_revs))
366- text = serializer_v5.write_revision_to_string(
367+ lines = serializer_v5.write_revision_to_lines(
368 self.revisions[rev_id])
369 key = (rev_id,)
370- revision_store.add_lines(key, None, osutils.split_lines(text))
371+ revision_store.add_lines(key, None, lines)
372 finally:
373 self.pb.clear()
374
375
376=== modified file 'breezy/plugins/weave_fmt/xml4.py'
377--- breezy/plugins/weave_fmt/xml4.py 2018-11-11 04:08:32 +0000
378+++ breezy/plugins/weave_fmt/xml4.py 2020-01-31 03:15:26 +0000
379@@ -145,6 +145,13 @@
380 p.set('revision_sha1', rev.parent_sha1s[i])
381 return root
382
383+ def write_revision_to_string(self, rev):
384+ return tostring(self._pack_revision(rev)) + b'\n'
385+
386+ def _write_element(self, elt, f):
387+ ElementTree(elt).write(f, 'utf-8')
388+ f.write(b'\n')
389+
390 def _unpack_revision(self, elt):
391 """XML Element -> Revision object"""
392
393
394=== modified file 'breezy/tests/__init__.py'
395--- breezy/tests/__init__.py 2019-02-03 23:43:20 +0000
396+++ breezy/tests/__init__.py 2020-01-31 03:15:26 +0000
397@@ -1336,7 +1336,9 @@
398 if a == b + ('\n' if isinstance(b, text_type) else b'\n'):
399 message = 'second string is missing a final newline.\n'
400 raise AssertionError(message
401- + self._ndiff_strings(a, b))
402+ + self._ndiff_strings(
403+ a if isinstance(a, text_type) else a.decode(),
404+ b if isinstance(b, text_type) else b.decode()))
405
406 def assertEqualMode(self, mode, mode_test):
407 self.assertEqual(mode, mode_test,
408
409=== modified file 'breezy/tests/per_repository_vf/helpers.py'
410--- breezy/tests/per_repository_vf/helpers.py 2018-11-11 04:08:32 +0000
411+++ breezy/tests/per_repository_vf/helpers.py 2020-01-31 03:15:26 +0000
412@@ -65,10 +65,10 @@
413 parent_ids=[])
414 # Manually add the revision text using the RevisionStore API, with
415 # bad parents.
416- rev_text = repo._serializer.write_revision_to_string(revision)
417+ lines = repo._serializer.write_revision_to_lines(revision)
418 repo.revisions.add_lines((revision.revision_id,),
419 [(b'incorrect-parent',)],
420- osutils.split_lines(rev_text))
421+ lines)
422 except:
423 repo.abort_write_group()
424 repo.unlock()
425
426=== modified file 'breezy/tests/test_chk_serializer.py'
427--- breezy/tests/test_chk_serializer.py 2018-11-11 04:08:32 +0000
428+++ breezy/tests/test_chk_serializer.py 2020-01-31 03:15:26 +0000
429@@ -86,8 +86,8 @@
430 self.assertEqual(None, rev.timezone)
431
432 def assertRoundTrips(self, serializer, orig_rev):
433- text = serializer.write_revision_to_string(orig_rev)
434- new_rev = serializer.read_revision_from_string(text)
435+ lines = serializer.write_revision_to_lines(orig_rev)
436+ new_rev = serializer.read_revision_from_string(b''.join(lines))
437 self.assertEqual(orig_rev, new_rev)
438
439 def test_roundtrips_non_ascii(self):
440
441=== modified file 'breezy/tests/test_remote.py'
442--- breezy/tests/test_remote.py 2019-06-01 02:04:54 +0000
443+++ breezy/tests/test_remote.py 2020-01-31 03:15:26 +0000
444@@ -2862,8 +2862,8 @@
445 somerev1.timezone = -60
446 somerev1.inventory_sha1 = b"691b39be74c67b1212a75fcb19c433aaed903c2b"
447 somerev1.message = "Message"
448- body = zlib.compress(chk_bencode_serializer.write_revision_to_string(
449- somerev1))
450+ body = zlib.compress(b''.join(chk_bencode_serializer.write_revision_to_lines(
451+ somerev1)))
452 # Split up body into two bits to make sure the zlib compression object
453 # gets data fed twice.
454 client.add_success_response_with_body(
455
456=== modified file 'breezy/tests/test_xml.py'
457--- breezy/tests/test_xml.py 2019-02-14 05:21:21 +0000
458+++ breezy/tests/test_xml.py 2020-01-31 03:15:26 +0000
459@@ -170,6 +170,22 @@
460 </revision>
461 """
462
463+_expected_rev_v8_complex = b"""<revision committer="Erik B&#229;gfors &lt;erik@foo.net&gt;" format="8" inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41" revision_id="erik@b&#229;gfors-02" timestamp="1125907235.212" timezone="36000">
464+<message>Include &#181;nicode characters
465+</message>
466+<parents>
467+<revision_ref revision_id="erik@b&#229;gfors-01" />
468+<revision_ref revision_id="erik@bagfors-02" />
469+</parents>
470+<properties><property name="bar" />
471+<property name="foo">this has a
472+newline in it</property>
473+</properties>
474+</revision>
475+"""
476+
477+
478+
479 _inventory_utf8_v5 = b"""<inventory file_id="TRE&#233;_ROOT" format="5"
480 revision_id="erik@b&#229;gfors-02">
481 <file file_id="b&#229;r-01"
482@@ -320,9 +336,7 @@
483 """Check that repacking a revision yields the same information"""
484 inp = BytesIO(txt)
485 rev = breezy.bzr.xml5.serializer_v5.read_revision(inp)
486- outp = BytesIO()
487- breezy.bzr.xml5.serializer_v5.write_revision(rev, outp)
488- outfile_contents = outp.getvalue()
489+ outfile_contents = breezy.bzr.xml5.serializer_v5.write_revision_to_string(rev)
490 rev2 = breezy.bzr.xml5.serializer_v5.read_revision(
491 BytesIO(outfile_contents))
492 self.assertEqual(rev, rev2)
493@@ -339,13 +353,11 @@
494 # fixed 20051025, revisions should have final newline
495 rev = breezy.bzr.xml5.serializer_v5.read_revision_from_string(
496 _revision_v5)
497- outp = BytesIO()
498- breezy.bzr.xml5.serializer_v5.write_revision(rev, outp)
499- outfile_contents = outp.getvalue()
500+ outfile_contents = breezy.bzr.xml5.serializer_v5.write_revision_to_string(rev)
501 self.assertEqual(outfile_contents[-1:], b'\n')
502 self.assertEqualDiff(
503 outfile_contents,
504- breezy.bzr.xml5.serializer_v5.write_revision_to_string(rev))
505+ b''.join(breezy.bzr.xml5.serializer_v5.write_revision_to_lines(rev)))
506 self.assertEqualDiff(outfile_contents, _expected_rev_v5)
507
508 def test_empty_property_value(self):
509@@ -354,7 +366,7 @@
510 rev = s_v5.read_revision_from_string(_revision_v5)
511 props = {'empty': '', 'one': 'one'}
512 rev.properties = props
513- txt = s_v5.write_revision_to_string(rev)
514+ txt = b''.join(s_v5.write_revision_to_lines(rev))
515 new_rev = s_v5.read_revision_from_string(txt)
516 self.assertEqual(props, new_rev.properties)
517
518@@ -447,25 +459,33 @@
519 """Pack revision to XML v6"""
520 rev = breezy.bzr.xml6.serializer_v6.read_revision_from_string(
521 _expected_rev_v5)
522- serialized = breezy.bzr.xml6.serializer_v6.write_revision_to_string(
523+ serialized = breezy.bzr.xml6.serializer_v6.write_revision_to_lines(
524 rev)
525- self.assertEqualDiff(serialized, _expected_rev_v5)
526+ self.assertEqualDiff(b''.join(serialized), _expected_rev_v5)
527
528 def test_revision_text_v7(self):
529 """Pack revision to XML v7"""
530 rev = breezy.bzr.xml7.serializer_v7.read_revision_from_string(
531 _expected_rev_v5)
532- serialized = breezy.bzr.xml7.serializer_v7.write_revision_to_string(
533+ serialized = breezy.bzr.xml7.serializer_v7.write_revision_to_lines(
534 rev)
535- self.assertEqualDiff(serialized, _expected_rev_v5)
536+ self.assertEqualDiff(b''.join(serialized), _expected_rev_v5)
537
538 def test_revision_text_v8(self):
539 """Pack revision to XML v8"""
540 rev = breezy.bzr.xml8.serializer_v8.read_revision_from_string(
541 _expected_rev_v8)
542- serialized = breezy.bzr.xml8.serializer_v8.write_revision_to_string(
543- rev)
544- self.assertEqualDiff(serialized, _expected_rev_v8)
545+ serialized = breezy.bzr.xml8.serializer_v8.write_revision_to_lines(
546+ rev)
547+ self.assertEqualDiff(b''.join(serialized), _expected_rev_v8)
548+
549+ def test_revision_text_v8_complex(self):
550+ """Pack revision to XML v8"""
551+ rev = breezy.bzr.xml8.serializer_v8.read_revision_from_string(
552+ _expected_rev_v8_complex)
553+ serialized = breezy.bzr.xml8.serializer_v8.write_revision_to_lines(
554+ rev)
555+ self.assertEqualDiff(b''.join(serialized), _expected_rev_v8_complex)
556
557 def test_revision_ids_are_utf8(self):
558 """Parsed revision_ids should all be utf-8 strings, not unicode."""
559@@ -533,24 +553,24 @@
560 # are being used in xml attributes, and by returning it now, we have to
561 # do fewer string operations later.
562 val = breezy.bzr.xml_serializer.encode_and_escape('foo bar')
563- self.assertEqual(b'foo bar"', val)
564+ self.assertEqual(b'foo bar', val)
565 # The second time should be cached
566 val2 = breezy.bzr.xml_serializer.encode_and_escape('foo bar')
567 self.assertIs(val2, val)
568
569 def test_ascii_with_xml(self):
570- self.assertEqual(b'&amp;&apos;&quot;&lt;&gt;"',
571+ self.assertEqual(b'&amp;&apos;&quot;&lt;&gt;',
572 breezy.bzr.xml_serializer.encode_and_escape('&\'"<>'))
573
574 def test_utf8_with_xml(self):
575 # u'\xb5\xe5&\u062c'
576 utf8_str = b'\xc2\xb5\xc3\xa5&\xd8\xac'
577- self.assertEqual(b'&#181;&#229;&amp;&#1580;"',
578+ self.assertEqual(b'&#181;&#229;&amp;&#1580;',
579 breezy.bzr.xml_serializer.encode_and_escape(utf8_str))
580
581 def test_unicode(self):
582 uni_str = u'\xb5\xe5&\u062c'
583- self.assertEqual(b'&#181;&#229;&amp;&#1580;"',
584+ self.assertEqual(b'&#181;&#229;&amp;&#1580;',
585 breezy.bzr.xml_serializer.encode_and_escape(uni_str))
586
587
588
589=== modified file 'tools/testr-run.py'
590--- tools/testr-run.py 2018-06-29 21:21:43 +0000
591+++ tools/testr-run.py 2020-01-31 03:15:26 +0000
592@@ -1,4 +1,4 @@
593-#!/usr/bin/python
594+#!/usr/bin/python3
595
596 import argparse
597 import subprocess
598@@ -38,7 +38,7 @@
599 if args.load_list:
600 py2_tests = []
601 py3_tests = []
602- with open(args.load_list, 'r') as f:
603+ with open(args.load_list, 'rb') as f:
604 all_tests = parse_list(f.read())
605 for testname in all_tests:
606 if testname.startswith("python2."):

Subscribers

People subscribed via source and target branches