/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/inventory_delta.py

  • Committer: Martin
  • Date: 2017-06-09 16:31:49 UTC
  • mto: This revision was merged to the branch mainline in revision 6673.
  • Revision ID: gzlist@googlemail.com-20170609163149-liveiasey25480q6
Make InventoryDeltaError use string formatting, and repr for fileids

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 - InventoryDeltaSerializer - object to read/write inventory deltas.
23
23
"""
24
24
 
 
25
from __future__ import absolute_import
 
26
 
25
27
__all__ = ['InventoryDeltaSerializer']
26
28
 
27
 
from bzrlib import errors
28
 
from bzrlib.osutils import basename
29
 
from bzrlib import inventory
30
 
from bzrlib.revision import NULL_REVISION
 
29
from . import errors
 
30
from .osutils import basename
 
31
from . import inventory
 
32
from .revision import NULL_REVISION
31
33
 
32
34
FORMAT_1 = 'bzr inventory delta v1 (bzr 1.14)'
33
35
 
34
36
 
35
37
class InventoryDeltaError(errors.BzrError):
36
38
    """An error when serializing or deserializing an inventory delta."""
37
 
    
 
39
 
38
40
    # Most errors when serializing and deserializing are due to bugs, although
39
41
    # damaged input (i.e. a bug in a different process) could cause
40
42
    # deserialization errors too.
41
43
    internal_error = True
42
44
 
 
45
    def __init__(self, format_string, **kwargs):
 
46
        # Let each error supply a custom format string and arguments.
 
47
        self._fmt = format_string
 
48
        super(InventoryDeltaError, self).__init__(**kwargs)
 
49
 
43
50
 
44
51
class IncompatibleInventoryDelta(errors.BzrError):
45
52
    """The delta could not be deserialised because its contents conflict with
68
75
        exec_bytes = ''
69
76
    size_exec_sha = (entry.text_size, exec_bytes, entry.text_sha1)
70
77
    if None in size_exec_sha:
71
 
        raise InventoryDeltaError('Missing size or sha for %s' % entry.file_id)
 
78
        raise InventoryDeltaError(
 
79
            'Missing size or sha for %(fileid)r', fileid=entry.file_id)
72
80
    return "file\x00%d\x00%s\x00%s" % size_exec_sha
73
81
 
74
82
 
79
87
    """
80
88
    target = entry.symlink_target
81
89
    if target is None:
82
 
        raise InventoryDeltaError('Missing target for %s' % entry.file_id)
 
90
        raise InventoryDeltaError(
 
91
            'Missing target for %(fileid)r', fileid=entry.file_id)
83
92
    return "link\x00%s" % target.encode('utf8')
84
93
 
85
94
 
91
100
    tree_revision = entry.reference_revision
92
101
    if tree_revision is None:
93
102
        raise InventoryDeltaError(
94
 
            'Missing reference revision for %s' % entry.file_id)
 
103
            'Missing reference revision for %(fileid)r', fileid=entry.file_id)
95
104
    return "tree\x00%s" % tree_revision
96
105
 
97
106
 
170
179
            takes.
171
180
        :return: The serialized delta as lines.
172
181
        """
173
 
        if type(old_name) is not str:
 
182
        if not isinstance(old_name, str):
174
183
            raise TypeError('old_name should be str, got %r' % (old_name,))
175
 
        if type(new_name) is not str:
 
184
        if not isinstance(new_name, str):
176
185
            raise TypeError('new_name should be str, got %r' % (new_name,))
177
186
        lines = ['', '', '', '', '']
178
187
        to_line = self._delta_item_to_line
179
188
        for delta_item in delta_to_new:
180
189
            line = to_line(delta_item, new_name)
181
 
            if line.__class__ != str:
 
190
            # GZ 2017-06-09: Not really worth asserting this here
 
191
            if line.__class__ != bytes:
182
192
                raise InventoryDeltaError(
183
 
                    'to_line generated non-str output %r' % lines[-1])
 
193
                    'to_line gave non-bytes output %(line)r', line=lines[-1])
184
194
            lines.append(line)
185
195
        lines.sort()
186
196
        lines[0] = "format: %s\n" % FORMAT_1
234
244
                # xml5 serializer.
235
245
                if last_modified != new_version:
236
246
                    raise InventoryDeltaError(
237
 
                        'Version present for / in %s (%s != %s)'
238
 
                        % (file_id, last_modified, new_version))
 
247
                        'Version present for / in %(fileid)r'
 
248
                        ' (%(last)r != %(new)r)',
 
249
                        fileid=file_id, last=last_modified, new=new_version)
239
250
            if last_modified is None:
240
 
                raise InventoryDeltaError("no version for fileid %s" % file_id)
 
251
                raise InventoryDeltaError(
 
252
                    "no version for fileid %(fileid)r", fileid=file_id)
241
253
            content = self._entry_to_content[entry.kind](entry)
242
254
        return ("%s\x00%s\x00%s\x00%s\x00%s\x00%s\n" %
243
255
            (oldpath_utf8, newpath_utf8, file_id, parent_id, last_modified,
263
275
        elif value == "false":
264
276
            return False
265
277
        else:
266
 
            raise InventoryDeltaError("value %r is not a bool" % (value,))
 
278
            raise InventoryDeltaError("value %(val)r is not a bool", val=value)
267
279
 
268
280
    def parse_text_bytes(self, bytes):
269
281
        """Parse the text bytes of a serialized inventory delta.
279
291
        """
280
292
        if bytes[-1:] != '\n':
281
293
            last_line = bytes.rsplit('\n', 1)[-1]
282
 
            raise InventoryDeltaError('last line not empty: %r' % (last_line,))
 
294
            raise InventoryDeltaError(
 
295
                'last line not empty: %(line)r', line=last_line)
283
296
        lines = bytes.split('\n')[:-1] # discard the last empty line
284
297
        if not lines or lines[0] != 'format: %s' % FORMAT_1:
285
 
            raise InventoryDeltaError('unknown format %r' % lines[0:1])
 
298
            raise InventoryDeltaError(
 
299
                'unknown format %(line)r', line=lines[0:1])
286
300
        if len(lines) < 2 or not lines[1].startswith('parent: '):
287
301
            raise InventoryDeltaError('missing parent: marker')
288
302
        delta_parent_id = lines[1][8:]
301
315
        seen_ids = set()
302
316
        line_iter = iter(lines)
303
317
        for i in range(5):
304
 
            line_iter.next()
 
318
            next(line_iter)
305
319
        for line in line_iter:
306
320
            (oldpath_utf8, newpath_utf8, file_id, parent_id, last_modified,
307
321
                content) = line.split('\x00', 5)
308
322
            parent_id = parent_id or None
309
323
            if file_id in seen_ids:
310
324
                raise InventoryDeltaError(
311
 
                    "duplicate file id in inventory delta %r" % lines)
 
325
                    "duplicate file id %(fileid)r", fileid=file_id)
312
326
            seen_ids.add(file_id)
313
327
            if (newpath_utf8 == '/' and not delta_versioned_root and
314
328
                last_modified != delta_version_id):
315
329
                    # Delta claims to be not have a versioned root, yet here's
316
330
                    # a root entry with a non-default version.
317
 
                    raise InventoryDeltaError("Versioned root found: %r" % line)
 
331
                    raise InventoryDeltaError(
 
332
                        "Versioned root found: %(line)r", line=line)
318
333
            elif newpath_utf8 != 'None' and last_modified[-1] == ':':
319
334
                # Deletes have a last_modified of null:, but otherwise special
320
335
                # revision ids should not occur.
321
 
                raise InventoryDeltaError('special revisionid found: %r' % line)
 
336
                raise InventoryDeltaError(
 
337
                    'special revisionid found: %(line)r', line=line)
322
338
            if content.startswith('tree\x00'):
323
339
                if delta_tree_references is False:
324
340
                    raise InventoryDeltaError(
325
341
                            "Tree reference found (but header said "
326
 
                            "tree_references: false): %r" % line)
 
342
                            "tree_references: false): %(line)r", line=line)
327
343
                elif not self._allow_tree_references:
328
344
                    raise IncompatibleInventoryDelta(
329
345
                        "Tree reference not allowed")
331
347
                oldpath = None
332
348
            elif oldpath_utf8[:1] != '/':
333
349
                raise InventoryDeltaError(
334
 
                    "oldpath invalid (does not start with /): %r"
335
 
                    % (oldpath_utf8,))
 
350
                    "oldpath invalid (does not start with /): %(path)r",
 
351
                    path=oldpath_utf8)
336
352
            else:
337
353
                oldpath_utf8 = oldpath_utf8[1:]
338
354
                oldpath = oldpath_utf8.decode('utf8')
340
356
                newpath = None
341
357
            elif newpath_utf8[:1] != '/':
342
358
                raise InventoryDeltaError(
343
 
                    "newpath invalid (does not start with /): %r"
344
 
                    % (newpath_utf8,))
 
359
                    "newpath invalid (does not start with /): %(path)r",
 
360
                    path=newpath_utf8)
345
361
            else:
346
362
                # Trim leading slash
347
363
                newpath_utf8 = newpath_utf8[1:]