| 143 | return r |
| 144 | |
| 145 | def format(self, record): |
| 146 | msg = super().format(record) |
| 147 | color = self.colors.get(record.levelname) |
| 148 | |
| 149 | # reset exception info later for other handlers... |
| 150 | einfo = sys.exc_info() if record.exc_info == 1 else record.exc_info |
| 151 | |
| 152 | if color and self.use_color: |
| 153 | try: |
| 154 | # safe_str will repr the color object |
| 155 | # and color will break on non-string objects |
| 156 | # so need to reorder calls based on type. |
| 157 | # Issue #427 |
| 158 | try: |
| 159 | if isinstance(msg, str): |
| 160 | return str(color(safe_str(msg))) |
| 161 | return safe_str(color(msg)) |
| 162 | except UnicodeDecodeError: # pragma: no cover |
| 163 | return safe_str(msg) # skip colors |
| 164 | except Exception as exc: # pylint: disable=broad-except |
| 165 | prev_msg, record.exc_info, record.msg = ( |
| 166 | record.msg, 1, '<Unrepresentable {!r}: {!r}>'.format( |
| 167 | type(msg), exc |
| 168 | ), |
| 169 | ) |
| 170 | try: |
| 171 | return super().format(record) |
| 172 | finally: |
| 173 | record.msg, record.exc_info = prev_msg, einfo |
| 174 | else: |
| 175 | return safe_str(msg) |
| 176 | |
| 177 | |
| 178 | class LoggingProxy: |