Make messages from either check more sane

This commit is contained in:
Foo 2015-03-01 14:25:40 +03:00
parent 704d4a47b3
commit 93d2109589
2 changed files with 40 additions and 15 deletions

View File

@ -145,10 +145,11 @@ def echoerr(**kwargs):
stream.write(format_error(**kwargs) + '\n')
def format_error(context=None, context_mark=None, problem=None, problem_mark=None, note=None):
def format_error(context=None, context_mark=None, problem=None, problem_mark=None, note=None, indent=0):
lines = []
indentstr = ' ' * indent
if context is not None:
lines.append(context)
lines.append(indentstr + context)
if (
context_mark is not None
and (
@ -158,13 +159,13 @@ def format_error(context=None, context_mark=None, problem=None, problem_mark=Non
or context_mark.column != problem_mark.column
)
):
lines.append(str(context_mark))
lines.append(context_mark.to_string(indent=indent))
if problem is not None:
lines.append(problem)
lines.append(indentstr + problem)
if problem_mark is not None:
lines.append(str(problem_mark))
lines.append(problem_mark.to_string(indent=indent))
if note is not None:
lines.append(note)
lines.append(indentstr + note)
return '\n'.join(lines)
@ -174,29 +175,48 @@ class MarkedError(Exception):
class EchoErr(object):
__slots__ = ('echoerr', 'logger',)
__slots__ = ('echoerr', 'logger', 'indent')
def __init__(self, echoerr, logger):
def __init__(self, echoerr, logger, indent=0):
self.echoerr = echoerr
self.logger = logger
self.indent = indent
def __call__(self, **kwargs):
kwargs = kwargs.copy()
kwargs.setdefault('indent', self.indent)
self.echoerr(**kwargs)
class DelayedEchoErr(EchoErr):
__slots__ = ('echoerr', 'logger', 'errs')
__slots__ = ('echoerr', 'logger', 'errs', 'message', 'separator_message', 'indent', 'indent_shift')
def __init__(self, echoerr):
def __init__(self, echoerr, message='', separator_message=''):
super(DelayedEchoErr, self).__init__(echoerr, echoerr.logger)
self.errs = []
self.errs = [[]]
self.message = message
self.separator_message = separator_message
self.indent_shift = (4 if message or separator_message else 0)
self.indent = echoerr.indent + self.indent_shift
def __call__(self, **kwargs):
self.errs.append(kwargs)
kwargs = kwargs.copy()
kwargs['indent'] = kwargs.get('indent', 0) + self.indent
self.errs[-1].append(kwargs)
def next_variant(self):
self.errs.append([])
def echo_all(self):
for kwargs in self.errs:
self.echoerr(**kwargs)
if self.message:
self.echoerr(problem=self.message, indent=(self.indent - self.indent_shift))
for variant in self.errs:
if not variant:
continue
if self.separator_message and variant is not self.errs[0]:
self.echoerr(problem=self.separator_message, indent=(self.indent - self.indent_shift))
for kwargs in variant:
self.echoerr(**kwargs)
def __nonzero__(self):
return not not self.errs

View File

@ -309,11 +309,16 @@ class Spec(object):
``self.specs[start:end]`` is matched by the given value.
'''
havemarks(value)
new_echoerr = DelayedEchoErr(echoerr)
new_echoerr = DelayedEchoErr(
echoerr,
'One of the either variants failed. Messages from the first variant:',
'messages from the next variant:'
)
hadproblem = False
for spec in self.specs[start:end]:
proceed, hadproblem = spec.match(value, value.mark, data, context, new_echoerr)
new_echoerr.next_variant()
if not proceed:
break
if not hadproblem: