Skip to content

Commit

Permalink
Make colored output configurable
Browse files Browse the repository at this point in the history
Colored exception output is now disabled by default and configurable through
`hy.errors._hy_colored_errors` and the environment variable
`HY_COLORED_ERRORS`.

Likewise, Hy model/AST color printing is now configurable and disabled by
default.  The corresponding variables are `hy.models._hy_colored_ast_objects`
and `HY_COLORED_AST_OBJECTS`.

Closes hylang#1429, closes hylang#1510.
  • Loading branch information
brandonwillard committed Jan 17, 2019
1 parent 0c77e88 commit 782555e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 34 deletions.
13 changes: 12 additions & 1 deletion hy/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import __builtin__ as builtins
except ImportError:
import builtins # NOQA
import sys, keyword, textwrap
import os, sys, keyword, textwrap
import distutils.util

PY3 = sys.version_info[0] >= 3
PY35 = sys.version_info >= (3, 5)
Expand Down Expand Up @@ -77,6 +78,16 @@ def isidentifier(x):
return False
return len(tokens) == 2 and tokens[0][0] == T.NAME


def _initialize_env_var(env_var, default_val):
try:
res = bool(distutils.util.strtobool(
os.environ.get(env_var, str(default_val))))
except ValueError as e:
res = default_val
return res


try:
FileNotFoundError = FileNotFoundError
except NameError:
Expand Down
61 changes: 33 additions & 28 deletions hy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@
import sys
import traceback
import pkgutil
import distutils.util

from functools import reduce
from contextlib import contextmanager
from hy._compat import _initialize_env_var

from clint.textui import colored


try:
_hy_filter_internal_errors = bool(distutils.util.strtobool(
os.environ.get('HY_FILTER_INTERNAL_ERRORS', 't')))
except ValueError as e:
_hy_filter_internal_errors = True
_hy_filter_internal_errors = _initialize_env_var('HY_FILTER_INTERNAL_ERRORS',
True)
_hy_colored_errors = _initialize_env_var('HY_COLORED_ERRORS', False)


class HyError(Exception):
Expand Down Expand Up @@ -77,9 +72,16 @@ def __init__(self, message, filename=None, expression=None, source=None):
source)

def __str__(self):
global _hy_colored_errors

result = ""

if _hy_colored_errors:
from clint.textui import colored
red, green, yellow = colored.red, colored.green, colored.yellow
else:
red = green = yellow = lambda x: x

if all(getattr(self.expression, x, None) is not None
for x in ("start_line", "start_column", "end_column")):

Expand All @@ -101,28 +103,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

Expand Down Expand Up @@ -203,18 +205,21 @@ def from_expression(message, expression, filename=None, source=None):
return HySyntaxError(message, filename, lineno, colno, source)

def __str__(self):
global _hy_colored_errors

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 _hy_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)
Expand Down
14 changes: 9 additions & 5 deletions hy/models.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# 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

from contextlib import contextmanager
from math import isnan, isinf
from hy._compat import PY3, str_type, bytes_type, long_type, string_types
from hy._compat import (PY3, str_type, bytes_type, long_type, string_types,
_initialize_env_var)
from fractions import Fraction
from clint.textui import colored


PRETTY = True
_hy_colored_ast_objects = _initialize_env_var('HY_COLORED_AST_OBJECTS', False)


@contextmanager
Expand Down Expand Up @@ -271,8 +272,9 @@ def __repr__(self):
return str(self) if PRETTY else super(HySequence, self).__repr__()

def __str__(self):
global _hy_colored_ast_objects
with pretty():
c = self.color
c = self.color if _hy_colored_ast_objects else str
if self:
return ("{}{}\n {}{}").format(
c(self.__class__.__name__),
Expand All @@ -298,10 +300,12 @@ class HyDict(HySequence):
"""
HyDict (just a representation of a dict)
"""
color = staticmethod(colored.green)

def __str__(self):
global _hy_colored_ast_objects
with pretty():
g = colored.green
g = self.color if _hy_colored_ast_objects else str
if self:
pairs = []
for k, v in zip(self[::2],self[1::2]):
Expand Down

0 comments on commit 782555e

Please sign in to comment.