From d40fd9bb154f001fdd1e9b1f1086e9489d224c55 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 13 Dec 2015 00:23:17 +0100 Subject: [PATCH] [song.chordpro] Catch fatal syntax error when a block is not closed --- patacrep/songs/__init__.py | 7 ++++--- patacrep/songs/chordpro/__init__.py | 2 +- patacrep/songs/chordpro/syntax.py | 27 +++++++++++---------------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index 5c40591a..9a357163 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -7,8 +7,10 @@ import os import pickle import re +from patacrep import errors as book_errors from patacrep import files, encoding from patacrep.authors import process_listauthors +from patacrep.songs import errors as song_errors LOGGER = logging.getLogger(__name__) @@ -106,7 +108,7 @@ class Song: self.subpath = subpath self._filehash = None self.encoding = config["encoding"] - self.default_lang = config["lang"] + self.lang = config["lang"] self.config = config self.errors = [] @@ -116,8 +118,7 @@ class Song: # Data extraction from the latex song self.titles = [] self.data = {} - self.cached = None - self.lang = None + self.cached = {} self._parse() # Post processing of data diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 48a16d95..cd3d5933 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -31,7 +31,7 @@ class ChordproSong(Song): song = parse_song(song.read(), self.fullpath) self.authors = song.authors self.titles = song.titles - self.lang = song.get_data_argument('language', self.default_lang) + self.lang = song.get_data_argument('language', self.lang) self.data = song.meta self.errors = [error(song=self) for error in song.error_builders] self.cached = { diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index abc79993..fd54406e 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -1,13 +1,14 @@ """ChordPro parser""" +import functools import logging import ply.yacc as yacc import re -from patacrep.songs.syntax import Parser +from patacrep.songs import errors from patacrep.songs.chordpro import ast from patacrep.songs.chordpro.lexer import tokens, ChordProLexer -from patacrep.songs import errors +from patacrep.songs.syntax import Parser LOGGER = logging.getLogger() @@ -328,19 +329,13 @@ def parse_song(content, filename=None): lexer=ChordProLexer(filename=filename).lexer, ) if parsed_content is None: - # pylint: disable=fixme - # TODO: Provide a nicer error (an empty song?) - # TODO: Add an error to the song.errors list. - # using parser._errors - - # pylint: disable=protected-access - if parser._errors: - # The line where it started to go wrong - lineno = parser._errors[-1].line - else: - lineno = None - raise errors.SongSyntaxError( - message='Fatal error during song parsing: {}'.format(filename), - line=lineno, + return ast.Song( + filename, + [], + errors=[functools.partial( + errors.SongSyntaxError, + line=parser._errors[-1].keywords['line'], + message='Fatal error during song parsing.', + )] ) return parsed_content