def setError(self, err_type=None, err_value=None, err_traceback=None): """Translates the given error object into an HTML string and places it in the message panel :param error: an error object (typically an exception object) :type error: object""" msgbox = self._msgbox error = "".join(traceback.format_exception_only(err_type, err_value)) msgbox.setText(error) msg = "<html><body><pre>%s</pre></body></html>" % error msgbox.setDetailedHtml(msg) html_orig = '<html><head><style type="text/css">{style}</style>' \ '</head><body>' exc_info = "".join( traceback.format_exception(err_type, err_value, err_traceback)) style = "" if pygments is not None: formatter = HtmlFormatter() style = formatter.get_style_defs() html = html_orig.format(style=style) if pygments is None: html += "<pre>%s</pre>" % exc_info else: formatter = HtmlFormatter() html += highlight(exc_info, PythonTracebackLexer(), formatter) html += "</body></html>" msgbox.setOriginHtml(html)
def color_exception(text: str) -> str: text = rex_exception.sub(r'\1', text) return pygments.highlight( code=text, lexer=PythonTracebackLexer(), formatter=TerminalFormatter(), )
def __init__(self, prompt='>>> ', continuation='... ', parent=None): QTextEdit.__init__(self, parent) self.shutting_down = False self.compiler = CommandCompiler() self.buf = self.old_buf = [] self.history = History([''], dynamic.get('console_history', [])) self.prompt_frame = None self.allow_output = False self.prompt_frame_format = QTextFrameFormat() self.prompt_frame_format.setBorder(1) self.prompt_frame_format.setBorderStyle(QTextFrameFormat.BorderStyle_Solid) self.prompt_len = len(prompt) self.doc.setMaximumBlockCount(int(prefs['scrollback'])) self.lexer = PythonLexer(ensurenl=False) self.tb_lexer = PythonTracebackLexer() self.context_menu = cm = QMenu(self) # {{{ cm.theme = ThemeMenu(cm) # }}} self.formatter = Formatter(prompt, continuation, style=prefs['theme']) p = QPalette() p.setColor(p.Base, QColor(self.formatter.background_color)) p.setColor(p.Text, QColor(self.formatter.color)) self.setPalette(p) self.key_dispatcher = { # {{{ Qt.Key_Enter : self.enter_pressed, Qt.Key_Return : self.enter_pressed, Qt.Key_Up : self.up_pressed, Qt.Key_Down : self.down_pressed, Qt.Key_Home : self.home_pressed, Qt.Key_End : self.end_pressed, Qt.Key_Left : self.left_pressed, Qt.Key_Right : self.right_pressed, Qt.Key_Backspace : self.backspace_pressed, Qt.Key_Delete : self.delete_pressed, } # }}} motd = textwrap.dedent('''\ # Python {0} # {1} {2} '''.format(sys.version.splitlines()[0], __appname__, __version__)) sys.excepthook = self.unhandled_exception self.controllers = [] QTimer.singleShot(0, self.launch_controller) with EditBlock(self.cursor): self.render_block(motd)
def jupyter(info, include="friendly_tb"): """Jupyter formatter using pygments and html format.""" _ = current_lang.translate css = HtmlFormatter().get_style_defs(".highlight") display(HTML(f"<style>{css}</style>")) items_to_show = select_items(include) result = False for item in items_to_show: if item in info: result = True if "source" in item or "variable" in item: text = info[item] text = highlight(text, PythonLexer(), HtmlFormatter()) display(HTML(text)) elif "traceback" in item: text = info[item] text = highlight(text, PythonTracebackLexer(), HtmlFormatter()) display(HTML(text)) elif item == "message": # format like last line of traceback content = info[item].split(":") error_name = content[0] if len(content) > 1: message = ":".join(content[1:]) else: message = "" text = "".join([ '<div class="highlight"><pre><span class="gr">', error_name, '</span>: <span class="n">', message, "</span></pre></div>", ]) display(HTML(text)) elif item == "suggest": text = html_escape(info[item]) display(HTML(f"<p><i>{text}<i><p>")) else: text = html_escape(info[item]) if "header" in item: display(HTML(f"<p><b>{text}</b></p>")) else: display(HTML(f'<p style="width: 70ch">{text}</p>')) if not result: text = "" if include == "why": text = _("I do not know.") elif include == "hint": if info["cause"]: text = _("I have no suggestion to offer; try `why()`.") else: text = _("I have no suggestion to offer.") if not text: return "" display(HTML(f'<p style="width: 70ch;">{text}</p>')) return ""
def print_exc(exc_str): try: from pygments import highlight from pygments.lexers import PythonTracebackLexer from pygments.formatters import TerminalFormatter exc_str = highlight(exc_str, PythonTracebackLexer(), TerminalFormatter()) except ImportError: pass print(exc_str, file=sys.stderr)
def print_exc(exc): exc_str = ''.join(exc) try: from pygments import highlight from pygments.lexers import PythonTracebackLexer from pygments.formatters import TerminalFormatter exc_str = highlight(exc_str, PythonTracebackLexer(), TerminalFormatter()) except ImportError: pass info(exc_str, file=sys.stderr, use_prefix=False)
def send_email_with_error(data: dict, error_traceback: str) -> str: """ Send an email to the user who committed the changes that an error has happened while processing their .jobs_done file. Returns the recipient of the email in case of success, otherwise will raise an exception (not sure which exceptions are raised by the underlying library). """ import mailer recipient = data['actor']['emailAddress'] project_key = data['repository']['project']['key'] slug = data['repository']['slug'] changes = [(change['ref']['id'], change['toHash']) for change in data['changes']] changes_msg = ', '.join( f'{branch.replace("refs/heads/", "")} @ {commit[:7]}' for (branch, commit) in changes) subject = f'JobsDone failure during push to {project_key}/{slug} ({changes_msg})' message = mailer.Message( From=os.environ['JD_EMAIL_FROM'], To=[recipient], # RTo=None, # Cc=self.cc, Subject=subject, charset='UTF-8', ) pretty_json = pprint.pformat(data) message.Body = EMAIL_PLAINTEXT.format(error_traceback=error_traceback, pretty_json=pretty_json) style = 'colorful' html = EMAIL_HTML.format( error_traceback_html=highlight(error_traceback, PythonTracebackLexer(), HtmlFormatter(style=style)), pretty_json_html=highlight(pretty_json, JsonLexer(), HtmlFormatter(style=style)), ) message.Html = html sender = mailer.Mailer( host=os.environ['JD_EMAIL_SERVER'], port=int(os.environ['JD_EMAIL_PORT']), use_tls=True, usr=os.environ['JD_EMAIL_USER'], pwd=os.environ['JD_EMAIL_PASSWORD'], ) sender.send(message) return recipient
def do_find_traceback(self, tb_id): """Ищет трейсбек ошибки по его id. :param tb_id: id трейсбека :type tb_id: str """ r = requests.get("http://{}/api/druid/traceback/{}".format( self.host, tb_id), headers={"Token": self.token}) print( highlight( loads(r.text)["traceback"], PythonTracebackLexer(), TerminalFormatter()))
def taskerror(taskid): if not has_permission('read'): abort(403, 'Nothing to see there.') job = getjob(engine, taskid) if job is None: abort(404, 'job does not exists') formatter = HtmlFormatter() traceback = highlight(job.traceback, PythonTracebackLexer(), formatter) return render_template('taskerror.html', tid=taskid, css=formatter.get_style_defs(), traceback=traceback)
def custom_traceback(et, ev, tb): trace = ''.join(traceback.format_exception(et, ev, tb)) print("this is custom traceback") # print(et) //zero division error //exception_type # print(ev) //division by zero //event_value # print(tb) //traceback object at 0x1015cc410 //traceback # lexer-> splits source into tokens with token type that... # ...determines what text represents semantically ... # formatter-> takes in token stream and writes it to an output... # ..file in format specified here terminalformatter print( highlight(code=trace, lexer=PythonTracebackLexer(), formatter=TerminalFormatter()))
def setError(self, err_type=None, err_value=None, err_traceback=None): """Translates the given error object into an HTML string and places it it the message panel :param error: an error object (typically an exception object) :type error: object""" msgbox = self._msgbox html_orig = '<html><head><style type="text/css">{style}</style>' \ '</head><body>' style, formatter = "", None if pygments is not None: formatter = HtmlFormatter() style = formatter.get_style_defs() html = html_orig.format(style=style) for de in err_value: e_html = """<pre>{reason}: {desc}</pre>{origin}<hr>""" origin, reason, desc = de.origin, de.reason, de.desc if reason.startswith("PyDs_") and pygments is not None: origin = highlight(origin, PythonTracebackLexer(), formatter) else: origin = "<pre>%s</pre>" % origin html += e_html.format(desc=desc, origin=origin, reason=reason) html += "</body></html>" msgbox.setText(err_value[0].desc) msgbox.setDetailedHtml(html) exc_info = "".join(traceback.format_exception(err_type, err_value, err_traceback)) html = html_orig.format(style=style) if pygments is None: html += "<pre>%s</pre>" % exc_info else: html += highlight(exc_info, PythonTracebackLexer(), formatter) html += "</body></html>" msgbox.setOriginHtml(html)
def toOriginHtml(self, err_type=None, err_value=None, err_traceback=None): exc_info = "".join( traceback.format_exception(err_type, err_value, err_traceback)) html_orig = '<html><head><style type="text/css">{style}</style>' \ '</head><body>' style, formatter = "", None if pygments is not None: formatter = HtmlFormatter() style = formatter.get_style_defs() html = html_orig.format(style=style) if pygments is None: html += "<pre>%s</pre>" % exc_info else: html += highlight(exc_info, PythonTracebackLexer(), formatter) html += "</body></html>" return html
def excepthook(exctype, value, traceback): """Prints exceptions to sys.stderr and colorizes them""" # traceback.format_exception() isn't used because it's # inconsistent with the built-in formatter old_stderr = sys.stderr sys.stderr = StringIO() try: _old_excepthook(exctype, value, traceback) s = sys.stderr.getvalue() try: s = highlight( s, PythonTracebackLexer(), TerminalFormatter()) except UnicodeError: pass old_stderr.write(s) finally: sys.stderr = old_stderr
def _handle_exception(self, e): stdout = self.cli.stdout # Instead of just calling ``traceback.format_exc``, we take the # traceback and skip the bottom calls of this framework. t, v, tb = sys.exc_info() tblist = traceback.extract_tb(tb)[3:] l = traceback.format_list(tblist) if l: l.insert(0, "Traceback (most recent call last):\n") l.extend(traceback.format_exception_only(t, v)) tb = ''.join(l) # Format exception and write to output. stdout.write( highlight(tb, PythonTracebackLexer(), Terminal256Formatter())) stdout.write('%s\n\n' % e) stdout.flush()
def highlight_traceback(recent_traceback): if global_settings.bigtb is False: tb = traceback.format_exception(*recent_traceback) tb.pop(1) print( highlight( ''.join([t.encode('ascii', 'ignore') for t in tb]), PythonTracebackLexer(), TerminalFormatter(bg='dark', colorscheme=TERMINAL_COLORS))) return tb = traceback.extract_tb(recent_traceback[-1]) colored_traceback = 'Traceback:\n' for filename, lineno, method_name, entry_name in tb: if filename.find('functest') is -1: source_file_lines = open(filename, 'r').read().splitlines() colored_traceback += ' in %s at line %s in %s\n' % ( method_name, lineno, filename) if lineno > LINES_IN_TB: index_start = lineno - LINES_IN_TB else: index_start = 0 index_str_length = len(str(lineno)) for i in range(LINES_IN_TB): line = source_file_lines[index_start + i] if len(str(index_start + i)) == index_str_length: index_string = str(index_start + i + 1) + ' ' else: index_string = '0' + str(index_start + i + 1) + ' ' if pygments is not None: colored_traceback += index_string + highlight( line, PythonLexer(), TerminalFormatter(bg='dark', colorscheme=TERMINAL_COLORS)) else: colored_traceback += index_string + line + '\n' print colored_traceback
def wrap_traceback(traceback): if email_type() == 'html': try: from pygments import highlight from pygments.lexers import PythonTracebackLexer from pygments.formatters import HtmlFormatter with_pygments = True except ImportError: with_pygments = False if with_pygments: formatter = HtmlFormatter(noclasses=True) wrapped = highlight(traceback, PythonTracebackLexer(), formatter) else: wrapped = '<pre>%s</pre>' % traceback else: wrapped = traceback return wrapped
def toolTip(self, index): if index.column() > 0: return self.data(index) obj = self.itemData() if hasattr(obj, "exc_info") and obj.exc_info is not None: html_orig = '<html><head><style type="text/css">{style}' \ '</style></head><body>' formatter, style = None, "" if pygments is not None: formatter = HtmlFormatter() style = formatter.get_style_defs() txt = html_orig.format(style=style) if formatter is None: txt += "<pre>%s</pre>" % obj.exc_info else: txt += highlight(obj.exc_info, PythonTracebackLexer(), formatter) txt += "</body></html>" else: txt = "{0} {1}".format(getElementTypeToolTip(obj.type), obj.name) return txt
def toDetailedErrorHtml(self, err_type=None, err_value=None, err_traceback=None): html_orig = '<html><head><style type="text/css">{style}</style>' \ '</head><body>' style, formatter = "", None if pygments is not None: formatter = HtmlFormatter() style = formatter.get_style_defs() html = html_orig.format(style=style) for de in err_value: e_html = """<pre>{reason}: {desc}</pre>{origin}<hr>""" origin, reason, desc = de.origin, de.reason, de.desc if reason.startswith("PyDs_") and pygments is not None: origin = highlight(origin, PythonTracebackLexer(), formatter) else: origin = "<pre>%s</pre>" % origin html += e_html.format(desc=desc, origin=origin, reason=reason) html += "</body></html>" return html
def wrap_traceback(traceback): """ For internal use only (until further notice) """ if email().format == 'html': try: from pygments import highlight from pygments.lexers import PythonTracebackLexer from pygments.formatters import HtmlFormatter with_pygments = True except ImportError: with_pygments = False if with_pygments: formatter = HtmlFormatter(noclasses=True) wrapped = highlight(traceback, PythonTracebackLexer(), formatter) else: wrapped = '<pre>%s</pre>' % traceback else: wrapped = traceback return wrapped
def error(self, e): if request.method == 'HEAD': if isinstance(e, HTTPException): return IppResponse('', status=e.code) else: return IppResponse('', 500) bm = request.accept_mimetypes.best_match( ['application/json', 'text/html']) if bm == 'text/html': if isinstance(e, HTTPException): if e.code == 400: (t, v, tb) = sys.exc_info() return IppResponse(highlight( '\n'.join(traceback.format_exception(t, v, tb)), PythonTracebackLexer(), HtmlFormatter(linenos='table', full=True, title="{}: {}".format( e.code, e.description))), status=e.code, mimetype='text/html') return e.get_response() (t, v, tb) = sys.exc_info() return IppResponse(highlight( '\n'.join(traceback.format_exception(t, v, tb)), PythonTracebackLexer(), HtmlFormatter(linenos='table', full=True, title='500: Internal Exception')), status=500, mimetype='text/html') else: t, v, tb = sys.exc_info() if isinstance(e, HTTPException): response = { 'code': e.code, 'error': e.description, 'debug': { 'traceback': [x for x in traceback.extract_tb(tb)], 'exception': [x for x in traceback.format_exception_only(t, v)] } } return IppResponse(json.dumps(response), status=e.code, mimetype='application/json') response = { 'code': 500, 'error': 'Internal Error', 'debug': { 'traceback': [x for x in traceback.extract_tb(tb)], 'exception': [x for x in traceback.format_exception_only(t, v)] } } return IppResponse(json.dumps(response), status=500, mimetype='application/json')
def _lex_python_traceback(tb): lexer = PythonTracebackLexer() return lexer.get_tokens(tb)
def _lex_python_traceback(tb): " Return token list for traceback string. " lexer = PythonTracebackLexer() return lexer.get_tokens(tb)
def _exc_info_to_string(self, err, test): code = super(HighlightedTextTestResult, self)._exc_info_to_string(err, test) return highlight(code, PythonTracebackLexer(), Terminal256Formatter(style="vim"))
bold(args['<method>'].upper()), bold(url), bold(data_str), status_code), file=sys.stderr) if args['<data>']: print(bold('Data: '), file=sys.stderr) print(pformat(json.loads(args['<data>'])), file=sys.stderr) print(bold('Response:'), file=sys.stderr) body = resp.json() if body: if isinstance(body, dict): if 'traceback' in body and not args['--raw']: traceback = body['traceback'] del body['traceback'] print('Details: ' + body['detail'], file=sys.stderr) print('Status: ' + body['status'], file=sys.stderr) print('Traceback: ' + highlight( traceback, PythonTracebackLexer(), TerminalFormatter()), file=sys.stderr) else: pprint(body) else: print('(not JSON)') print(json.dumps(body, indent=2)) else: print('Response didn\'t contain a body', file=sys.stderr) if failed: sys.exit()
def print_cli_exception(cli_entry, stdout): """ When an action, called from the interactive shell fails, print the exception. """ e = cli_entry.exception def print_exec_failed_exception(e): # hosts.run/sudo failed? Print error information. print print termcolor.colored('FAILED !!', 'red', attrs=['bold']) print termcolor.colored('Command: ', 'yellow'), print termcolor.colored(e.command, 'red', attrs=['bold']) print termcolor.colored('Host: ', 'yellow'), print termcolor.colored(e.host.slug, 'red', attrs=['bold']) print termcolor.colored('Status code: ', 'yellow'), print termcolor.colored(str(e.status_code), 'red', attrs=['bold']) print def print_query_exception(e): print print termcolor.colored('FAILED TO EXECUTE QUERY', 'red', attrs=['bold']) print termcolor.colored('Service: ', 'yellow'), print termcolor.colored(e.service.__repr__(path_only=True), 'red', attrs=['bold']) print termcolor.colored('Attribute: ', 'yellow'), print termcolor.colored(e.attr_name, 'red', attrs=['bold']) print termcolor.colored('Query: ', 'yellow'), print termcolor.colored(e.query, 'red', attrs=['bold']) print if e.inner_exception: print_exception(e.inner_exception) def print_action_exception(e): if isinstance(e.inner_exception, (ExecCommandFailed, QueryException)): print_exception(e.inner_exception) else: print '-'*79 print highlight(e.traceback, PythonTracebackLexer(), Formatter()) print '-'*79 def print_other_exception(e): # Normal exception: print exception print print e print def print_exception(e): if isinstance(e, ActionException): print_action_exception(e) elif isinstance(e, ExecCommandFailed): print_exec_failed_exception(e) elif isinstance(e, QueryException): print_query_exception(e) else: print_other_exception(e) if cli_entry.traceback: print '-'*79 print highlight(cli_entry.traceback, PythonTracebackLexer(), Formatter()) print '-'*79 print_exception(e)
def finished(self): from pygments.lexers import (PythonTracebackLexer, PythonLexer, DiffLexer) if ANSI_COLORS_SUPPORT: from pygments.console import colorize from pygments import highlight if self.style in ('light', 'dark'): from pygments.formatters import TerminalFormatter formatter = TerminalFormatter(bg=self.style) if self.colorscheme is not None: from pygments.token import string_to_tokentype for token, value in self.colorscheme.iteritems(): token = string_to_tokentype(token.capitalize()) formatter.colorscheme[token] = (value, value) else: from pygments.formatters import Terminal256Formatter formatter = Terminal256Formatter(style=self.style) else: # ANSI color codes seem not to be supported, make colorize() # and highlight() no-ops. formatter = None def colorize(_format, text): return text def highlight(text, _lexer, _formatter): return text if self.counter: self.progress.finish() print width, _ = utils.get_terminal_size() def show(result): print colorize('bold', result.test_name) if result.test.__doc__: print inspect.getdoc(result.test) print colorize('faint', '─' * width) for line in result.stdout: print colorize('bold', '→'), print line for line in result.stderr: print colorize('red', '→'), print line if self.verbose: for result in self.passes: if result.stdout or result.stderr: show(result) print for result in self.failures: show(result) # result.traceback seems to be in UTF-8 on my system (eg. for # literal unicode strings) but I guess this depends on the source # file encoding. Tell Pygments to guess: try UTF-8 and then latin1. # Without an `encoding` argument, Pygments just uses latin1. print highlight(result.traceback, PythonTracebackLexer(encoding='guess'), formatter) assertion = result.assertion if assertion is not None: print highlight(assertion, PythonLexer(encoding='guess'), formatter) equality_diff = result.equality_diff if equality_diff is not None: print highlight(equality_diff, DiffLexer(encoding='guess'), formatter) result.debug() if self.failures: failed = colorize('red', str(len(self.failures))) else: failed = len(self.failures) print 'Failures: %s/%s (%s assertions, %.3f seconds)' % ( failed, self.counter, statistics.assertions, self.total_time) if self.failures: raise SystemExit(1)
class Console(QTextEdit): running = pyqtSignal() running_done = pyqtSignal() @property def doc(self): return self.document() @property def cursor(self): return self.textCursor() @property def root_frame(self): return self.doc.rootFrame() def unhandled_exception(self, type, value, tb): if type == KeyboardInterrupt: return try: sio = StringIO.StringIO() traceback.print_exception(type, value, tb, file=sio) fe = sio.getvalue() prints(fe) try: val = unicode(value) except: val = repr(value) msg = '<b>%s</b>:'%type.__name__ + val error_dialog(self, _('ERROR: Unhandled exception'), msg, det_msg=fe, show=True) except BaseException: pass def __init__(self, prompt='>>> ', continuation='... ', parent=None): QTextEdit.__init__(self, parent) self.shutting_down = False self.compiler = CommandCompiler() self.buf = self.old_buf = [] self.history = History([''], dynamic.get('console_history', [])) self.prompt_frame = None self.allow_output = False self.prompt_frame_format = QTextFrameFormat() self.prompt_frame_format.setBorder(1) self.prompt_frame_format.setBorderStyle(QTextFrameFormat.BorderStyle_Solid) self.prompt_len = len(prompt) self.doc.setMaximumBlockCount(int(prefs['scrollback'])) self.lexer = PythonLexer(ensurenl=False) self.tb_lexer = PythonTracebackLexer() self.context_menu = cm = QMenu(self) # {{{ cm.theme = ThemeMenu(cm) # }}} self.formatter = Formatter(prompt, continuation, style=prefs['theme']) p = QPalette() p.setColor(p.Base, QColor(self.formatter.background_color)) p.setColor(p.Text, QColor(self.formatter.color)) self.setPalette(p) self.key_dispatcher = { # {{{ Qt.Key_Enter : self.enter_pressed, Qt.Key_Return : self.enter_pressed, Qt.Key_Up : self.up_pressed, Qt.Key_Down : self.down_pressed, Qt.Key_Home : self.home_pressed, Qt.Key_End : self.end_pressed, Qt.Key_Left : self.left_pressed, Qt.Key_Right : self.right_pressed, Qt.Key_Backspace : self.backspace_pressed, Qt.Key_Delete : self.delete_pressed, } # }}} motd = textwrap.dedent('''\ # Python {0} # {1} {2} '''.format(sys.version.splitlines()[0], __appname__, __version__)) sys.excepthook = self.unhandled_exception self.controllers = [] QTimer.singleShot(0, self.launch_controller) with EditBlock(self.cursor): self.render_block(motd) def shutdown(self): dynamic.set('console_history', self.history.serialize()) self.shutting_down = True for c in self.controllers: c.kill() def contextMenuEvent(self, event): self.context_menu.popup(event.globalPos()) event.accept() # Controller management {{{ @property def controller(self): return self.controllers[-1] def no_controller_error(self): error_dialog(self, _('No interpreter'), _('No active interpreter found. Try restarting the' ' console'), show=True) def launch_controller(self, *args): c = Controller(self) c.write_output.connect(self.show_output, type=Qt.QueuedConnection) c.show_error.connect(self.show_error, type=Qt.QueuedConnection) c.interpreter_died.connect(self.interpreter_died, type=Qt.QueuedConnection) c.interpreter_done.connect(self.execution_done) self.controllers.append(c) def interpreter_died(self, controller, returncode): if not self.shutting_down and controller.current_command is not None: error_dialog(self, _('Interpreter died'), _('Interpreter dies while executing a command. To see ' 'the command, click Show details'), det_msg=controller.current_command, show=True) def execute(self, prompt_lines): c = self.root_frame.lastCursorPosition() self.setTextCursor(c) self.old_prompt_frame = self.prompt_frame self.prompt_frame = None self.old_buf = self.buf self.buf = [] self.running.emit() self.controller.runsource('\n'.join(prompt_lines)) def execution_done(self, controller, ret): if controller is self.controller: self.running_done.emit() if ret: # Incomplete command self.buf = self.old_buf self.prompt_frame = self.old_prompt_frame c = self.prompt_frame.lastCursorPosition() c.insertBlock() self.setTextCursor(c) else: # Command completed try: self.old_prompt_frame.setFrameFormat(QTextFrameFormat()) except RuntimeError: # Happens if enough lines of output that the old # frame was deleted pass self.render_current_prompt() # }}} # Prompt management {{{ @dynamic_property def cursor_pos(self): doc = ''' The cursor position in the prompt has the form (row, col). row starts at 0 for the first line col is 0 if the cursor is at the start of the line, 1 if it is after the first character, n if it is after the nth char. ''' def fget(self): if self.prompt_frame is not None: pos = self.cursor.position() it = self.prompt_frame.begin() lineno = 0 while not it.atEnd(): bl = it.currentBlock() if bl.contains(pos): return (lineno, pos - bl.position()) it += 1 lineno += 1 return (-1, -1) def fset(self, val): row, col = val if self.prompt_frame is not None: it = self.prompt_frame.begin() lineno = 0 while not it.atEnd(): if lineno == row: c = self.cursor c.setPosition(it.currentBlock().position()) c.movePosition(c.NextCharacter, n=col) self.setTextCursor(c) break it += 1 lineno += 1 return property(fget=fget, fset=fset, doc=doc) def move_cursor_to_prompt(self): if self.prompt_frame is not None and self.cursor_pos[0] < 0: c = self.prompt_frame.lastCursorPosition() self.setTextCursor(c) def prompt(self, strip_prompt_strings=True): if not self.prompt_frame: yield u'' if strip_prompt_strings else self.formatter.prompt else: it = self.prompt_frame.begin() while not it.atEnd(): bl = it.currentBlock() t = unicode(bl.text()) if strip_prompt_strings: t = t[self.prompt_len:] yield t it += 1 def set_prompt(self, lines): self.render_current_prompt(lines) def clear_current_prompt(self): if self.prompt_frame is None: c = self.root_frame.lastCursorPosition() self.prompt_frame = c.insertFrame(self.prompt_frame_format) self.setTextCursor(c) else: c = self.prompt_frame.firstCursorPosition() self.setTextCursor(c) c.setPosition(self.prompt_frame.lastPosition(), c.KeepAnchor) c.removeSelectedText() c.setPosition(self.prompt_frame.firstPosition()) def render_current_prompt(self, lines=None, restore_cursor=False): row, col = self.cursor_pos cp = list(self.prompt()) if lines is None else lines self.clear_current_prompt() for i, line in enumerate(cp): start = i == 0 end = i == len(cp) - 1 self.formatter.render_prompt(not start, self.cursor) self.formatter.render(self.lexer.get_tokens(line), self.cursor) if not end: self.cursor.insertBlock() if row > -1 and restore_cursor: self.cursor_pos = (row, col) self.ensureCursorVisible() # }}} # Non-prompt Rendering {{{ def render_block(self, text, restore_prompt=True): self.formatter.render(self.lexer.get_tokens(text), self.cursor) self.cursor.insertBlock() self.cursor.movePosition(self.cursor.End) if restore_prompt: self.render_current_prompt() def show_error(self, is_syntax_err, tb, controller=None): if self.prompt_frame is not None: # At a prompt, so redirect output return prints(tb, end='') try: self.buf.append(tb) if is_syntax_err: self.formatter.render_syntax_error(tb, self.cursor) else: self.formatter.render(self.tb_lexer.get_tokens(tb), self.cursor) except: prints(tb, end='') self.ensureCursorVisible() QApplication.processEvents() def show_output(self, raw, which='stdout', controller=None): def do_show(): try: self.buf.append(raw) self.formatter.render_raw(raw, self.cursor) except: import traceback prints(traceback.format_exc()) prints(raw, end='') if self.prompt_frame is not None: with Prepender(self): do_show() else: do_show() self.ensureCursorVisible() QApplication.processEvents() # }}} # Keyboard management {{{ def keyPressEvent(self, ev): text = unicode(ev.text()) key = ev.key() action = self.key_dispatcher.get(key, None) if callable(action): action() elif key in (Qt.Key_Escape,): QTextEdit.keyPressEvent(self, ev) elif text: self.text_typed(text) else: QTextEdit.keyPressEvent(self, ev) def left_pressed(self): lineno, pos = self.cursor_pos if lineno < 0: return if pos > self.prompt_len: c = self.cursor c.movePosition(c.PreviousCharacter) self.setTextCursor(c) elif lineno > 0: c = self.cursor c.movePosition(c.Up) c.movePosition(c.EndOfLine) self.setTextCursor(c) self.ensureCursorVisible() def up_pressed(self): lineno, pos = self.cursor_pos if lineno < 0: return if lineno == 0: b = self.history.back() if b is not None: self.set_prompt(b) else: c = self.cursor c.movePosition(c.Up) self.setTextCursor(c) self.ensureCursorVisible() def backspace_pressed(self): lineno, pos = self.cursor_pos if lineno < 0: return if pos > self.prompt_len: self.cursor.deletePreviousChar() elif lineno > 0: c = self.cursor c.movePosition(c.Up) c.movePosition(c.EndOfLine) self.setTextCursor(c) self.ensureCursorVisible() def delete_pressed(self): self.cursor.deleteChar() self.ensureCursorVisible() def right_pressed(self): lineno, pos = self.cursor_pos if lineno < 0: return c = self.cursor cp = list(self.prompt(False)) if pos < len(cp[lineno]): c.movePosition(c.NextCharacter) elif lineno < len(cp)-1: c.movePosition(c.NextCharacter, n=1+self.prompt_len) self.setTextCursor(c) self.ensureCursorVisible() def down_pressed(self): lineno, pos = self.cursor_pos if lineno < 0: return c = self.cursor cp = list(self.prompt(False)) if lineno >= len(cp) - 1: b = self.history.forward() if b is not None: self.set_prompt(b) else: c = self.cursor c.movePosition(c.Down) self.setTextCursor(c) self.ensureCursorVisible() def home_pressed(self): if self.prompt_frame is not None: mods = QApplication.keyboardModifiers() ctrl = bool(int(mods & Qt.CTRL)) if ctrl: self.cursor_pos = (0, self.prompt_len) else: c = self.cursor c.movePosition(c.StartOfLine) c.movePosition(c.NextCharacter, n=self.prompt_len) self.setTextCursor(c) self.ensureCursorVisible() def end_pressed(self): if self.prompt_frame is not None: mods = QApplication.keyboardModifiers() ctrl = bool(int(mods & Qt.CTRL)) if ctrl: self.cursor_pos = (len(list(self.prompt()))-1, self.prompt_len) c = self.cursor c.movePosition(c.EndOfLine) self.setTextCursor(c) self.ensureCursorVisible() def enter_pressed(self): if self.prompt_frame is None: return if not self.controller.is_alive: return self.no_controller_error() cp = list(self.prompt()) if cp[0]: try: ret = self.compiler('\n'.join(cp)) except: pass else: if ret is None: c = self.prompt_frame.lastCursorPosition() c.insertBlock() self.setTextCursor(c) self.render_current_prompt() return else: self.history.enter(cp) self.execute(cp) def text_typed(self, text): if self.prompt_frame is not None: self.move_cursor_to_prompt() self.cursor.insertText(text) self.render_current_prompt(restore_cursor=True) self.history.current = list(self.prompt())
def print_output(string): if string: print(highlight(string, PythonTracebackLexer(), TerminalFormatter(bg='dark')))
def showtraceback(self): tokens = PythonTracebackLexer().get_tokens(traceback.format_exc()) self.cli.print_tokens(tokens, style=DefaultStyle)
def _exc_info_to_string(self, err, test): code = super(ColorTextTestResult, self)._exc_info_to_string(err, test) return highlight(code, PythonTracebackLexer(), TerminalFormatter())
def traceback(self, tb): """Highlight text of a Python traceback. """ return pygments.highlight(tb, PythonTracebackLexer(), HtmlFormatter())
import logging import re import sys import ipywidgets from scrapydo.utils import highlight from pygments.formatters import TerminalFormatter from pygments.lexers import PythonTracebackLexer, PythonLexer from fabric.colors import blue, cyan, green, magenta, red lexer = PythonLexer() python_traceback_lexer = PythonTracebackLexer() terminal_formatter = TerminalFormatter() re_color_codes = re.compile(r'\033\[(\d;)?\d+m') LEVELS = { 'INFO': blue('INFO'), 'DEBUG': blue('DEBUG'), 'WARNING': red('WARN', bold=True), 'CRITICAL': magenta('CRIT'), 'ERROR': red('ERROR'), } class ScrapyFormatter(logging.Formatter): def __init__(self): logging.Formatter.__init__(self) def format(self, record): s = '%(levelname)s %(name)s %(message)s' % {