|
10 | 10 | END = '\033[0m' |
11 | 11 |
|
12 | 12 |
|
| 13 | +class ColorModes(object): |
| 14 | + AUTO = 'auto' |
| 15 | + ALWAYS = 'always' |
| 16 | + NEVER = 'never' |
| 17 | + |
| 18 | +color_mode = 'auto' |
| 19 | + |
| 20 | + |
13 | 21 | def colorize(level, message): |
14 | 22 | # if not in a tty, we're likely redirected or piped |
15 | | - if not sys.stdout.isatty(): |
| 23 | + if color_mode == ColorModes.NEVER or (color_mode == ColorModes.AUTO and not sys.stdout.isatty()): |
16 | 24 | return message |
17 | 25 |
|
18 | 26 | # color mappings |
@@ -60,4 +68,27 @@ def format(self, record): |
60 | 68 | record.isodate = date.isoformat() |
61 | 69 | record.message = record.msg % record.args |
62 | 70 | record.coloredlevel = colorize(record.levelname, record.levelname) |
63 | | - return "%(isodate)s %(coloredlevel)s [process=%(processName)s, pid=%(process)s]: %(message)s" % record.__dict__ |
| 71 | + s = "%(isodate)s %(coloredlevel)s [process=%(processName)s, pid=%(process)s]: %(message)s" % record.__dict__ |
| 72 | + |
| 73 | + # C&P from logging.Formatter#format |
| 74 | + if record.exc_info: |
| 75 | + # Cache the traceback text to avoid converting it multiple times |
| 76 | + # (it's constant anyway) |
| 77 | + if not record.exc_text: |
| 78 | + record.exc_text = self.formatException(record.exc_info) |
| 79 | + if record.exc_text: |
| 80 | + if s[-1:] != "\n": |
| 81 | + s = s + "\n" |
| 82 | + try: |
| 83 | + s = s + record.exc_text |
| 84 | + except UnicodeError: |
| 85 | + # Sometimes filenames have non-ASCII chars, which can lead |
| 86 | + # to errors when s is Unicode and record.exc_text is str |
| 87 | + # See issue 8924. |
| 88 | + # We also use replace for when there are multiple |
| 89 | + # encodings, e.g. UTF-8 for the filesystem and latin-1 |
| 90 | + # for a script. See issue 13232. |
| 91 | + s = s + record.exc_text.decode(sys.getfilesystemencoding(), |
| 92 | + 'replace') |
| 93 | + |
| 94 | + return s |
0 commit comments