Drop clint for colors in favor of colorama

Closes #1820.
This commit is contained in:
Ryan Gonzalez 2019-10-07 19:20:54 -05:00
parent 84d1a116f6
commit 0579561b83
7 changed files with 64 additions and 44 deletions

View File

@ -31,6 +31,11 @@ Bug Fixes
* `hy2py` can now handle format strings.
* Fixed crashes from inaccessible history files.
Misc. Improvements
------------------------------
* Drop the use of the long-abandoned `clint <https://github.com/kennethreitz/clint>`_ library
for colors. `colorama <https://github.com/tartley/colorama>`_ is now used instead.
0.17.0
==============================

View File

@ -44,9 +44,9 @@ If this is causing issues,
it can be turned off globally by setting ``hy.models.PRETTY`` to ``False``,
or temporarily by using the ``hy.models.pretty`` context manager.
Hy also attempts to color pretty reprs using ``clint.textui.colored``.
This module has a flag to disable coloring,
and a method ``clean`` to strip colored strings of their color tags.
Hy also attempts to color pretty reprs and errors using ``colorama``. These can
be turned off globally by setting ``hy.models.COLORED`` and ``hy.errors.COLORED``,
respectively, to ``False``.
.. _hysequence:

View File

@ -4,6 +4,9 @@
from __future__ import print_function
import colorama
colorama.init()
import argparse
import code
import ast

View File

@ -9,14 +9,13 @@ import traceback
import pkgutil
from functools import reduce
from colorama import Fore
from contextlib import contextmanager
from hy import _initialize_env_var
from clint.textui import colored
_hy_filter_internal_errors = _initialize_env_var('HY_FILTER_INTERNAL_ERRORS',
True)
_hy_colored_errors = _initialize_env_var('HY_COLORED_ERRORS', False)
COLORED = _initialize_env_var('HY_COLORED_ERRORS', False)
class HyError(Exception):
@ -108,15 +107,12 @@ class HyLanguageError(HyError):
"""Provide an exception message that includes SyntaxError-like source
line information when available.
"""
global _hy_colored_errors
# Syntax errors are special and annotate the traceback (instead of what
# we would do in the message that follows the traceback).
if isinstance(self, SyntaxError):
return super(HyLanguageError, self).__str__()
# When there isn't extra source information, use the normal message.
if not isinstance(self, SyntaxError) and not self.text:
elif not self.text:
return super(HyLanguageError, self).__str__()
# Re-purpose Python's builtin syntax error formatting.
@ -142,15 +138,14 @@ class HyLanguageError(HyError):
output[arrow_idx] = '{}{}^\n'.format(output[arrow_idx].rstrip('\n'),
'-' * (self.arrow_offset - 1))
if _hy_colored_errors:
from clint.textui import colored
output[msg_idx:] = [colored.yellow(o) for o in output[msg_idx:]]
if COLORED:
output[msg_idx:] = [Fore.YELLOW + o + Fore.RESET for o in output[msg_idx:]]
if arrow_idx:
output[arrow_idx] = colored.green(output[arrow_idx])
output[arrow_idx] = Fore.GREEN + output[arrow_idx] + Fore.RESET
for idx, line in enumerate(output[::msg_idx]):
if line.strip().startswith(
'File "{}", line'.format(self.filename)):
output[idx] = colored.red(line)
output[idx] = Fore.RED + line + Fore.RESET
# This resulting string will come after a "<class-name>:" prompt, so
# put it down a line.

View File

@ -8,10 +8,10 @@ from math import isnan, isinf
from hy import _initialize_env_var
from hy.errors import HyWrapperError
from fractions import Fraction
from clint.textui import colored
from colorama import Fore
PRETTY = True
_hy_colored_ast_objects = _initialize_env_var('HY_COLORED_AST_OBJECTS', False)
COLORED = _initialize_env_var('HY_COLORED_AST_OBJECTS', False)
@contextmanager
@ -28,6 +28,18 @@ def pretty(pretty=True):
PRETTY = old
class _ColoredModel:
"""
Mixin that provides a helper function for models that have color.
"""
def _colored(self, text):
if COLORED:
return self.color + text + Fore.RESET
else:
return text
class HyObject(object):
"""
Generic Hy Object model. This is helpful to inject things into all the
@ -243,7 +255,7 @@ class HyComplex(HyObject, complex):
_wrappers[complex] = HyComplex
class HySequence(HyObject, tuple):
class HySequence(HyObject, tuple, _ColoredModel):
"""
An abstract type for sequence-like models to inherit from.
"""
@ -276,21 +288,25 @@ class HySequence(HyObject, tuple):
return str(self) if PRETTY else super(HySequence, self).__repr__()
def __str__(self):
global _hy_colored_ast_objects
with pretty():
c = self.color if _hy_colored_ast_objects else str
if self:
return ("{}{}\n {}{}").format(
c(self.__class__.__name__),
c("(["),
(c(",") + "\n ").join([repr_indent(e) for e in self]),
c("])"))
return self._colored("{}{}\n {}{}".format(
self._colored(self.__class__.__name__),
self._colored("(["),
self._colored(",\n ").join(map(repr_indent, self)),
self._colored("])"),
))
return self._colored("{}([\n {}])".format(
self.__class__.__name__,
','.join(repr_indent(e) for e in self),
))
else:
return '' + c(self.__class__.__name__ + "()")
return self._colored(self.__class__.__name__ + "()")
class HyList(HySequence):
color = staticmethod(colored.cyan)
color = Fore.CYAN
def recwrap(f):
return lambda l: f(wrap_value(x) for x in l)
@ -300,16 +316,14 @@ _wrappers[list] = recwrap(HyList)
_wrappers[tuple] = recwrap(HyList)
class HyDict(HySequence):
class HyDict(HySequence, _ColoredModel):
"""
HyDict (just a representation of a dict)
"""
color = staticmethod(colored.green)
color = Fore.GREEN
def __str__(self):
global _hy_colored_ast_objects
with pretty():
g = self.color if _hy_colored_ast_objects else str
if self:
pairs = []
for k, v in zip(self[::2],self[1::2]):
@ -317,14 +331,16 @@ class HyDict(HySequence):
pairs.append(
("{0}{c}\n {1}\n "
if '\n' in k+v
else "{0}{c} {1}").format(k, v, c=g(',')))
else "{0}{c} {1}").format(k, v, c=self._colored(',')))
if len(self) % 2 == 1:
pairs.append("{} {}\n".format(
repr_indent(self[-1]), g("# odd")))
repr_indent(self[-1]), self._colored("# odd")))
return "{}\n {}{}".format(
g("HyDict(["), ("{c}\n ".format(c=g(',')).join(pairs)), g("])"))
self._colored("HyDict(["),
"{c}\n ".format(c=self._colored(',')).join(pairs),
self._colored("])"))
else:
return '' + g("HyDict()")
return self._colored("HyDict()")
def keys(self):
return list(self[0::2])
@ -343,7 +359,7 @@ class HyExpression(HySequence):
"""
Hy S-Expression. Basically just a list.
"""
color = staticmethod(colored.yellow)
color = Fore.YELLOW
_wrappers[HyExpression] = recwrap(HyExpression)
_wrappers[Fraction] = lambda e: HyExpression(
@ -354,7 +370,7 @@ class HySet(HySequence):
"""
Hy set (just a representation of a set)
"""
color = staticmethod(colored.red)
color = Fore.RED
_wrappers[HySet] = recwrap(HySet)
_wrappers[set] = recwrap(HySet)

View File

@ -35,7 +35,7 @@ install_requires = [
'rply>=0.7.7',
'astor>=0.8',
'funcparserlib>=0.3.6',
'clint>=0.4']
'colorama']
if os.name == 'nt':
install_requires.append('pyreadline>=2.1')

View File

@ -4,10 +4,11 @@
import copy
import hy
from clint.textui.colored import clean
from hy.models import (wrap_value, replace_hy_obj, HyString, HyInteger, HyList,
HyDict, HySet, HyExpression, HyComplex, HyFloat, pretty)
hy.models.COLORED = False
def test_wrap_int():
""" Test conversion of integers."""
@ -182,13 +183,13 @@ def test_compound_model_repr():
assert eval(repr(model([1, 2, 3]))) == model([1, 2, 3])
for k, v in PRETTY_STRINGS.items():
# `str` should be pretty, even under `pretty(False)`.
assert clean(str(hy.read_str(k))) == v
assert str(hy.read_str(k)) == v
for k in PRETTY_STRINGS.keys():
assert eval(repr(hy.read_str(k))) == hy.read_str(k)
with pretty(True):
for model in HY_LIST_MODELS:
assert eval(clean(repr(model()))).__class__ is model
assert eval(clean(repr(model([1, 2])))) == model([1, 2])
assert eval(clean(repr(model([1, 2, 3])))) == model([1, 2, 3])
assert eval(repr(model())).__class__ is model
assert eval(repr(model([1, 2]))) == model([1, 2])
assert eval(repr(model([1, 2, 3]))) == model([1, 2, 3])
for k, v in PRETTY_STRINGS.items():
assert clean(repr(hy.read_str(k))) == v
assert repr(hy.read_str(k)) == v