Browse Source

Song errors contain a reference to the song they occur in

pull/176/head
Louis 9 years ago
parent
commit
362c6b87ce
  1. 6
      patacrep/errors.py
  2. 1
      patacrep/latex/syntax.py
  3. 4
      patacrep/songs/__init__.py
  4. 2
      patacrep/songs/chordpro/__init__.py
  5. 4
      patacrep/songs/chordpro/ast.py
  6. 22
      patacrep/songs/errors.py
  7. 12
      patacrep/songs/syntax.py

6
patacrep/errors.py

@ -104,6 +104,12 @@ class ParsingError(SongbookError):
def __str__(self): def __str__(self):
return self.message return self.message
class SharedError(SongbookError):
"""Error that is meant to be shared to third party tools using patacrep."""
def __str__(self):
raise NotImplementedError()
def notfound(filename, paths, message=None): def notfound(filename, paths, message=None):
"""Return a string saying that file was not found in paths.""" """Return a string saying that file was not found in paths."""
if message is None: if message is None:

1
patacrep/latex/syntax.py

@ -136,6 +136,7 @@ class LatexParser(Parser):
symbols[0][symbols[1]] = symbols[3] symbols[0][symbols[1]] = symbols[3]
symbols[0].update(symbols[4]) symbols[0].update(symbols[4])
else: else:
# TODO put error in self.errors
raise ParsingError("Do enclose arguments between braces.") raise ParsingError("Do enclose arguments between braces.")
@staticmethod @staticmethod

4
patacrep/songs/__init__.py

@ -180,8 +180,8 @@ class Song:
protocol=-1 protocol=-1
) )
def __repr__(self): def __str__(self):
return repr((self.titles, self.data, self.fullpath)) return str(self.fullpath)
def render(self, *args, **kwargs): def render(self, *args, **kwargs):
"""Return the code rendering this song. """Return the code rendering this song.

2
patacrep/songs/chordpro/__init__.py

@ -33,7 +33,7 @@ class ChordproSong(Song):
self.titles = song.titles self.titles = song.titles
self.lang = song.get_data_argument('language', self.default_lang) self.lang = song.get_data_argument('language', self.default_lang)
self.data = song.meta self.data = song.meta
self.errors = song.errors self.errors = [error(song=self) for error in song.error_builders]
self.cached = { self.cached = {
'song': song, 'song': song,
} }

4
patacrep/songs/chordpro/ast.py

@ -232,9 +232,9 @@ class Song(AST):
self._subtitles = [] self._subtitles = []
self.filename = filename self.filename = filename
if errors is None: if errors is None:
self.errors = [] self.error_builders = []
else: else:
self.errors = errors self.error_builders = errors
for directive in directives: for directive in directives:
self.add(directive) self.add(directive)

22
patacrep/songs/errors.py

@ -1,37 +1,35 @@
"""Errors in song definition (syntax errors, and so on)""" """Errors in song definition (syntax errors, and so on)"""
class SongError(Exception): from patacrep.errors import SharedError
class SongError(SharedError):
"""Generic song error""" """Generic song error"""
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
type = "generic" def __init__(self, song, message):
def __init__(self, message):
super().__init__() super().__init__()
self.song = song
self.message = message self.message = message
def __str__(self): def __str__(self):
raise NotImplementedError() return "Song {}: {}".format(self.song, self.message)
class SongSyntaxError(SongError): class SongSyntaxError(SongError):
"""Syntax error""" """Syntax error"""
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
type = "syntax" def __init__(self, song, line, message):
super().__init__(song, message)
def __init__(self, line, message):
super().__init__(message)
#: Line of error. May be `None` if irrelevant. #: Line of error. May be `None` if irrelevant.
self.line = line self.line = line
def __str__(self): def __str__(self):
if self.line is not None: if self.line is not None:
return "Line {}: {}".format(self.line, self.message) return "Song {}, line {}: {}".format(self.song, self.line, self.message)
else: else:
return self.message return "Song {}: {}".format(self.song, self.message)
# class FileError(SongError): # class FileError(SongError):
# type = "file" # type = "file"
# #
# class LanguageError(SongError): # class LanguageError(SongError):
# type = "language"

12
patacrep/songs/syntax.py

@ -1,5 +1,6 @@
"""Generic parsing classes and methods""" """Generic parsing classes and methods"""
import functools
import logging import logging
from patacrep.songs import errors from patacrep.songs import errors
@ -25,12 +26,11 @@ class Parser:
def error(self, *, line=None, column=None, message=""): def error(self, *, line=None, column=None, message=""):
"""Record and display an error message""" """Record and display an error message"""
self._errors.append( self._errors.append(functools.partial(
errors.SongSyntaxError( errors.SongSyntaxError,
line=line, line=line,
message=message, message=message,
) ))
)
coordinates = [] coordinates = []
if line is not None: if line is not None:

Loading…
Cancel
Save