mirror of
https://github.com/beetbox/beets.git
synced 2025-12-30 20:42:37 +01:00
Widen usage of InvalidQueryError
Replace previous InvalidQueryError with InvalidQueryArgumentTypeError which extends the former as TypeError. However they lack context: the query that caused the error. Raise an InvalidQueryError when a shell-like expression cannot be parsed by shlex. Improve #1290.
This commit is contained in:
parent
bbc6d0906b
commit
54887e7655
5 changed files with 25 additions and 9 deletions
|
|
@ -23,5 +23,6 @@ from .types import Type
|
|||
from .queryparse import query_from_strings
|
||||
from .queryparse import sort_from_strings
|
||||
from .queryparse import parse_sorted_query
|
||||
from .query import InvalidQueryError
|
||||
|
||||
# flake8: noqa
|
||||
|
|
|
|||
|
|
@ -24,11 +24,17 @@ from datetime import datetime, timedelta
|
|||
|
||||
|
||||
class InvalidQueryError(ValueError):
|
||||
def __init__(self, query, explanation):
|
||||
message = "Invalid query '{0}': {1}".format(query, explanation)
|
||||
super(InvalidQueryError, self).__init__(message)
|
||||
|
||||
|
||||
class InvalidQueryArgumentTypeError(InvalidQueryError, TypeError):
|
||||
def __init__(self, what, expected, detail=None):
|
||||
message = "'{0}' is not {1}".format(what, expected)
|
||||
if detail:
|
||||
message = "{0}: {1}".format(message, detail)
|
||||
super(InvalidQueryError, self).__init__(message)
|
||||
super(InvalidQueryArgumentTypeError, self).__init__(None, message)
|
||||
|
||||
|
||||
class Query(object):
|
||||
|
|
@ -160,8 +166,9 @@ class RegexpQuery(StringFieldQuery):
|
|||
self.pattern = re.compile(self.pattern)
|
||||
except re.error as exc:
|
||||
# Invalid regular expression.
|
||||
raise InvalidQueryError(pattern, "a regular expression",
|
||||
format(exc))
|
||||
raise InvalidQueryArgumentTypeError(pattern,
|
||||
"a regular expression",
|
||||
format(exc))
|
||||
|
||||
@classmethod
|
||||
def string_match(cls, pattern, value):
|
||||
|
|
@ -228,7 +235,7 @@ class NumericQuery(FieldQuery):
|
|||
try:
|
||||
return float(s)
|
||||
except ValueError:
|
||||
raise InvalidQueryError(s, "an int or a float")
|
||||
raise InvalidQueryArgumentTypeError(s, "an int or a float")
|
||||
|
||||
def __init__(self, field, pattern, fast=True):
|
||||
super(NumericQuery, self).__init__(field, pattern, fast)
|
||||
|
|
|
|||
|
|
@ -1085,7 +1085,7 @@ def parse_query_string(s, model_cls):
|
|||
try:
|
||||
parts = [p.decode('utf8') for p in shlex.split(s)]
|
||||
except ValueError as exc:
|
||||
raise ValueError("Cannot parse {0!r} (error was: {1})".format(s, exc))
|
||||
raise dbcore.InvalidQueryError(s, exc)
|
||||
return parse_query_parts(parts, model_cls)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ from test._common import unittest
|
|||
from test._common import item
|
||||
import beets.library
|
||||
import beets.mediafile
|
||||
import beets.dbcore
|
||||
from beets import util
|
||||
from beets import plugins
|
||||
from beets import config
|
||||
|
|
@ -1171,6 +1172,12 @@ class ItemReadTest(unittest.TestCase):
|
|||
item.read('/thisfiledoesnotexist')
|
||||
|
||||
|
||||
class ParseQueryTest(unittest.TestCase):
|
||||
def test_parse_invalid_query_string(self):
|
||||
with self.assertRaises(beets.dbcore.InvalidQueryError):
|
||||
beets.library.parse_query_string('foo"', None)
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ from test import helper
|
|||
|
||||
import beets.library
|
||||
from beets import dbcore
|
||||
from beets.dbcore import types
|
||||
from beets.dbcore.query import NoneQuery, InvalidQueryError
|
||||
from beets.dbcore import types, InvalidQueryError
|
||||
from beets.dbcore.query import NoneQuery, InvalidQueryArgumentTypeError
|
||||
from beets.library import Library, Item
|
||||
|
||||
|
||||
|
|
@ -282,14 +282,15 @@ class GetTest(DummyDataTestCase):
|
|||
self.assertFalse(results)
|
||||
|
||||
def test_invalid_query(self):
|
||||
with self.assertRaises(InvalidQueryError) as raised:
|
||||
with self.assertRaises(InvalidQueryArgumentTypeError) as raised:
|
||||
dbcore.query.NumericQuery('year', '199a')
|
||||
self.assertIn('not an int', unicode(raised.exception))
|
||||
|
||||
with self.assertRaises(InvalidQueryError) as raised:
|
||||
with self.assertRaises(InvalidQueryArgumentTypeError) as raised:
|
||||
dbcore.query.RegexpQuery('year', '199(')
|
||||
self.assertIn('not a regular expression', unicode(raised.exception))
|
||||
self.assertIn('unbalanced parenthesis', unicode(raised.exception))
|
||||
self.assertIsInstance(raised.exception, (InvalidQueryError, TypeError))
|
||||
|
||||
|
||||
class MatchTest(_common.TestCase):
|
||||
|
|
|
|||
Loading…
Reference in a new issue