Merge pull request #1824 from refi64/drop-clint

Drop clint for colors in favor of colorama
This commit is contained in:
Kodi Arfer 2019-10-22 08:59:46 -04:00 committed by GitHub
commit f8d3826689
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 44 deletions

View File

@ -34,6 +34,11 @@ Bug Fixes
* The unit tests no longer unintentionally import the internal Python module "test". * The unit tests no longer unintentionally import the internal Python module "test".
This allows them to pass when run inside the "slim" Python Docker images. This allows them to pass when run inside the "slim" Python Docker images.
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 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``, it can be turned off globally by setting ``hy.models.PRETTY`` to ``False``,
or temporarily by using the ``hy.models.pretty`` context manager. or temporarily by using the ``hy.models.pretty`` context manager.
Hy also attempts to color pretty reprs using ``clint.textui.colored``. Hy also attempts to color pretty reprs and errors using ``colorama``. These can
This module has a flag to disable coloring, be turned off globally by setting ``hy.models.COLORED`` and ``hy.errors.COLORED``,
and a method ``clean`` to strip colored strings of their color tags. respectively, to ``False``.
.. _hysequence: .. _hysequence:

View File

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

View File

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

View File

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

View File

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

View File

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