parent
84d1a116f6
commit
0579561b83
5
NEWS.rst
5
NEWS.rst
@ -31,6 +31,11 @@ Bug Fixes
|
|||||||
* `hy2py` can now handle format strings.
|
* `hy2py` can now handle format strings.
|
||||||
* Fixed crashes from inaccessible history files.
|
* 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
|
0.17.0
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
19
hy/errors.py
19
hy/errors.py
@ -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.
|
||||||
|
60
hy/models.py
60
hy/models.py
@ -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)
|
||||||
|
2
setup.py
2
setup.py
@ -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')
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user