|
1
|
|
|
"""Shared utility functions.""" |
|
2
|
|
|
|
|
3
|
5 |
|
import sys |
|
4
|
5 |
|
from traceback import format_exception, format_exception_only |
|
5
|
|
|
|
|
6
|
|
|
|
|
7
|
5 |
|
def format_exc_skip(skip, limit=None): |
|
8
|
|
|
"""Like traceback.format_exc but allow skipping the first frames.""" |
|
9
|
5 |
|
type, val, tb = sys.exc_info() |
|
|
|
|
|
|
10
|
5 |
|
for i in range(skip): |
|
|
|
|
|
|
11
|
5 |
|
tb = tb.tb_next |
|
12
|
5 |
|
return ('\n'.join(format_exception(type, val, tb, limit))).rstrip() |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
|
|
def format_exc_msg(skip=1, limit=None): |
|
|
|
|
|
|
16
|
5 |
|
"""Format ``exc`` to be used in error messages. |
|
17
|
|
|
|
|
18
|
|
|
It duplicates the exception itself on the first line, since v:exception |
|
19
|
|
|
will only contain this. |
|
20
|
5 |
|
|
|
21
|
|
|
`repr()` is used for SyntaxErrors, because it will contain more information |
|
22
|
5 |
|
that cannot be easily displayed on a single line: |
|
23
|
|
|
|
|
24
|
5 |
|
SyntaxError('unexpected EOF while parsing', |
|
25
|
|
|
('<string>', 1, 12, 'syntaxerror('))) |
|
26
|
|
|
|
|
27
|
|
|
For all other exceptions `traceback.format_exception_only` is used, |
|
28
|
|
|
which is the same as the last line then (via with `format_exception` in |
|
29
|
|
|
`format_exc_skip`). |
|
30
|
5 |
|
""" |
|
31
|
|
|
etype, value, _ = sys.exc_info() |
|
32
|
|
|
if issubclass(etype, SyntaxError): |
|
33
|
|
|
exc_msg = repr(value) |
|
34
|
|
|
else: |
|
35
|
|
|
exc_msg = format_exception_only(etype, value)[-1].rstrip('\n') |
|
36
|
|
|
return "{!s}\n{}\n\n".format(exc_msg, format_exc_skip(skip)) |
|
37
|
|
|
|
|
38
|
|
|
|
|
39
|
|
|
# Taken from SimpleNamespace in python 3 |
|
40
|
|
|
class Version: |
|
41
|
|
|
|
|
42
|
|
|
"""Helper class for version info.""" |
|
43
|
|
|
|
|
44
|
|
|
def __init__(self, **kwargs): |
|
45
|
|
|
"""Create the Version object.""" |
|
46
|
|
|
self.__dict__.update(kwargs) |
|
47
|
|
|
|
|
48
|
|
|
def __repr__(self): |
|
49
|
|
|
"""Return str representation of the Version.""" |
|
50
|
|
|
keys = sorted(self.__dict__) |
|
51
|
|
|
items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys) |
|
52
|
|
|
return "{}({})".format(type(self).__name__, ", ".join(items)) |
|
53
|
|
|
|
|
54
|
|
|
def __eq__(self, other): |
|
55
|
|
|
"""Check if version is same as other.""" |
|
56
|
|
|
return self.__dict__ == other.__dict__ |
|
57
|
|
|
|
It is generally discouraged to redefine built-ins as this makes code very hard to read.