107 |
113 |
108 class CommandError(Exception): |
114 class CommandError(Exception): |
109 """Exception raised on errors in parsing the command line.""" |
115 """Exception raised on errors in parsing the command line.""" |
110 |
116 |
111 def __init__(self, command, message): |
117 def __init__(self, command, message): |
|
118 # type: (bytes, bytes) -> None |
112 self.command = command |
119 self.command = command |
113 self.message = message |
120 self.message = message |
114 super(CommandError, self).__init__() |
121 super(CommandError, self).__init__() |
115 |
122 |
116 __bytes__ = _tobytes |
123 __bytes__ = _tobytes |
118 |
125 |
119 class UnknownCommand(Exception): |
126 class UnknownCommand(Exception): |
120 """Exception raised if command is not in the command table.""" |
127 """Exception raised if command is not in the command table.""" |
121 |
128 |
122 def __init__(self, command, all_commands=None): |
129 def __init__(self, command, all_commands=None): |
|
130 # type: (bytes, Optional[List[bytes]]) -> None |
123 self.command = command |
131 self.command = command |
124 self.all_commands = all_commands |
132 self.all_commands = all_commands |
125 super(UnknownCommand, self).__init__() |
133 super(UnknownCommand, self).__init__() |
126 |
134 |
127 __bytes__ = _tobytes |
135 __bytes__ = _tobytes |
129 |
137 |
130 class AmbiguousCommand(Exception): |
138 class AmbiguousCommand(Exception): |
131 """Exception raised if command shortcut matches more than one command.""" |
139 """Exception raised if command shortcut matches more than one command.""" |
132 |
140 |
133 def __init__(self, prefix, matches): |
141 def __init__(self, prefix, matches): |
|
142 # type: (bytes, List[bytes]) -> None |
134 self.prefix = prefix |
143 self.prefix = prefix |
135 self.matches = matches |
144 self.matches = matches |
136 super(AmbiguousCommand, self).__init__() |
145 super(AmbiguousCommand, self).__init__() |
137 |
146 |
138 __bytes__ = _tobytes |
147 __bytes__ = _tobytes |
140 |
149 |
141 class WorkerError(Exception): |
150 class WorkerError(Exception): |
142 """Exception raised when a worker process dies.""" |
151 """Exception raised when a worker process dies.""" |
143 |
152 |
144 def __init__(self, status_code): |
153 def __init__(self, status_code): |
|
154 # type: (int) -> None |
145 self.status_code = status_code |
155 self.status_code = status_code |
146 # Pass status code to superclass just so it becomes part of __bytes__ |
156 # Pass status code to superclass just so it becomes part of __bytes__ |
147 super(WorkerError, self).__init__(status_code) |
157 super(WorkerError, self).__init__(status_code) |
148 |
158 |
149 __bytes__ = _tobytes |
159 __bytes__ = _tobytes |
157 |
167 |
158 class ConflictResolutionRequired(InterventionRequired): |
168 class ConflictResolutionRequired(InterventionRequired): |
159 """Exception raised when a continuable command required merge conflict resolution.""" |
169 """Exception raised when a continuable command required merge conflict resolution.""" |
160 |
170 |
161 def __init__(self, opname): |
171 def __init__(self, opname): |
|
172 # type: (bytes) -> None |
162 from .i18n import _ |
173 from .i18n import _ |
163 |
174 |
164 self.opname = opname |
175 self.opname = opname |
165 InterventionRequired.__init__( |
176 InterventionRequired.__init__( |
166 self, |
177 self, |
192 # but do not replace it with encoding.strfromlocal(), which |
203 # but do not replace it with encoding.strfromlocal(), which |
193 # may raise another exception. |
204 # may raise another exception. |
194 return pycompat.sysstr(self.__bytes__()) |
205 return pycompat.sysstr(self.__bytes__()) |
195 |
206 |
196 def format(self): |
207 def format(self): |
|
208 # type: () -> bytes |
197 from .i18n import _ |
209 from .i18n import _ |
198 |
210 |
199 message = _(b"abort: %s\n") % self.message |
211 message = _(b"abort: %s\n") % self.message |
200 if self.hint: |
212 if self.hint: |
201 message += _(b"(%s)\n") % self.hint |
213 message += _(b"(%s)\n") % self.hint |
245 |
257 |
246 class ConfigError(Abort): |
258 class ConfigError(Abort): |
247 """Exception raised when parsing config files""" |
259 """Exception raised when parsing config files""" |
248 |
260 |
249 def __init__(self, message, location=None, hint=None): |
261 def __init__(self, message, location=None, hint=None): |
|
262 # type: (bytes, Optional[bytes], Optional[bytes]) -> None |
250 super(ConfigError, self).__init__(message, hint=hint) |
263 super(ConfigError, self).__init__(message, hint=hint) |
251 self.location = location |
264 self.location = location |
252 |
265 |
253 def format(self): |
266 def format(self): |
|
267 # type: () -> bytes |
254 from .i18n import _ |
268 from .i18n import _ |
255 |
269 |
256 if self.location is not None: |
270 if self.location is not None: |
257 message = _(b"config error at %s: %s\n") % ( |
271 message = _(b"config error at %s: %s\n") % ( |
258 pycompat.bytestr(self.location), |
272 pycompat.bytestr(self.location), |
298 |
312 |
299 class ParseError(Abort): |
313 class ParseError(Abort): |
300 """Raised when parsing config files and {rev,file}sets (msg[, pos])""" |
314 """Raised when parsing config files and {rev,file}sets (msg[, pos])""" |
301 |
315 |
302 def __init__(self, message, location=None, hint=None): |
316 def __init__(self, message, location=None, hint=None): |
|
317 # type: (bytes, Optional[Union[bytes, int]], Optional[bytes]) -> None |
303 super(ParseError, self).__init__(message, hint=hint) |
318 super(ParseError, self).__init__(message, hint=hint) |
304 self.location = location |
319 self.location = location |
305 |
320 |
306 def format(self): |
321 def format(self): |
|
322 # type: () -> bytes |
307 from .i18n import _ |
323 from .i18n import _ |
308 |
324 |
309 if self.location is not None: |
325 if self.location is not None: |
310 message = _(b"hg: parse error at %s: %s\n") % ( |
326 message = _(b"hg: parse error at %s: %s\n") % ( |
311 pycompat.bytestr(self.location), |
327 pycompat.bytestr(self.location), |
321 class PatchError(Exception): |
337 class PatchError(Exception): |
322 __bytes__ = _tobytes |
338 __bytes__ = _tobytes |
323 |
339 |
324 |
340 |
325 def getsimilar(symbols, value): |
341 def getsimilar(symbols, value): |
|
342 # type: (Iterable[bytes], bytes) -> List[bytes] |
326 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio() |
343 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio() |
327 # The cutoff for similarity here is pretty arbitrary. It should |
344 # The cutoff for similarity here is pretty arbitrary. It should |
328 # probably be investigated and tweaked. |
345 # probably be investigated and tweaked. |
329 return [s for s in symbols if sim(s) > 0.6] |
346 return [s for s in symbols if sim(s) > 0.6] |
330 |
347 |
331 |
348 |
332 def similarity_hint(similar): |
349 def similarity_hint(similar): |
|
350 # type: (List[bytes]) -> Optional[bytes] |
333 from .i18n import _ |
351 from .i18n import _ |
334 |
352 |
335 if len(similar) == 1: |
353 if len(similar) == 1: |
336 return _(b"did you mean %s?") % similar[0] |
354 return _(b"did you mean %s?") % similar[0] |
337 elif similar: |
355 elif similar: |
343 |
361 |
344 class UnknownIdentifier(ParseError): |
362 class UnknownIdentifier(ParseError): |
345 """Exception raised when a {rev,file}set references an unknown identifier""" |
363 """Exception raised when a {rev,file}set references an unknown identifier""" |
346 |
364 |
347 def __init__(self, function, symbols): |
365 def __init__(self, function, symbols): |
|
366 # type: (bytes, Iterable[bytes]) -> None |
348 from .i18n import _ |
367 from .i18n import _ |
349 |
368 |
350 similar = getsimilar(symbols, function) |
369 similar = getsimilar(symbols, function) |
351 hint = similarity_hint(similar) |
370 hint = similarity_hint(similar) |
352 |
371 |
377 |
396 |
378 class StdioError(IOError): |
397 class StdioError(IOError): |
379 """Raised if I/O to stdout or stderr fails""" |
398 """Raised if I/O to stdout or stderr fails""" |
380 |
399 |
381 def __init__(self, err): |
400 def __init__(self, err): |
|
401 # type: (IOError) -> None |
382 IOError.__init__(self, err.errno, err.strerror) |
402 IOError.__init__(self, err.errno, err.strerror) |
383 |
403 |
384 # no __bytes__() because error message is derived from the standard IOError |
404 # no __bytes__() because error message is derived from the standard IOError |
385 |
405 |
386 |
406 |
387 class UnsupportedMergeRecords(Abort): |
407 class UnsupportedMergeRecords(Abort): |
388 def __init__(self, recordtypes): |
408 def __init__(self, recordtypes): |
|
409 # type: (Iterable[bytes]) -> None |
389 from .i18n import _ |
410 from .i18n import _ |
390 |
411 |
391 self.recordtypes = sorted(recordtypes) |
412 self.recordtypes = sorted(recordtypes) |
392 s = b' '.join(self.recordtypes) |
413 s = b' '.join(self.recordtypes) |
393 Abort.__init__( |
414 Abort.__init__( |
402 |
423 |
403 class UnknownVersion(Abort): |
424 class UnknownVersion(Abort): |
404 """generic exception for aborting from an encounter with an unknown version""" |
425 """generic exception for aborting from an encounter with an unknown version""" |
405 |
426 |
406 def __init__(self, msg, hint=None, version=None): |
427 def __init__(self, msg, hint=None, version=None): |
|
428 # type: (bytes, Optional[bytes], Optional[bytes]) -> None |
407 self.version = version |
429 self.version = version |
408 super(UnknownVersion, self).__init__(msg, hint=hint) |
430 super(UnknownVersion, self).__init__(msg, hint=hint) |
409 |
431 |
410 |
432 |
411 class LockError(IOError): |
433 class LockError(IOError): |
412 def __init__(self, errno, strerror, filename, desc): |
434 def __init__(self, errno, strerror, filename, desc): |
|
435 # TODO: figure out if this should be bytes or str |
|
436 # _type: (int, str, str, bytes) -> None |
413 IOError.__init__(self, errno, strerror, filename) |
437 IOError.__init__(self, errno, strerror, filename) |
414 self.desc = desc |
438 self.desc = desc |
415 |
439 |
416 # no __bytes__() because error message is derived from the standard IOError |
440 # no __bytes__() because error message is derived from the standard IOError |
417 |
441 |
454 |
478 |
455 class ProgrammingError(Hint, RuntimeError): |
479 class ProgrammingError(Hint, RuntimeError): |
456 """Raised if a mercurial (core or extension) developer made a mistake""" |
480 """Raised if a mercurial (core or extension) developer made a mistake""" |
457 |
481 |
458 def __init__(self, msg, *args, **kwargs): |
482 def __init__(self, msg, *args, **kwargs): |
|
483 # type: (AnyStr, Any, Any) -> None |
459 # On Python 3, turn the message back into a string since this is |
484 # On Python 3, turn the message back into a string since this is |
460 # an internal-only error that won't be printed except in a |
485 # an internal-only error that won't be printed except in a |
461 # stack traces. |
486 # stack traces. |
462 msg = pycompat.sysstr(msg) |
487 msg = pycompat.sysstr(msg) |
463 super(ProgrammingError, self).__init__(msg, *args, **kwargs) |
488 super(ProgrammingError, self).__init__(msg, *args, **kwargs) |
497 entries.append(val) |
522 entries.append(val) |
498 else: |
523 else: |
499 entries.append(b"%s=%r" % (par, pycompat.maybebytestr(val))) |
524 entries.append(b"%s=%r" % (par, pycompat.maybebytestr(val))) |
500 if entries: |
525 if entries: |
501 msg = b'%s - %s' % (msg, b', '.join(entries)) |
526 msg = b'%s - %s' % (msg, b', '.join(entries)) |
502 ValueError.__init__(self, msg) |
527 ValueError.__init__(self, msg) # TODO: convert to str? |
503 |
528 |
504 |
529 |
505 class ReadOnlyPartError(RuntimeError): |
530 class ReadOnlyPartError(RuntimeError): |
506 """error raised when code tries to alter a part being generated""" |
531 """error raised when code tries to alter a part being generated""" |
507 |
532 |
531 |
556 |
532 Also contains the tombstone data substituted for the uncensored data. |
557 Also contains the tombstone data substituted for the uncensored data. |
533 """ |
558 """ |
534 |
559 |
535 def __init__(self, filename, node, tombstone): |
560 def __init__(self, filename, node, tombstone): |
|
561 # type: (bytes, bytes, bytes) -> None |
536 from .node import short |
562 from .node import short |
537 |
563 |
538 StorageError.__init__(self, b'%s:%s' % (filename, short(node))) |
564 StorageError.__init__(self, b'%s:%s' % (filename, short(node))) |
539 self.tombstone = tombstone |
565 self.tombstone = tombstone |
540 |
566 |
586 |
612 |
587 The error is a formatter string and an optional iterable of arguments. |
613 The error is a formatter string and an optional iterable of arguments. |
588 """ |
614 """ |
589 |
615 |
590 def __init__(self, message, args=None): |
616 def __init__(self, message, args=None): |
|
617 # type: (bytes, Optional[Sequence[bytes]]) -> None |
591 self.message = message |
618 self.message = message |
592 self.messageargs = args |
619 self.messageargs = args |