~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/errors.py

  • Committer: Martin Pool
  • Date: 2006-10-15 11:57:58 UTC
  • mto: This revision was merged to the branch mainline in revision 2119.
  • Revision ID: mbp@sourcefrog.net-20061015115758-041391cf08503621
Clean up BzrNewError, other exception classes and users.

This cleans up the probably-mistaken BzrNewError behaviour of using error
class docstrings as their format string.  Instead errors can define a _fmt
attribute with the same meaning.  The docstring is now reserved for its
regular purpose of documentation for programmers.  This behaviour is added to
BzrError.  BzrNewError is left in place for compatibility but no builtin
errors use it anymore and it gives a deprecation warning on construction.

BzrError now accepts either a single preformatted string, or a set of named
parameters to be substituted in to a format string for that class.  This 
behaviour is cleaned up and a couple of callers that depended on the
Python2.4-style exception args tuple are fixed.

Display of unprintable errors is slightly more robust.

errors.IncompatibleFormat was defined twice (shadowing the first
definition), so one use was disambiguated to IncompatibleBundleFormat.

UnsupportedEOLMarker called the wrong superclass constructor.

test_time_creates_benchmark_in_result was too dependent on benchmark
timing and has been loosened.

Some error representations changed slightly because of this (e.g. in use
of punctuation.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Exceptions for bzr, and reporting of them.
18
 
 
19
 
There are 3 different classes of error:
20
 
 
21
 
 * KeyboardInterrupt, and OSError with EPIPE - the program terminates 
22
 
   with an appropriate short message
23
 
 
24
 
 * User errors, indicating a problem caused by the user such as a bad URL.
25
 
   These are printed in a short form.
26
 
 
27
 
 * Internal unexpected errors, including most Python builtin errors
28
 
   and some raised from inside bzr.  These are printed with a full 
29
 
   traceback and an invitation to report the bug.
30
 
 
31
 
Exceptions are caught at a high level to report errors to the user, and
32
 
might also be caught inside the program.  Therefore it needs to be
33
 
possible to convert them to a meaningful string, and also for them to be
34
 
interrogated by the program.
35
 
 
36
 
Exceptions are defined such that the arguments given to the constructor
37
 
are stored in the object as properties of the same name.  When the
38
 
object is printed as a string, the doc string of the class is used as
39
 
a format string with the property dictionary available to it.
40
 
 
41
 
This means that exceptions can used like this:
42
 
 
43
 
>>> import sys
44
 
>>> try:
45
 
...   raise NotBranchError(path='/foo/bar')
46
 
... except:
47
 
...   print '%s.%s' % (sys.exc_type.__module__, sys.exc_type.__name__)
48
 
...   print sys.exc_value
49
 
...   path = getattr(sys.exc_value, 'path', None)
50
 
...   if path is not None:
51
 
...     print path
52
 
bzrlib.errors.NotBranchError
53
 
Not a branch: /foo/bar
54
 
/foo/bar
55
 
 
56
 
Therefore:
57
 
 
58
 
 * create a new exception class for any class of error that can be
59
 
   usefully distinguished.  If no callers are likely to want to catch
60
 
   one but not another, don't worry about them.
61
 
 
62
 
 * the __str__ method should generate something useful; BzrError provides
63
 
   a good default implementation
64
 
 
65
 
Exception strings should start with a capital letter and should not have a
66
 
final fullstop.
67
18
"""
68
19
 
69
 
from warnings import warn
70
20
 
 
21
from bzrlib import symbol_versioning
71
22
from bzrlib.patches import (PatchSyntax, 
72
23
                            PatchConflict, 
73
24
                            MalformedPatchHeader,
75
26
                            MalformedLine,)
76
27
 
77
28
 
78
 
# based on Scott James Remnant's hct error classes
79
 
 
80
29
# TODO: is there any value in providing the .args field used by standard
81
30
# python exceptions?   A list of values with no names seems less useful 
82
31
# to me.
85
34
# constructed to make sure it will succeed.  But that says nothing about
86
35
# exceptions that are never raised.
87
36
 
88
 
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
89
 
# the old one.
90
 
 
91
 
# TODO: The pattern (from hct) of using classes docstrings as message
92
 
# templates is cute but maybe not such a great idea - perhaps should have a
93
 
# separate static message_template.
 
37
# TODO: selftest assertRaises should probably also check that every error
 
38
# raised can be formatted as a string successfully, and without giving
 
39
# 'unprintable'.
94
40
 
95
41
 
96
42
class BzrError(StandardError):
 
43
    """
 
44
    Base class for errors raised by bzrlib.
 
45
 
 
46
    :cvar is_user_error: True if this is a user error and should be 
 
47
    displayed concisely; false if this is bzr's fault and it should 
 
48
    give a traceback.
 
49
 
 
50
    :cvar fmt: Format string to display the error; this is expanded
 
51
    by the instance's dict.
 
52
    """
97
53
    
98
54
    is_user_error = True
99
55
 
 
56
    def __init__(self, msg=None, **kwds):
 
57
        """Construct a new BzrError.
 
58
 
 
59
        There are two alternative forms for constructing these objects.
 
60
        Either a preformatted string may be passed, or a set of named
 
61
        arguments can be given.  The first is for generic "user" errors which
 
62
        are not intended to be caught and so do not need a specific subclass.
 
63
        The second case is for use with subclasses that provide a _fmt format
 
64
        string to print the arguments.  
 
65
 
 
66
        Keyword arguments are taken as parameters to the error, which can 
 
67
        be inserted into the format string template.  It's recommended 
 
68
        that subclasses override the __init__ method to require specific 
 
69
        parameters.
 
70
 
 
71
        :param msg: Deprecated parameter for passing a format string 
 
72
        when constructing.
 
73
        """
 
74
        StandardError.__init__(self)
 
75
        if msg is not None:
 
76
            ## symbol_versioning.warn(
 
77
            ##         'constructing a BzrError from a string was deprecated '
 
78
            ##         'in bzr 0.12; please raise a specific subclass instead',
 
79
            ##         DeprecationWarning,
 
80
            ##         stacklevel=2)
 
81
            self._str = msg
 
82
        else:
 
83
            self._str = None
 
84
            for key, value in kwds.items():
 
85
                setattr(self, key, value)
 
86
 
100
87
    def __str__(self):
101
 
        # XXX: Should we show the exception class in 
102
 
        # exceptions that don't provide their own message?  
103
 
        # maybe it should be done at a higher level
104
 
        ## n = self.__class__.__name__ + ': '
105
 
        n = ''
106
 
        if len(self.args) == 1:
107
 
            return str(self.args[0])
108
 
        elif len(self.args) == 2:
109
 
            # further explanation or suggestions
110
 
            try:
111
 
                return n + '\n  '.join([self.args[0]] + self.args[1])
112
 
            except TypeError:
113
 
                return n + "%r" % self
114
 
        else:
115
 
            return n + `self.args`
 
88
        s = getattr(self, '_str', None)
 
89
        if s is not None:
 
90
            # contains a preformatted message; must be cast to plain str
 
91
            return str(s)
 
92
        try:
 
93
            # __str__() should always return a 'str' object
 
94
            # never a 'unicode' object.
 
95
            s = self._fmt % self.__dict__
 
96
            if isinstance(s, unicode):
 
97
                return s.encode('utf8')
 
98
            return s
 
99
        except (AttributeError, TypeError, NameError, ValueError, KeyError), e:
 
100
            return 'Unprintable exception %s: dict=%r, fmt=%r, error=%s' \
 
101
                % (self.__class__.__name__,
 
102
                   self.__dict__,
 
103
                   getattr(self, '_fmt', None),
 
104
                   str(e))
116
105
 
117
106
 
118
107
class BzrNewError(BzrError):
119
 
    """bzr error"""
 
108
    """Deprecated error base class."""
120
109
    # base classes should override the docstring with their human-
121
110
    # readable explanation
122
111
 
124
113
        # XXX: Use the underlying BzrError to always generate the args attribute
125
114
        # if it doesn't exist.  We can't use super here, because exceptions are
126
115
        # old-style classes in python2.4 (but new in 2.5).  --bmc, 20060426
 
116
        symbol_versioning.warn('BzrNewError was deprecated in bzr 0.12; '
 
117
             'please convert %s to use BzrError instead' 
 
118
             % self.__class__.__name__,
 
119
             DeprecationWarning,
 
120
             stacklevel=2)
127
121
        BzrError.__init__(self, *args)
128
122
        for key, value in kwds.items():
129
123
            setattr(self, key, value)
142
136
                   self.__dict__, str(e))
143
137
 
144
138
 
145
 
class AlreadyBuilding(BzrNewError):
146
 
    """The tree builder is already building a tree."""
147
 
 
148
 
 
149
 
class BzrCheckError(BzrNewError):
150
 
    """Internal check failed: %(message)s"""
 
139
class AlreadyBuilding(BzrError):
 
140
    
 
141
    _fmt = "The tree builder is already building a tree."
 
142
 
 
143
 
 
144
class BzrCheckError(BzrError):
 
145
    
 
146
    _fmt = "Internal check failed: %(message)s"
151
147
 
152
148
    is_user_error = False
153
149
 
154
150
    def __init__(self, message):
155
 
        BzrNewError.__init__(self)
 
151
        BzrError.__init__(self)
156
152
        self.message = message
157
153
 
158
154
 
159
 
class InvalidEntryName(BzrNewError):
160
 
    """Invalid entry name: %(name)s"""
 
155
class InvalidEntryName(BzrError):
 
156
    
 
157
    _fmt = "Invalid entry name: %(name)s"
161
158
 
162
159
    is_user_error = False
163
160
 
164
161
    def __init__(self, name):
165
 
        BzrNewError.__init__(self)
 
162
        BzrError.__init__(self)
166
163
        self.name = name
167
164
 
168
165
 
169
 
class InvalidRevisionNumber(BzrNewError):
170
 
    """Invalid revision number %(revno)d"""
 
166
class InvalidRevisionNumber(BzrError):
 
167
    
 
168
    _fmt = "Invalid revision number %(revno)s"
 
169
 
171
170
    def __init__(self, revno):
172
 
        BzrNewError.__init__(self)
 
171
        BzrError.__init__(self)
173
172
        self.revno = revno
174
173
 
175
174
 
176
 
class InvalidRevisionId(BzrNewError):
177
 
    """Invalid revision-id {%(revision_id)s} in %(branch)s"""
 
175
class InvalidRevisionId(BzrError):
 
176
 
 
177
    _fmt = "Invalid revision-id {%(revision_id)s} in %(branch)s"
178
178
 
179
179
    def __init__(self, revision_id, branch):
180
180
        # branch can be any string or object with __str__ defined
181
 
        BzrNewError.__init__(self)
 
181
        BzrError.__init__(self)
182
182
        self.revision_id = revision_id
183
183
        self.branch = branch
184
184
 
185
185
 
186
 
class NoSuchId(BzrNewError):
187
 
    """The file id %(file_id)s is not present in the tree %(tree)s."""
 
186
class NoSuchId(BzrError):
 
187
 
 
188
    _fmt = "The file id %(file_id)s is not present in the tree %(tree)s."
188
189
    
189
190
    def __init__(self, tree, file_id):
190
 
        BzrNewError.__init__(self)
 
191
        BzrError.__init__(self)
191
192
        self.file_id = file_id
192
193
        self.tree = tree
193
194
 
194
195
 
195
 
class NoWorkingTree(BzrNewError):
196
 
    """No WorkingTree exists for %(base)s."""
 
196
class NoWorkingTree(BzrError):
 
197
 
 
198
    _fmt = "No WorkingTree exists for %(base)s."
197
199
    
198
200
    def __init__(self, base):
199
 
        BzrNewError.__init__(self)
 
201
        BzrError.__init__(self)
200
202
        self.base = base
201
203
 
202
204
 
203
 
class NotBuilding(BzrNewError):
204
 
    """Not currently building a tree."""
205
 
 
206
 
 
207
 
class NotLocalUrl(BzrNewError):
208
 
    """%(url)s is not a local path."""
 
205
class NotBuilding(BzrError):
 
206
 
 
207
    _fmt = "Not currently building a tree."
 
208
 
 
209
 
 
210
class NotLocalUrl(BzrError):
 
211
 
 
212
    _fmt = "%(url)s is not a local path."
209
213
    
210
214
    def __init__(self, url):
211
 
        BzrNewError.__init__(self)
 
215
        BzrError.__init__(self)
212
216
        self.url = url
213
217
 
214
218
 
215
 
class BzrCommandError(BzrNewError):
 
219
class BzrCommandError(BzrError):
216
220
    """Error from user command"""
217
221
 
218
222
    is_user_error = True
237
241
 
238
242
 
239
243
class BzrOptionError(BzrCommandError):
240
 
    """Error in command line options"""
 
244
 
 
245
    _fmt = "Error in command line options"
241
246
 
242
247
    
243
 
class StrictCommitFailed(BzrNewError):
244
 
    """Commit refused because there are unknown files in the tree"""
 
248
class StrictCommitFailed(BzrError):
 
249
 
 
250
    _fmt = "Commit refused because there are unknown files in the tree"
245
251
 
246
252
 
247
253
# XXX: Should be unified with TransportError; they seem to represent the
248
254
# same thing
249
 
class PathError(BzrNewError):
250
 
    """Generic path error: %(path)r%(extra)s)"""
 
255
class PathError(BzrError):
 
256
    
 
257
    _fmt = "Generic path error: %(path)r%(extra)s)"
251
258
 
252
259
    def __init__(self, path, extra=None):
253
 
        BzrNewError.__init__(self)
 
260
        BzrError.__init__(self)
254
261
        self.path = path
255
262
        if extra:
256
263
            self.extra = ': ' + str(extra)
259
266
 
260
267
 
261
268
class NoSuchFile(PathError):
262
 
    """No such file: %(path)r%(extra)s"""
 
269
 
 
270
    _fmt = "No such file: %(path)r%(extra)s"
263
271
 
264
272
 
265
273
class FileExists(PathError):
266
 
    """File exists: %(path)r%(extra)s"""
 
274
 
 
275
    _fmt = "File exists: %(path)r%(extra)s"
267
276
 
268
277
 
269
278
class DirectoryNotEmpty(PathError):
270
 
    """Directory not empty: %(path)r%(extra)s"""
 
279
 
 
280
    _fmt = "Directory not empty: %(path)r%(extra)s"
271
281
 
272
282
 
273
283
class ResourceBusy(PathError):
274
 
    """Device or resource busy: %(path)r%(extra)s"""
 
284
 
 
285
    _fmt = "Device or resource busy: %(path)r%(extra)s"
275
286
 
276
287
 
277
288
class PermissionDenied(PathError):
278
 
    """Permission denied: %(path)r%(extra)s"""
 
289
 
 
290
    _fmt = "Permission denied: %(path)r%(extra)s"
279
291
 
280
292
 
281
293
class InvalidURL(PathError):
282
 
    """Invalid url supplied to transport: %(path)r%(extra)s"""
 
294
 
 
295
    _fmt = "Invalid url supplied to transport: %(path)r%(extra)s"
283
296
 
284
297
 
285
298
class InvalidURLJoin(PathError):
286
 
    """Invalid URL join request: %(args)s%(extra)s"""
 
299
 
 
300
    _fmt = "Invalid URL join request: %(args)s%(extra)s"
287
301
 
288
302
    def __init__(self, msg, base, args):
289
303
        PathError.__init__(self, base, msg)
291
305
 
292
306
 
293
307
class UnsupportedProtocol(PathError):
294
 
    """Unsupported protocol for url "%(path)s"%(extra)s"""
 
308
 
 
309
    _fmt = 'Unsupported protocol for url "%(path)s"%(extra)s'
295
310
 
296
311
    def __init__(self, url, extra):
297
312
        PathError.__init__(self, url, extra=extra)
298
313
 
299
314
 
300
315
class ShortReadvError(PathError):
301
 
    """readv() read %(actual)s bytes rather than %(length)s bytes at %(offset)s for %(path)s%(extra)s"""
 
316
 
 
317
    _fmt = "readv() read %(actual)s bytes rather than %(length)s bytes at %(offset)s for %(path)s%(extra)s"
302
318
 
303
319
    is_user_error = False
304
320
 
309
325
        self.actual = actual
310
326
 
311
327
 
312
 
class PathNotChild(BzrNewError):
313
 
    """Path %(path)r is not a child of path %(base)r%(extra)s"""
 
328
class PathNotChild(BzrError):
 
329
 
 
330
    _fmt = "Path %(path)r is not a child of path %(base)r%(extra)s"
314
331
 
315
332
    is_user_error = False
316
333
 
317
334
    def __init__(self, path, base, extra=None):
318
 
        BzrNewError.__init__(self)
 
335
        BzrError.__init__(self)
319
336
        self.path = path
320
337
        self.base = base
321
338
        if extra:
325
342
 
326
343
 
327
344
class InvalidNormalization(PathError):
328
 
    """Path %(path)r is not unicode normalized"""
 
345
 
 
346
    _fmt = "Path %(path)r is not unicode normalized"
329
347
 
330
348
 
331
349
# TODO: This is given a URL; we try to unescape it but doing that from inside
332
350
# the exception object is a bit undesirable.
333
351
# TODO: Probably this behavior of should be a common superclass 
334
352
class NotBranchError(PathError):
335
 
    """Not a branch: %(path)s"""
 
353
 
 
354
    _fmt = "Not a branch: %(path)s"
336
355
 
337
356
    def __init__(self, path):
338
357
       import bzrlib.urlutils as urlutils
340
359
 
341
360
 
342
361
class AlreadyBranchError(PathError):
343
 
    """Already a branch: %(path)s."""
 
362
 
 
363
    _fmt = "Already a branch: %(path)s."
344
364
 
345
365
 
346
366
class BranchExistsWithoutWorkingTree(PathError):
347
 
    """Directory contains a branch, but no working tree \
 
367
 
 
368
    _fmt = "Directory contains a branch, but no working tree \
348
369
(use bzr checkout if you wish to build a working tree): %(path)s"""
349
370
 
350
371
 
351
372
class AtomicFileAlreadyClosed(PathError):
352
 
    """'%(function)s' called on an AtomicFile after it was closed: %(path)s"""
 
373
 
 
374
    _fmt = "'%(function)s' called on an AtomicFile after it was closed: %(path)s"
353
375
 
354
376
    def __init__(self, path, function):
355
377
        PathError.__init__(self, path=path, extra=None)
357
379
 
358
380
 
359
381
class InaccessibleParent(PathError):
360
 
    """Parent not accessible given base %(base)s and relative path %(path)s"""
 
382
 
 
383
    _fmt = "Parent not accessible given base %(base)s and relative path %(path)s"
361
384
 
362
385
    def __init__(self, path, base):
363
386
        PathError.__init__(self, path)
364
387
        self.base = base
365
388
 
366
389
 
367
 
class NoRepositoryPresent(BzrNewError):
368
 
    """No repository present: %(path)r"""
 
390
class NoRepositoryPresent(BzrError):
 
391
 
 
392
    _fmt = "No repository present: %(path)r"
369
393
    def __init__(self, bzrdir):
370
 
        BzrNewError.__init__(self)
 
394
        BzrError.__init__(self)
371
395
        self.path = bzrdir.transport.clone('..').base
372
396
 
373
397
 
374
 
class FileInWrongBranch(BzrNewError):
375
 
    """File %(path)s in not in branch %(branch_base)s."""
 
398
class FileInWrongBranch(BzrError):
 
399
 
 
400
    _fmt = "File %(path)s in not in branch %(branch_base)s."
376
401
 
377
402
    def __init__(self, branch, path):
378
 
        BzrNewError.__init__(self)
 
403
        BzrError.__init__(self)
379
404
        self.branch = branch
380
405
        self.branch_base = branch.base
381
406
        self.path = path
382
407
 
383
408
 
384
 
class UnsupportedFormatError(BzrNewError):
385
 
    """Unsupported branch format: %(format)s"""
386
 
 
387
 
 
388
 
class UnknownFormatError(BzrNewError):
389
 
    """Unknown branch format: %(format)r"""
390
 
 
391
 
 
392
 
class IncompatibleFormat(BzrNewError):
393
 
    """Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
 
409
class UnsupportedFormatError(BzrError):
 
410
    
 
411
    _fmt = "Unsupported branch format: %(format)s"
 
412
 
 
413
 
 
414
class UnknownFormatError(BzrError):
 
415
    
 
416
    _fmt = "Unknown branch format: %(format)r"
 
417
 
 
418
 
 
419
class IncompatibleFormat(BzrError):
 
420
    
 
421
    _fmt = "Format %(format)s is not compatible with .bzr version %(bzrdir)s."
394
422
 
395
423
    def __init__(self, format, bzrdir_format):
396
 
        BzrNewError.__init__(self)
 
424
        BzrError.__init__(self)
397
425
        self.format = format
398
426
        self.bzrdir = bzrdir_format
399
427
 
400
428
 
401
 
class IncompatibleRevision(BzrNewError):
402
 
    """Revision is not compatible with %(repo_format)s"""
 
429
class IncompatibleRevision(BzrError):
 
430
    
 
431
    _fmt = "Revision is not compatible with %(repo_format)s"
403
432
 
404
433
    def __init__(self, repo_format):
405
 
        BzrNewError.__init__(self)
 
434
        BzrError.__init__(self)
406
435
        self.repo_format = repo_format
407
436
 
408
437
 
409
 
class NotVersionedError(BzrNewError):
410
 
    """%(path)s is not versioned"""
 
438
class NotVersionedError(BzrError):
 
439
 
 
440
    _fmt = "%(path)s is not versioned"
 
441
 
411
442
    def __init__(self, path):
412
 
        BzrNewError.__init__(self)
 
443
        BzrError.__init__(self)
413
444
        self.path = path
414
445
 
415
446
 
416
 
class PathsNotVersionedError(BzrNewError):
 
447
class PathsNotVersionedError(BzrError):
417
448
    # used when reporting several paths are not versioned
418
 
    """Path(s) are not versioned: %(paths_as_string)s"""
 
449
 
 
450
    _fmt = "Path(s) are not versioned: %(paths_as_string)s"
419
451
 
420
452
    def __init__(self, paths):
421
453
        from bzrlib.osutils import quotefn
422
 
        BzrNewError.__init__(self)
 
454
        BzrError.__init__(self)
423
455
        self.paths = paths
424
456
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
425
457
 
426
458
 
427
 
class PathsDoNotExist(BzrNewError):
428
 
    """Path(s) do not exist: %(paths_as_string)s"""
 
459
class PathsDoNotExist(BzrError):
 
460
 
 
461
    _fmt = "Path(s) do not exist: %(paths_as_string)s"
429
462
 
430
463
    # used when reporting that paths are neither versioned nor in the working
431
464
    # tree
433
466
    def __init__(self, paths):
434
467
        # circular import
435
468
        from bzrlib.osutils import quotefn
436
 
        BzrNewError.__init__(self)
 
469
        BzrError.__init__(self)
437
470
        self.paths = paths
438
471
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
439
472
 
440
473
 
441
 
class BadFileKindError(BzrNewError):
442
 
    """Cannot operate on %(filename)s of unsupported kind %(kind)s"""
443
 
 
444
 
 
445
 
class ForbiddenControlFileError(BzrNewError):
446
 
    """Cannot operate on %(filename)s because it is a control file"""
447
 
 
448
 
 
449
 
class LockError(BzrNewError):
450
 
    """Lock error: %(message)s"""
 
474
class BadFileKindError(BzrError):
 
475
 
 
476
    _fmt = "Cannot operate on %(filename)s of unsupported kind %(kind)s"
 
477
 
 
478
 
 
479
class ForbiddenControlFileError(BzrError):
 
480
 
 
481
    _fmt = "Cannot operate on %(filename)s because it is a control file"
 
482
 
 
483
 
 
484
class LockError(BzrError):
 
485
 
 
486
    _fmt = "Lock error: %(message)s"
451
487
    # All exceptions from the lock/unlock functions should be from
452
488
    # this exception class.  They will be translated as necessary. The
453
489
    # original exception is available as e.original_error
458
494
 
459
495
 
460
496
class CommitNotPossible(LockError):
461
 
    """A commit was attempted but we do not have a write lock open."""
 
497
 
 
498
    _fmt = "A commit was attempted but we do not have a write lock open."
462
499
    def __init__(self):
463
500
        pass
464
501
 
465
502
 
466
503
class AlreadyCommitted(LockError):
467
 
    """A rollback was requested, but is not able to be accomplished."""
 
504
 
 
505
    _fmt = "A rollback was requested, but is not able to be accomplished."
468
506
    def __init__(self):
469
507
        pass
470
508
 
471
509
 
472
510
class ReadOnlyError(LockError):
473
 
    """A write attempt was made in a read only transaction on %(obj)s"""
 
511
 
 
512
    _fmt = "A write attempt was made in a read only transaction on %(obj)s"
474
513
    def __init__(self, obj):
475
514
        self.obj = obj
476
515
 
477
516
 
478
 
class OutSideTransaction(BzrNewError):
479
 
    """A transaction related operation was attempted after the transaction finished."""
 
517
class OutSideTransaction(BzrError):
 
518
 
 
519
    _fmt = "A transaction related operation was attempted after the transaction finished."
480
520
 
481
521
 
482
522
class ObjectNotLocked(LockError):
483
 
    """%(obj)r is not locked"""
 
523
 
 
524
    _fmt = "%(obj)r is not locked"
484
525
 
485
526
    is_user_error = False
486
527
 
492
533
 
493
534
 
494
535
class ReadOnlyObjectDirtiedError(ReadOnlyError):
495
 
    """Cannot change object %(obj)r in read only transaction"""
 
536
 
 
537
    _fmt = "Cannot change object %(obj)r in read only transaction"
496
538
    def __init__(self, obj):
497
539
        self.obj = obj
498
540
 
499
541
 
500
542
class UnlockableTransport(LockError):
501
 
    """Cannot lock: transport is read only: %(transport)s"""
 
543
 
 
544
    _fmt = "Cannot lock: transport is read only: %(transport)s"
502
545
    def __init__(self, transport):
503
546
        self.transport = transport
504
547
 
505
548
 
506
549
class LockContention(LockError):
507
 
    """Could not acquire lock %(lock)s"""
 
550
 
 
551
    _fmt = "Could not acquire lock %(lock)s"
508
552
    # TODO: show full url for lock, combining the transport and relative bits?
 
553
    
509
554
    def __init__(self, lock):
510
555
        self.lock = lock
511
556
 
512
557
 
513
558
class LockBroken(LockError):
514
 
    """Lock was broken while still open: %(lock)s - check storage consistency!"""
 
559
 
 
560
    _fmt = "Lock was broken while still open: %(lock)s - check storage consistency!"
 
561
 
515
562
    def __init__(self, lock):
516
563
        self.lock = lock
517
564
 
518
565
 
519
566
class LockBreakMismatch(LockError):
520
 
    """Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
 
567
 
 
568
    _fmt = "Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"
 
569
 
521
570
    def __init__(self, lock, holder, target):
522
571
        self.lock = lock
523
572
        self.holder = holder
525
574
 
526
575
 
527
576
class LockNotHeld(LockError):
528
 
    """Lock not held: %(lock)s"""
 
577
 
 
578
    _fmt = "Lock not held: %(lock)s"
 
579
 
529
580
    def __init__(self, lock):
530
581
        self.lock = lock
531
582
 
532
583
 
533
 
class PointlessCommit(BzrNewError):
534
 
    """No changes to commit"""
535
 
 
536
 
 
537
 
class UpgradeReadonly(BzrNewError):
538
 
    """Upgrade URL cannot work with readonly URL's."""
539
 
 
540
 
 
541
 
class UpToDateFormat(BzrNewError):
542
 
    """The branch format %(format)s is already at the most recent format."""
 
584
class PointlessCommit(BzrError):
 
585
 
 
586
    _fmt = "No changes to commit"
 
587
 
 
588
 
 
589
class UpgradeReadonly(BzrError):
 
590
 
 
591
    _fmt = "Upgrade URL cannot work with readonly URLs."
 
592
 
 
593
 
 
594
class UpToDateFormat(BzrError):
 
595
 
 
596
    _fmt = "The branch format %(format)s is already at the most recent format."
543
597
 
544
598
    def __init__(self, format):
545
 
        BzrNewError.__init__(self)
 
599
        BzrError.__init__(self)
546
600
        self.format = format
547
601
 
548
602
 
549
603
class StrictCommitFailed(Exception):
550
 
    """Commit refused because there are unknowns in the tree."""
551
 
 
552
 
 
553
 
class NoSuchRevision(BzrNewError):
554
 
    """Branch %(branch)s has no revision %(revision)s"""
 
604
 
 
605
    _fmt = "Commit refused because there are unknowns in the tree."
 
606
 
 
607
 
 
608
class NoSuchRevision(BzrError):
 
609
 
 
610
    _fmt = "Branch %(branch)s has no revision %(revision)s"
555
611
 
556
612
    is_user_error = False
557
613
 
558
614
    def __init__(self, branch, revision):
559
 
        BzrNewError.__init__(self, branch=branch, revision=revision)
560
 
 
561
 
 
562
 
class NoSuchRevisionSpec(BzrNewError):
563
 
    """No namespace registered for string: %(spec)r"""
 
615
        BzrError.__init__(self, branch=branch, revision=revision)
 
616
 
 
617
 
 
618
class NoSuchRevisionSpec(BzrError):
 
619
 
 
620
    _fmt = "No namespace registered for string: %(spec)r"
564
621
 
565
622
    def __init__(self, spec):
566
 
        BzrNewError.__init__(self, spec=spec)
567
 
 
568
 
 
569
 
class InvalidRevisionSpec(BzrNewError):
570
 
    """Requested revision: '%(spec)s' does not exist in branch:
571
 
%(branch)s%(extra)s"""
 
623
        BzrError.__init__(self, spec=spec)
 
624
 
 
625
 
 
626
class InvalidRevisionSpec(BzrError):
 
627
 
 
628
    _fmt = "Requested revision: %(spec)r does not exist in branch: %(branch)s%(extra)s"
572
629
 
573
630
    def __init__(self, spec, branch, extra=None):
574
 
        BzrNewError.__init__(self, branch=branch, spec=spec)
 
631
        BzrError.__init__(self, branch=branch, spec=spec)
575
632
        if extra:
576
633
            self.extra = '\n' + str(extra)
577
634
        else:
579
636
 
580
637
 
581
638
class HistoryMissing(BzrError):
582
 
    def __init__(self, branch, object_type, object_id):
583
 
        self.branch = branch
584
 
        BzrError.__init__(self,
585
 
                          '%s is missing %s {%s}'
586
 
                          % (branch, object_type, object_id))
587
 
 
588
 
 
589
 
class DivergedBranches(BzrNewError):
590
 
    "These branches have diverged.  Use the merge command to reconcile them."""
 
639
 
 
640
    _fmt = "%(branch)s is missing %(object_type)s {%(object_id)s}"
 
641
 
 
642
 
 
643
class DivergedBranches(BzrError):
 
644
    
 
645
    _fmt = "These branches have diverged.  Use the merge command to reconcile them."""
591
646
 
592
647
    is_user_error = True
593
648
 
596
651
        self.branch2 = branch2
597
652
 
598
653
 
599
 
class UnrelatedBranches(BzrNewError):
 
654
class UnrelatedBranches(BzrError):
600
655
    "Branches have no common ancestor, and no merge base revision was specified."
601
656
 
602
657
    is_user_error = True
603
658
 
604
659
 
605
 
class NoCommonAncestor(BzrNewError):
 
660
class NoCommonAncestor(BzrError):
606
661
    "Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
607
662
 
608
663
    def __init__(self, revision_a, revision_b):
611
666
 
612
667
 
613
668
class NoCommonRoot(BzrError):
 
669
 
 
670
    _fmt = "Revisions are not derived from the same root: " \
 
671
           "%(revision_a)s %(revision_b)s."
 
672
 
614
673
    def __init__(self, revision_a, revision_b):
615
 
        msg = "Revisions are not derived from the same root: %s %s." \
616
 
            % (revision_a, revision_b) 
617
 
        BzrError.__init__(self, msg)
618
 
 
 
674
        BzrError.__init__(self, revision_a=revision_a, revision_b=revision_b)
619
675
 
620
676
 
621
677
class NotAncestor(BzrError):
 
678
 
 
679
    _fmt = "Revision %(rev_id)s is not an ancestor of %(not_ancestor_id)s"
 
680
 
622
681
    def __init__(self, rev_id, not_ancestor_id):
623
 
        msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id, 
624
 
                                                        rev_id)
625
 
        BzrError.__init__(self, msg)
626
 
        self.rev_id = rev_id
627
 
        self.not_ancestor_id = not_ancestor_id
 
682
        BzrError.__init__(self, rev_id=rev_id,
 
683
            not_ancestor_id=not_ancestor_id)
628
684
 
629
685
 
630
686
class InstallFailed(BzrError):
644
700
        self.bases = bases
645
701
 
646
702
 
647
 
class NoCommits(BzrNewError):
648
 
    """Branch %(branch)s has no commits."""
 
703
class NoCommits(BzrError):
 
704
 
 
705
    _fmt = "Branch %(branch)s has no commits."
649
706
 
650
707
    def __init__(self, branch):
651
 
        BzrNewError.__init__(self, branch=branch)
 
708
        BzrError.__init__(self, branch=branch)
652
709
 
653
710
 
654
711
class UnlistableStore(BzrError):
662
719
        BzrError.__init__(self, "Stores for branch %s are not listable" % br)
663
720
 
664
721
 
665
 
class BoundBranchOutOfDate(BzrNewError):
666
 
    """Bound branch %(branch)s is out of date with master branch %(master)s."""
 
722
class BoundBranchOutOfDate(BzrError):
 
723
 
 
724
    _fmt = "Bound branch %(branch)s is out of date with master branch %(master)s."
667
725
    def __init__(self, branch, master):
668
 
        BzrNewError.__init__(self)
 
726
        BzrError.__init__(self)
669
727
        self.branch = branch
670
728
        self.master = master
671
729
 
672
730
        
673
 
class CommitToDoubleBoundBranch(BzrNewError):
674
 
    """Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
 
731
class CommitToDoubleBoundBranch(BzrError):
 
732
 
 
733
    _fmt = "Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."
675
734
    def __init__(self, branch, master, remote):
676
 
        BzrNewError.__init__(self)
 
735
        BzrError.__init__(self)
677
736
        self.branch = branch
678
737
        self.master = master
679
738
        self.remote = remote
680
739
 
681
740
 
682
 
class OverwriteBoundBranch(BzrNewError):
683
 
    """Cannot pull --overwrite to a branch which is bound %(branch)s"""
 
741
class OverwriteBoundBranch(BzrError):
 
742
 
 
743
    _fmt = "Cannot pull --overwrite to a branch which is bound %(branch)s"
684
744
    def __init__(self, branch):
685
 
        BzrNewError.__init__(self)
 
745
        BzrError.__init__(self)
686
746
        self.branch = branch
687
747
 
688
748
 
689
 
class BoundBranchConnectionFailure(BzrNewError):
690
 
    """Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
 
749
class BoundBranchConnectionFailure(BzrError):
 
750
 
 
751
    _fmt = "Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"
691
752
    def __init__(self, branch, target, error):
692
 
        BzrNewError.__init__(self)
 
753
        BzrError.__init__(self)
693
754
        self.branch = branch
694
755
        self.target = target
695
756
        self.error = error
696
757
 
697
758
 
698
 
class WeaveError(BzrNewError):
699
 
    """Error in processing weave: %(message)s"""
 
759
class WeaveError(BzrError):
 
760
 
 
761
    _fmt = "Error in processing weave: %(message)s"
700
762
 
701
763
    def __init__(self, message=None):
702
 
        BzrNewError.__init__(self)
 
764
        BzrError.__init__(self)
703
765
        self.message = message
704
766
 
705
767
 
706
768
class WeaveRevisionAlreadyPresent(WeaveError):
707
 
    """Revision {%(revision_id)s} already present in %(weave)s"""
 
769
 
 
770
    _fmt = "Revision {%(revision_id)s} already present in %(weave)s"
708
771
    def __init__(self, revision_id, weave):
709
772
 
710
773
        WeaveError.__init__(self)
713
776
 
714
777
 
715
778
class WeaveRevisionNotPresent(WeaveError):
716
 
    """Revision {%(revision_id)s} not present in %(weave)s"""
 
779
 
 
780
    _fmt = "Revision {%(revision_id)s} not present in %(weave)s"
717
781
 
718
782
    def __init__(self, revision_id, weave):
719
783
        WeaveError.__init__(self)
722
786
 
723
787
 
724
788
class WeaveFormatError(WeaveError):
725
 
    """Weave invariant violated: %(what)s"""
 
789
 
 
790
    _fmt = "Weave invariant violated: %(what)s"
726
791
 
727
792
    def __init__(self, what):
728
793
        WeaveError.__init__(self)
730
795
 
731
796
 
732
797
class WeaveParentMismatch(WeaveError):
733
 
    """Parents are mismatched between two revisions."""
 
798
 
 
799
    _fmt = "Parents are mismatched between two revisions."
734
800
    
735
801
 
736
802
class WeaveInvalidChecksum(WeaveError):
737
 
    """Text did not match it's checksum: %(message)s"""
738
 
 
739
 
 
740
 
class WeaveTextDiffers(WeaveError):
741
 
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
742
 
 
743
 
    def __init__(self, revision_id, weave_a, weave_b):
744
 
        WeaveError.__init__(self)
745
 
        self.revision_id = revision_id
746
 
        self.weave_a = weave_a
747
 
        self.weave_b = weave_b
748
 
 
749
 
 
750
 
class WeaveTextDiffers(WeaveError):
751
 
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
752
 
 
753
 
    def __init__(self, revision_id, weave_a, weave_b):
754
 
        WeaveError.__init__(self)
755
 
        self.revision_id = revision_id
756
 
        self.weave_a = weave_a
757
 
        self.weave_b = weave_b
758
 
 
759
 
 
760
 
class VersionedFileError(BzrNewError):
761
 
    """Versioned file error."""
 
803
 
 
804
    _fmt = "Text did not match it's checksum: %(message)s"
 
805
 
 
806
 
 
807
class WeaveTextDiffers(WeaveError):
 
808
 
 
809
    _fmt = "Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"
 
810
 
 
811
    def __init__(self, revision_id, weave_a, weave_b):
 
812
        WeaveError.__init__(self)
 
813
        self.revision_id = revision_id
 
814
        self.weave_a = weave_a
 
815
        self.weave_b = weave_b
 
816
 
 
817
 
 
818
class WeaveTextDiffers(WeaveError):
 
819
 
 
820
    _fmt = "Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"
 
821
 
 
822
    def __init__(self, revision_id, weave_a, weave_b):
 
823
        WeaveError.__init__(self)
 
824
        self.revision_id = revision_id
 
825
        self.weave_a = weave_a
 
826
        self.weave_b = weave_b
 
827
 
 
828
 
 
829
class VersionedFileError(BzrError):
 
830
    
 
831
    _fmt = "Versioned file error"
762
832
 
763
833
 
764
834
class RevisionNotPresent(VersionedFileError):
765
 
    """Revision {%(revision_id)s} not present in %(file_id)s."""
 
835
    
 
836
    _fmt = "Revision {%(revision_id)s} not present in %(file_id)s."
766
837
 
767
838
    def __init__(self, revision_id, file_id):
768
839
        VersionedFileError.__init__(self)
771
842
 
772
843
 
773
844
class RevisionAlreadyPresent(VersionedFileError):
774
 
    """Revision {%(revision_id)s} already present in %(file_id)s."""
 
845
    
 
846
    _fmt = "Revision {%(revision_id)s} already present in %(file_id)s."
775
847
 
776
848
    def __init__(self, revision_id, file_id):
777
849
        VersionedFileError.__init__(self)
779
851
        self.file_id = file_id
780
852
 
781
853
 
782
 
class KnitError(BzrNewError):
783
 
    """Knit error"""
 
854
class KnitError(BzrError):
 
855
    
 
856
    _fmt = "Knit error"
784
857
 
785
858
 
786
859
class KnitHeaderError(KnitError):
787
 
    """Knit header error: %(badline)r unexpected"""
 
860
 
 
861
    _fmt = "Knit header error: %(badline)r unexpected"
788
862
 
789
863
    def __init__(self, badline):
790
864
        KnitError.__init__(self)
792
866
 
793
867
 
794
868
class KnitCorrupt(KnitError):
795
 
    """Knit %(filename)s corrupt: %(how)s"""
 
869
 
 
870
    _fmt = "Knit %(filename)s corrupt: %(how)s"
796
871
 
797
872
    def __init__(self, filename, how):
798
873
        KnitError.__init__(self)
800
875
        self.how = how
801
876
 
802
877
 
803
 
class NoSuchExportFormat(BzrNewError):
804
 
    """Export format %(format)r not supported"""
 
878
class NoSuchExportFormat(BzrError):
 
879
    
 
880
    _fmt = "Export format %(format)r not supported"
 
881
 
805
882
    def __init__(self, format):
806
 
        BzrNewError.__init__(self)
 
883
        BzrError.__init__(self)
807
884
        self.format = format
808
885
 
809
886
 
810
 
class TransportError(BzrNewError):
811
 
    """Transport error: %(msg)s %(orig_error)s"""
 
887
class TransportError(BzrError):
 
888
    
 
889
    _fmt = "Transport error: %(msg)s %(orig_error)s"
812
890
 
813
891
    def __init__(self, msg=None, orig_error=None):
814
892
        if msg is None and orig_error is not None:
819
897
            msg =  ''
820
898
        self.msg = msg
821
899
        self.orig_error = orig_error
822
 
        BzrNewError.__init__(self)
 
900
        BzrError.__init__(self)
823
901
 
824
902
 
825
903
class SmartProtocolError(TransportError):
826
 
    """Generic bzr smart protocol error: %(details)s"""
 
904
 
 
905
    _fmt = "Generic bzr smart protocol error: %(details)s"
827
906
 
828
907
    def __init__(self, details):
829
908
        self.details = details
831
910
 
832
911
# A set of semi-meaningful errors which can be thrown
833
912
class TransportNotPossible(TransportError):
834
 
    """Transport operation not possible: %(msg)s %(orig_error)s"""
 
913
 
 
914
    _fmt = "Transport operation not possible: %(msg)s %(orig_error)s"
835
915
 
836
916
 
837
917
class ConnectionError(TransportError):
838
 
    """Connection error: %(msg)s %(orig_error)s"""
 
918
 
 
919
    _fmt = "Connection error: %(msg)s %(orig_error)s"
839
920
 
840
921
 
841
922
class ConnectionReset(TransportError):
842
 
    """Connection closed: %(msg)s %(orig_error)s"""
 
923
 
 
924
    _fmt = "Connection closed: %(msg)s %(orig_error)s"
843
925
 
844
926
 
845
927
class InvalidRange(TransportError):
846
 
    """Invalid range access in %(path)s at %(offset)s."""
 
928
 
 
929
    _fmt = "Invalid range access in %(path)s at %(offset)s."
847
930
    
848
931
    def __init__(self, path, offset):
849
932
        TransportError.__init__(self, ("Invalid range access in %s at %d"
853
936
 
854
937
 
855
938
class InvalidHttpResponse(TransportError):
856
 
    """Invalid http response for %(path)s: %(msg)s"""
 
939
 
 
940
    _fmt = "Invalid http response for %(path)s: %(msg)s"
857
941
 
858
942
    def __init__(self, path, msg, orig_error=None):
859
943
        self.path = path
861
945
 
862
946
 
863
947
class InvalidHttpRange(InvalidHttpResponse):
864
 
    """Invalid http range "%(range)s" for %(path)s: %(msg)s"""
 
948
 
 
949
    _fmt = "Invalid http range %(range)r for %(path)s: %(msg)s"
865
950
    
866
951
    def __init__(self, path, range, msg):
867
952
        self.range = range
869
954
 
870
955
 
871
956
class InvalidHttpContentType(InvalidHttpResponse):
872
 
    """Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
 
957
 
 
958
    _fmt = 'Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s'
873
959
    
874
960
    def __init__(self, path, ctype, msg):
875
961
        self.ctype = ctype
890
976
        BzrError.__init__(self, message)
891
977
 
892
978
 
893
 
class NoEmailInUsername(BzrNewError):
894
 
    """%(username)r does not seem to contain a reasonable email address"""
 
979
class NoEmailInUsername(BzrError):
 
980
 
 
981
    _fmt = "%(username)r does not seem to contain a reasonable email address"
895
982
 
896
983
    def __init__(self, username):
897
 
        BzrNewError.__init__(self)
 
984
        BzrError.__init__(self)
898
985
        self.username = username
899
986
 
900
987
 
901
988
class SigningFailed(BzrError):
 
989
 
 
990
    _fmt = "Failed to gpg sign data with command %(command_line)r"
 
991
 
902
992
    def __init__(self, command_line):
903
 
        BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
904
 
                               % command_line)
 
993
        BzrError.__init__(self, command_line=command_line)
905
994
 
906
995
 
907
996
class WorkingTreeNotRevision(BzrError):
 
997
 
 
998
    _fmt = ("The working tree for %(basedir)s has changed since" 
 
999
            " the last commit, but weave merge requires that it be"
 
1000
            " unchanged")
 
1001
 
908
1002
    def __init__(self, tree):
909
 
        BzrError.__init__(self, "The working tree for %s has changed since"
910
 
                          " last commit, but weave merge requires that it be"
911
 
                          " unchanged." % tree.basedir)
912
 
 
913
 
 
914
 
class CantReprocessAndShowBase(BzrNewError):
915
 
    """Can't reprocess and show base.
916
 
Reprocessing obscures relationship of conflicting lines to base."""
917
 
 
918
 
 
919
 
class GraphCycleError(BzrNewError):
920
 
    """Cycle in graph %(graph)r"""
 
1003
        BzrError.__init__(self, basedir=tree.basedir)
 
1004
 
 
1005
 
 
1006
class CantReprocessAndShowBase(BzrError):
 
1007
 
 
1008
    _fmt = "Can't reprocess and show base, because reprocessing obscures " \
 
1009
           "the relationship of conflicting lines to the base"
 
1010
 
 
1011
 
 
1012
class GraphCycleError(BzrError):
 
1013
 
 
1014
    _fmt = "Cycle in graph %(graph)r"
921
1015
    def __init__(self, graph):
922
 
        BzrNewError.__init__(self)
 
1016
        BzrError.__init__(self)
923
1017
        self.graph = graph
924
1018
 
925
1019
 
926
 
class NotConflicted(BzrNewError):
927
 
    """File %(filename)s is not conflicted."""
 
1020
class NotConflicted(BzrError):
 
1021
 
 
1022
    _fmt = "File %(filename)s is not conflicted."
928
1023
 
929
1024
    def __init__(self, filename):
930
 
        BzrNewError.__init__(self)
 
1025
        BzrError.__init__(self)
931
1026
        self.filename = filename
932
1027
 
933
1028
 
938
1033
    """
939
1034
 
940
1035
 
941
 
class NoBundleFound(BzrNewError):
942
 
    """No bundle was found in %(filename)s"""
 
1036
class NoBundleFound(BzrError):
 
1037
 
 
1038
    _fmt = "No bundle was found in %(filename)s"
943
1039
    def __init__(self, filename):
944
 
        BzrNewError.__init__(self)
 
1040
        BzrError.__init__(self)
945
1041
        self.filename = filename
946
1042
 
947
1043
 
948
 
class BundleNotSupported(BzrNewError):
949
 
    """Unable to handle bundle version %(version)s: %(msg)s"""
 
1044
class BundleNotSupported(BzrError):
 
1045
 
 
1046
    _fmt = "Unable to handle bundle version %(version)s: %(msg)s"
950
1047
    def __init__(self, version, msg):
951
 
        BzrNewError.__init__(self)
 
1048
        BzrError.__init__(self)
952
1049
        self.version = version
953
1050
        self.msg = msg
954
1051
 
955
1052
 
956
 
class MissingText(BzrNewError):
957
 
    """Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
 
1053
class MissingText(BzrError):
 
1054
 
 
1055
    _fmt = "Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"
958
1056
 
959
1057
    def __init__(self, branch, text_revision, file_id):
960
 
        BzrNewError.__init__(self)
 
1058
        BzrError.__init__(self)
961
1059
        self.branch = branch
962
1060
        self.base = branch.base
963
1061
        self.text_revision = text_revision
964
1062
        self.file_id = file_id
965
1063
 
966
1064
 
967
 
class DuplicateKey(BzrNewError):
968
 
    """Key %(key)s is already present in map"""
969
 
 
970
 
 
971
 
class MalformedTransform(BzrNewError):
972
 
    """Tree transform is malformed %(conflicts)r"""
973
 
 
974
 
 
975
 
class BzrBadParameter(BzrNewError):
976
 
    """A bad parameter : %(param)s is not usable.
 
1065
class DuplicateKey(BzrError):
 
1066
 
 
1067
    _fmt = "Key %(key)s is already present in map"
 
1068
 
 
1069
 
 
1070
class MalformedTransform(BzrError):
 
1071
 
 
1072
    _fmt = "Tree transform is malformed %(conflicts)r"
 
1073
 
 
1074
 
 
1075
class BzrBadParameter(BzrError):
 
1076
 
 
1077
    _fmt = "Bad parameter: %(param)r"
977
1078
    
978
 
    This exception should never be thrown, but it is a base class for all
979
 
    parameter-to-function errors.
980
 
    """
 
1079
    # This exception should never be thrown, but it is a base class for all
 
1080
    # parameter-to-function errors.
 
1081
 
981
1082
    def __init__(self, param):
982
 
        BzrNewError.__init__(self)
 
1083
        BzrError.__init__(self)
983
1084
        self.param = param
984
1085
 
985
1086
 
986
1087
class BzrBadParameterNotUnicode(BzrBadParameter):
987
 
    """Parameter %(param)s is neither unicode nor utf8."""
988
 
 
989
 
 
990
 
class ReusingTransform(BzrNewError):
991
 
    """Attempt to reuse a transform that has already been applied."""
992
 
 
993
 
 
994
 
class CantMoveRoot(BzrNewError):
995
 
    """Moving the root directory is not supported at this time"""
 
1088
 
 
1089
    _fmt = "Parameter %(param)s is neither unicode nor utf8."
 
1090
 
 
1091
 
 
1092
class ReusingTransform(BzrError):
 
1093
 
 
1094
    _fmt = "Attempt to reuse a transform that has already been applied."
 
1095
 
 
1096
 
 
1097
class CantMoveRoot(BzrError):
 
1098
 
 
1099
    _fmt = "Moving the root directory is not supported at this time"
996
1100
 
997
1101
 
998
1102
class BzrBadParameterNotString(BzrBadParameter):
999
 
    """Parameter %(param)s is not a string or unicode string."""
 
1103
 
 
1104
    _fmt = "Parameter %(param)s is not a string or unicode string."
1000
1105
 
1001
1106
 
1002
1107
class BzrBadParameterMissing(BzrBadParameter):
1003
 
    """Parameter $(param)s is required but not present."""
 
1108
 
 
1109
    _fmt = "Parameter $(param)s is required but not present."
1004
1110
 
1005
1111
 
1006
1112
class BzrBadParameterUnicode(BzrBadParameter):
1007
 
    """Parameter %(param)s is unicode but only byte-strings are permitted."""
 
1113
 
 
1114
    _fmt = "Parameter %(param)s is unicode but only byte-strings are permitted."
1008
1115
 
1009
1116
 
1010
1117
class BzrBadParameterContainsNewline(BzrBadParameter):
1011
 
    """Parameter %(param)s contains a newline."""
1012
 
 
1013
 
 
1014
 
class DependencyNotPresent(BzrNewError):
1015
 
    """Unable to import library "%(library)s": %(error)s"""
 
1118
 
 
1119
    _fmt = "Parameter %(param)s contains a newline."
 
1120
 
 
1121
 
 
1122
class DependencyNotPresent(BzrError):
 
1123
 
 
1124
    _fmt = 'Unable to import library "%(library)s": %(error)s'
1016
1125
 
1017
1126
    def __init__(self, library, error):
1018
 
        BzrNewError.__init__(self, library=library, error=error)
 
1127
        BzrError.__init__(self, library=library, error=error)
1019
1128
 
1020
1129
 
1021
1130
class ParamikoNotPresent(DependencyNotPresent):
1022
 
    """Unable to import paramiko (required for sftp support): %(error)s"""
 
1131
 
 
1132
    _fmt = "Unable to import paramiko (required for sftp support): %(error)s"
1023
1133
 
1024
1134
    def __init__(self, error):
1025
1135
        DependencyNotPresent.__init__(self, 'paramiko', error)
1026
1136
 
1027
1137
 
1028
 
class PointlessMerge(BzrNewError):
1029
 
    """Nothing to merge."""
1030
 
 
1031
 
 
1032
 
class UninitializableFormat(BzrNewError):
1033
 
    """Format %(format)s cannot be initialised by this version of bzr."""
 
1138
class PointlessMerge(BzrError):
 
1139
 
 
1140
    _fmt = "Nothing to merge."
 
1141
 
 
1142
 
 
1143
class UninitializableFormat(BzrError):
 
1144
 
 
1145
    _fmt = "Format %(format)s cannot be initialised by this version of bzr."
1034
1146
 
1035
1147
    def __init__(self, format):
1036
 
        BzrNewError.__init__(self)
 
1148
        BzrError.__init__(self)
1037
1149
        self.format = format
1038
1150
 
1039
1151
 
1040
 
class BadConversionTarget(BzrNewError):
1041
 
    """Cannot convert to format %(format)s.  %(problem)s"""
 
1152
class BadConversionTarget(BzrError):
 
1153
 
 
1154
    _fmt = "Cannot convert to format %(format)s.  %(problem)s"
1042
1155
 
1043
1156
    def __init__(self, problem, format):
1044
 
        BzrNewError.__init__(self)
 
1157
        BzrError.__init__(self)
1045
1158
        self.problem = problem
1046
1159
        self.format = format
1047
1160
 
1048
1161
 
1049
 
class NoDiff(BzrNewError):
1050
 
    """Diff is not installed on this machine: %(msg)s"""
 
1162
class NoDiff(BzrError):
 
1163
 
 
1164
    _fmt = "Diff is not installed on this machine: %(msg)s"
1051
1165
 
1052
1166
    def __init__(self, msg):
1053
 
        BzrNewError.__init__(self, msg=msg)
1054
 
 
1055
 
 
1056
 
class NoDiff3(BzrNewError):
1057
 
    """Diff3 is not installed on this machine."""
1058
 
 
1059
 
 
1060
 
class ExistingLimbo(BzrNewError):
1061
 
    """This tree contains left-over files from a failed operation.
1062
 
    Please examine %(limbo_dir)s to see if it contains any files you wish to
1063
 
    keep, and delete it when you are done.
1064
 
    """
1065
 
    def __init__(self, limbo_dir):
1066
 
       BzrNewError.__init__(self)
1067
 
       self.limbo_dir = limbo_dir
1068
 
 
1069
 
 
1070
 
class ImmortalLimbo(BzrNewError):
1071
 
    """Unable to delete transform temporary directory $(limbo_dir)s.
1072
 
    Please examine %(limbo_dir)s to see if it contains any files you wish to
1073
 
    keep, and delete it when you are done.
1074
 
    """
1075
 
    def __init__(self, limbo_dir):
1076
 
       BzrNewError.__init__(self)
1077
 
       self.limbo_dir = limbo_dir
1078
 
 
1079
 
 
1080
 
class OutOfDateTree(BzrNewError):
1081
 
    """Working tree is out of date, please run 'bzr update'."""
 
1167
        BzrError.__init__(self, msg=msg)
 
1168
 
 
1169
 
 
1170
class NoDiff3(BzrError):
 
1171
 
 
1172
    _fmt = "Diff3 is not installed on this machine."
 
1173
 
 
1174
 
 
1175
class ExistingLimbo(BzrError):
 
1176
 
 
1177
    _fmt = """This tree contains left-over files from a failed operation.
 
1178
    Please examine %(limbo_dir)s to see if it contains any files you wish to
 
1179
    keep, and delete it when you are done."""
 
1180
    
 
1181
    def __init__(self, limbo_dir):
 
1182
       BzrError.__init__(self)
 
1183
       self.limbo_dir = limbo_dir
 
1184
 
 
1185
 
 
1186
class ImmortalLimbo(BzrError):
 
1187
 
 
1188
    _fmt = """Unable to delete transform temporary directory $(limbo_dir)s.
 
1189
    Please examine %(limbo_dir)s to see if it contains any files you wish to
 
1190
    keep, and delete it when you are done."""
 
1191
 
 
1192
    def __init__(self, limbo_dir):
 
1193
       BzrError.__init__(self)
 
1194
       self.limbo_dir = limbo_dir
 
1195
 
 
1196
 
 
1197
class OutOfDateTree(BzrError):
 
1198
 
 
1199
    _fmt = "Working tree is out of date, please run 'bzr update'."
1082
1200
 
1083
1201
    def __init__(self, tree):
1084
 
        BzrNewError.__init__(self)
 
1202
        BzrError.__init__(self)
1085
1203
        self.tree = tree
1086
1204
 
1087
1205
 
1088
 
class MergeModifiedFormatError(BzrNewError):
1089
 
    """Error in merge modified format"""
1090
 
 
1091
 
 
1092
 
class ConflictFormatError(BzrNewError):
1093
 
    """Format error in conflict listings"""
1094
 
 
1095
 
 
1096
 
class CorruptRepository(BzrNewError):
1097
 
    """An error has been detected in the repository %(repo_path)s.
 
1206
class MergeModifiedFormatError(BzrError):
 
1207
 
 
1208
    _fmt = "Error in merge modified format"
 
1209
 
 
1210
 
 
1211
class ConflictFormatError(BzrError):
 
1212
 
 
1213
    _fmt = "Format error in conflict listings"
 
1214
 
 
1215
 
 
1216
class CorruptRepository(BzrError):
 
1217
 
 
1218
    _fmt = """An error has been detected in the repository %(repo_path)s.
1098
1219
Please run bzr reconcile on this repository."""
1099
1220
 
1100
1221
    def __init__(self, repo):
1101
 
        BzrNewError.__init__(self)
 
1222
        BzrError.__init__(self)
1102
1223
        self.repo_path = repo.bzrdir.root_transport.base
1103
1224
 
1104
1225
 
1105
 
class UpgradeRequired(BzrNewError):
1106
 
    """To use this feature you must upgrade your branch at %(path)s."""
 
1226
class UpgradeRequired(BzrError):
 
1227
 
 
1228
    _fmt = "To use this feature you must upgrade your branch at %(path)s."
1107
1229
 
1108
1230
    def __init__(self, path):
1109
 
        BzrNewError.__init__(self)
 
1231
        BzrError.__init__(self)
1110
1232
        self.path = path
1111
1233
 
1112
1234
 
1113
 
class LocalRequiresBoundBranch(BzrNewError):
1114
 
    """Cannot perform local-only commits on unbound branches."""
1115
 
 
1116
 
 
1117
 
class MissingProgressBarFinish(BzrNewError):
1118
 
    """A nested progress bar was not 'finished' correctly."""
1119
 
 
1120
 
 
1121
 
class InvalidProgressBarType(BzrNewError):
1122
 
    """Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
 
1235
class LocalRequiresBoundBranch(BzrError):
 
1236
 
 
1237
    _fmt = "Cannot perform local-only commits on unbound branches."
 
1238
 
 
1239
 
 
1240
class MissingProgressBarFinish(BzrError):
 
1241
 
 
1242
    _fmt = "A nested progress bar was not 'finished' correctly."
 
1243
 
 
1244
 
 
1245
class InvalidProgressBarType(BzrError):
 
1246
 
 
1247
    _fmt = """Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
1123
1248
Select one of: %(valid_types)s"""
1124
1249
 
1125
1250
    def __init__(self, bar_type, valid_types):
1126
 
        BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
1127
 
 
1128
 
 
1129
 
class UnsupportedOperation(BzrNewError):
1130
 
    """The method %(mname)s is not supported on objects of type %(tname)s."""
 
1251
        BzrError.__init__(self, bar_type=bar_type, valid_types=valid_types)
 
1252
 
 
1253
 
 
1254
class UnsupportedOperation(BzrError):
 
1255
 
 
1256
    _fmt = "The method %(mname)s is not supported on objects of type %(tname)s."
1131
1257
    def __init__(self, method, method_self):
1132
1258
        self.method = method
1133
1259
        self.mname = method.__name__
1134
1260
        self.tname = type(method_self).__name__
1135
1261
 
1136
1262
 
1137
 
class BinaryFile(BzrNewError):
1138
 
    """File is binary but should be text."""
1139
 
 
1140
 
 
1141
 
class IllegalPath(BzrNewError):
1142
 
    """The path %(path)s is not permitted on this platform"""
 
1263
class BinaryFile(BzrError):
 
1264
    
 
1265
    _fmt = "File is binary but should be text."
 
1266
 
 
1267
 
 
1268
class IllegalPath(BzrError):
 
1269
 
 
1270
    _fmt = "The path %(path)s is not permitted on this platform"
1143
1271
 
1144
1272
    def __init__(self, path):
1145
 
        BzrNewError.__init__(self)
 
1273
        BzrError.__init__(self)
1146
1274
        self.path = path
1147
1275
 
1148
1276
 
1149
 
class TestamentMismatch(BzrNewError):
1150
 
    """Testament did not match expected value.  
 
1277
class TestamentMismatch(BzrError):
 
1278
 
 
1279
    _fmt = """Testament did not match expected value.  
1151
1280
       For revision_id {%(revision_id)s}, expected {%(expected)s}, measured 
1152
 
       {%(measured)s}
1153
 
    """
 
1281
       {%(measured)s}"""
 
1282
 
1154
1283
    def __init__(self, revision_id, expected, measured):
1155
1284
        self.revision_id = revision_id
1156
1285
        self.expected = expected
1157
1286
        self.measured = measured
1158
1287
 
1159
1288
 
1160
 
class NotABundle(BzrNewError):
1161
 
    """Not a bzr revision-bundle: %(text)r"""
 
1289
class NotABundle(BzrError):
 
1290
    
 
1291
    _fmt = "Not a bzr revision-bundle: %(text)r"
1162
1292
 
1163
1293
    def __init__(self, text):
1164
 
        BzrNewError.__init__(self)
 
1294
        BzrError.__init__(self)
1165
1295
        self.text = text
1166
1296
 
1167
1297
 
1168
 
class BadBundle(BzrNewError): 
1169
 
    """Bad bzr revision-bundle: %(text)r"""
 
1298
class BadBundle(BzrError): 
 
1299
    
 
1300
    _fmt = "Bad bzr revision-bundle: %(text)r"
1170
1301
 
1171
1302
    def __init__(self, text):
1172
 
        BzrNewError.__init__(self)
 
1303
        BzrError.__init__(self)
1173
1304
        self.text = text
1174
1305
 
1175
1306
 
1176
1307
class MalformedHeader(BadBundle): 
1177
 
    """Malformed bzr revision-bundle header: %(text)r"""
1178
 
 
1179
 
    def __init__(self, text):
1180
 
        BzrNewError.__init__(self)
1181
 
        self.text = text
 
1308
    
 
1309
    _fmt = "Malformed bzr revision-bundle header: %(text)r"
1182
1310
 
1183
1311
 
1184
1312
class MalformedPatches(BadBundle): 
1185
 
    """Malformed patches in bzr revision-bundle: %(text)r"""
1186
 
 
1187
 
    def __init__(self, text):
1188
 
        BzrNewError.__init__(self)
1189
 
        self.text = text
 
1313
    
 
1314
    _fmt = "Malformed patches in bzr revision-bundle: %(text)r"
1190
1315
 
1191
1316
 
1192
1317
class MalformedFooter(BadBundle): 
1193
 
    """Malformed footer in bzr revision-bundle: %(text)r"""
1194
 
 
1195
 
    def __init__(self, text):
1196
 
        BzrNewError.__init__(self)
1197
 
        self.text = text
 
1318
    
 
1319
    _fmt = "Malformed footer in bzr revision-bundle: %(text)r"
1198
1320
 
1199
1321
 
1200
1322
class UnsupportedEOLMarker(BadBundle):
1201
 
    """End of line marker was not \\n in bzr revision-bundle"""    
 
1323
    
 
1324
    _fmt = "End of line marker was not \\n in bzr revision-bundle"    
1202
1325
 
1203
1326
    def __init__(self):
1204
 
        BzrNewError.__init__(self)
1205
 
 
1206
 
 
1207
 
class IncompatibleFormat(BzrNewError):
1208
 
    """Bundle format %(bundle_format)s is incompatible with %(other)s"""
 
1327
        # XXX: BadBundle's constructor assumes there's explanatory text, 
 
1328
        # but for this there is not
 
1329
        BzrError.__init__(self)
 
1330
 
 
1331
 
 
1332
class IncompatibleBundleFormat(BzrError):
 
1333
    
 
1334
    _fmt = "Bundle format %(bundle_format)s is incompatible with %(other)s"
1209
1335
 
1210
1336
    def __init__(self, bundle_format, other):
1211
 
        BzrNewError.__init__(self)
 
1337
        BzrError.__init__(self)
1212
1338
        self.bundle_format = bundle_format
1213
1339
        self.other = other
1214
1340
 
1215
1341
 
1216
 
class BadInventoryFormat(BzrNewError):
1217
 
    """Root class for inventory serialization errors"""
 
1342
class BadInventoryFormat(BzrError):
 
1343
    
 
1344
    _fmt = "Root class for inventory serialization errors"
1218
1345
 
1219
1346
 
1220
1347
class UnexpectedInventoryFormat(BadInventoryFormat):
1221
 
    """The inventory was not in the expected format:\n %(msg)s"""
 
1348
 
 
1349
    _fmt = "The inventory was not in the expected format:\n %(msg)s"
1222
1350
 
1223
1351
    def __init__(self, msg):
1224
1352
        BadInventoryFormat.__init__(self, msg=msg)
1225
1353
 
1226
1354
 
1227
1355
class NoSmartServer(NotBranchError):
1228
 
    """No smart server available at %(url)s"""
 
1356
 
 
1357
    _fmt = "No smart server available at %(url)s"
1229
1358
 
1230
1359
    def __init__(self, url):
1231
1360
        self.url = url
1232
1361
 
1233
1362
 
1234
 
class UnknownSSH(BzrNewError):
1235
 
    """Unrecognised value for BZR_SSH environment variable: %(vendor)s"""
 
1363
class UnknownSSH(BzrError):
 
1364
 
 
1365
    _fmt = "Unrecognised value for BZR_SSH environment variable: %(vendor)s"
1236
1366
 
1237
1367
    def __init__(self, vendor):
1238
 
        BzrNewError.__init__(self)
 
1368
        BzrError.__init__(self)
1239
1369
        self.vendor = vendor
1240
1370
 
1241
1371
 
1242
 
class GhostRevisionUnusableHere(BzrNewError):
1243
 
    """Ghost revision {%(revision_id)s} cannot be used here."""
 
1372
class GhostRevisionUnusableHere(BzrError):
 
1373
 
 
1374
    _fmt = "Ghost revision {%(revision_id)s} cannot be used here."
1244
1375
 
1245
1376
    def __init__(self, revision_id):
1246
 
        BzrNewError.__init__(self)
 
1377
        BzrError.__init__(self)
1247
1378
        self.revision_id = revision_id
1248
1379
 
1249
1380
 
1250
 
class IllegalUseOfScopeReplacer(BzrNewError):
1251
 
    """ScopeReplacer object %(name)r was used incorrectly: %(msg)s%(extra)s"""
 
1381
class IllegalUseOfScopeReplacer(BzrError):
 
1382
 
 
1383
    _fmt = "ScopeReplacer object %(name)r was used incorrectly: %(msg)s%(extra)s"
1252
1384
 
1253
1385
    is_user_error = False
1254
1386
 
1255
1387
    def __init__(self, name, msg, extra=None):
1256
 
        BzrNewError.__init__(self)
 
1388
        BzrError.__init__(self)
1257
1389
        self.name = name
1258
1390
        self.msg = msg
1259
1391
        if extra:
1262
1394
            self.extra = ''
1263
1395
 
1264
1396
 
1265
 
class InvalidImportLine(BzrNewError):
1266
 
    """Not a valid import statement: %(msg)\n%(text)s"""
 
1397
class InvalidImportLine(BzrError):
 
1398
 
 
1399
    _fmt = "Not a valid import statement: %(msg)\n%(text)s"
1267
1400
 
1268
1401
    is_user_error = False
1269
1402
 
1270
1403
    def __init__(self, text, msg):
1271
 
        BzrNewError.__init__(self)
 
1404
        BzrError.__init__(self)
1272
1405
        self.text = text
1273
1406
        self.msg = msg
1274
1407
 
1275
1408
 
1276
 
class ImportNameCollision(BzrNewError):
1277
 
    """Tried to import an object to the same name as an existing object. %(name)s"""
 
1409
class ImportNameCollision(BzrError):
 
1410
 
 
1411
    _fmt = "Tried to import an object to the same name as an existing object. %(name)s"
1278
1412
 
1279
1413
    is_user_error = False
1280
1414
 
1281
1415
    def __init__(self, name):
1282
 
        BzrNewError.__init__(self)
 
1416
        BzrError.__init__(self)
1283
1417
        self.name = name