1
1
from __future__ import print_function
2
+
2
3
import inspect
3
4
import re
4
5
import sys
5
6
7
+ from distutils .sysconfig import get_python_lib
8
+ from os .path import abspath , join
9
+ from termcolor import colored
10
+ from traceback import extract_tb , format_list , format_exception_only , format_exception
11
+
12
+
6
13
class flushfile ():
7
14
"""
8
15
Disable buffering for standard output and standard error.
9
16
10
17
http://stackoverflow.com/a/231216
11
18
"""
19
+
12
20
def __init__ (self , f ):
13
21
self .f = f
14
22
@@ -18,9 +26,12 @@ def __getattr__(self, name):
18
26
def write (self , x ):
19
27
self .f .write (x )
20
28
self .f .flush ()
29
+
30
+
21
31
sys .stderr = flushfile (sys .stderr )
22
32
sys .stdout = flushfile (sys .stdout )
23
33
34
+
24
35
def eprint (* args , ** kwargs ):
25
36
"""
26
37
Print an error message to standard error, prefixing it with
@@ -32,6 +43,32 @@ def eprint(*args, **kwargs):
32
43
print ("{}:{}: " .format (filename , lineno ), end = "" )
33
44
print (* args , end = end , file = sys .stderr , sep = sep )
34
45
46
+
47
+ def formatException (type , value , tb ):
48
+ """
49
+ Format traceback, darkening entries from global site-packages directories
50
+ and user-specific site-packages directory.
51
+
52
+ https://stackoverflow.com/a/46071447/5156190
53
+ """
54
+
55
+ # Absolute paths to site-packages
56
+ packages = tuple (join (abspath (p ), "" ) for p in sys .path [1 :])
57
+
58
+ # Darken lines referring to files in site-packages
59
+ lines = []
60
+ for line in format_exception (type , value , tb ):
61
+ matches = re .search (r"^ File \"([^\"]+)\", line \d+, in .+" , line )
62
+ if matches and matches .group (1 ).startswith (packages ):
63
+ lines += colored (line , attrs = ["dark" ])
64
+ else :
65
+ lines += line
66
+ return "" .join (lines ).rstrip ()
67
+
68
+
69
+ sys .excepthook = lambda type , value , tb : print (formatException (type , value , tb ), file = sys .stderr )
70
+
71
+
35
72
def get_char (prompt = None ):
36
73
"""
37
74
Read a line of text from standard input and return the equivalent char;
@@ -49,6 +86,7 @@ def get_char(prompt=None):
49
86
if prompt is None :
50
87
print ("Retry: " , end = "" )
51
88
89
+
52
90
def get_float (prompt = None ):
53
91
"""
54
92
Read a line of text from standard input and return the equivalent float
@@ -69,20 +107,21 @@ def get_float(prompt=None):
69
107
if prompt is None :
70
108
print ("Retry: " , end = "" )
71
109
110
+
72
111
def get_int (prompt = None ):
73
112
"""
74
113
Read a line of text from standard input and return the equivalent int;
75
114
if text does not represent an int, user is prompted to retry. If line
76
115
can't be read, return None.
77
116
"""
78
117
while True :
79
- s = get_string (prompt );
118
+ s = get_string (prompt )
80
119
if s is None :
81
120
return None
82
121
if re .search (r"^[+-]?\d+$" , s ):
83
122
try :
84
123
i = int (s , 10 )
85
- if type (i ) is int : # could become long in Python 2
124
+ if type (i ) is int : # could become long in Python 2
86
125
return i
87
126
except ValueError :
88
127
pass
@@ -91,6 +130,7 @@ def get_int(prompt=None):
91
130
if prompt is None :
92
131
print ("Retry: " , end = "" )
93
132
133
+
94
134
if sys .version_info .major != 3 :
95
135
def get_long (prompt = None ):
96
136
"""
@@ -112,6 +152,7 @@ def get_long(prompt=None):
112
152
if prompt is None :
113
153
print ("Retry: " , end = "" )
114
154
155
+
115
156
def get_string (prompt = None ):
116
157
"""
117
158
Read a line of text from standard input and return it as a string,
0 commit comments