diff --git a/hy/errors.py b/hy/errors.py index 14dc84296..4c9906b7c 100644 --- a/hy/errors.py +++ b/hy/errors.py @@ -10,9 +10,7 @@ from functools import reduce from contextlib import contextmanager -from clint.textui import colored - - +_hy_colored_errors = False _hy_filter_internal_errors = True @@ -22,6 +20,11 @@ def filter_errors(): _hy_filter_internal_errors) +def colored_errors(): + global _hy_colored_errors + return os.environ.get('HY_COLORED_ERRORS', _hy_colored_errors) + + class HyError(Exception): def __init__(self, message, *args): self.message = message @@ -84,6 +87,13 @@ def __str__(self): has_syntax_info = all(hasattr(self.expression, x) for x in ("start_line", "start_column", "end_column", "end_line")) + + if colored_errors(): + from clint.textui import colored + red, green, yellow = colored.red, colored.green, colored.yellow + else: + red = green = yellow = lambda x: x + if has_syntax_info: line = self.expression.start_line start = self.expression.start_column @@ -103,28 +113,28 @@ def __str__(self): start) if len(source) == 1: - result += ' %s\n' % colored.red(source[0]) + result += ' %s\n' % red(source[0]) result += ' %s%s\n' % (' '*(start-1), - colored.green('^' + '-'*(length-1) + '^')) + green('^' + '-'*(length-1) + '^')) if len(source) > 1: - result += ' %s\n' % colored.red(source[0]) + result += ' %s\n' % red(source[0]) result += ' %s%s\n' % (' '*(start-1), - colored.green('^' + '-'*length)) + green('^' + '-'*length)) if len(source) > 2: # write the middle lines for line in source[1:-1]: - result += ' %s\n' % colored.red("".join(line)) - result += ' %s\n' % colored.green("-"*len(line)) + result += ' %s\n' % red("".join(line)) + result += ' %s\n' % green("-"*len(line)) # write the last line - result += ' %s\n' % colored.red("".join(source[-1])) - result += ' %s\n' % colored.green('-'*(end-1) + '^') + result += ' %s\n' % red("".join(source[-1])) + result += ' %s\n' % green('-'*(end-1) + '^') else: result += ' File "%s", unknown location\n' % self.filename - result += colored.yellow("%s: %s\n\n" % - (self.__class__.__name__, - self.message)) + result += yellow("%s: %s\n\n" % + (self.__class__.__name__, + self.message)) return result @@ -209,14 +219,16 @@ def __str__(self): output = traceback.format_exception_only(SyntaxError, SyntaxError(*self.args)) - output[-1] = colored.yellow(output[-1]) - if len(self.source) > 0: - output[-2] = colored.green(output[-2]) - for line in output[::-2]: - if line.strip().startswith( - 'File "{}", line'.format(self.filename)): - break - output[-3] = colored.red(output[-3]) + if colored_errors(): + from hy.errors import colored + output[-1] = colored.yellow(output[-1]) + if len(self.source) > 0: + output[-2] = colored.green(output[-2]) + for line in output[::-2]: + if line.strip().startswith( + 'File "{}", line'.format(self.filename)): + break + output[-3] = colored.red(output[-3]) # Avoid "...expected str instance, ColoredString found" return reduce(lambda x, y: x + y, output) diff --git a/hy/models.py b/hy/models.py index 2ff5efa11..f8575a881 100644 --- a/hy/models.py +++ b/hy/models.py @@ -1,8 +1,10 @@ # Copyright 2018 the authors. # This file is part of Hy, which is free software licensed under the Expat # license. See the LICENSE. - from __future__ import unicode_literals + +import os + from contextlib import contextmanager from math import isnan, isinf from hy._compat import PY3, str_type, bytes_type, long_type, string_types @@ -11,6 +13,12 @@ PRETTY = True +_hy_colored_ast_objects = False + + +def colored_ast_objects(): + global _hy_colored_ast_objects + return os.environ.get('HY_COLORED_AST_OBJECTS', _hy_colored_ast_objects) @contextmanager @@ -272,7 +280,7 @@ def __repr__(self): def __str__(self): with pretty(): - c = self.color + c = self.color if colored_ast_objects() else str if self: return ("{}{}\n {}{}").format( c(self.__class__.__name__), @@ -298,10 +306,11 @@ class HyDict(HySequence): """ HyDict (just a representation of a dict) """ + color = staticmethod(colored.green) def __str__(self): with pretty(): - g = colored.green + g = self.color if colored_ast_objects() else str if self: pairs = [] for k, v in zip(self[::2],self[1::2]):