fix non-string value matching in SubstringQuery

This commit is contained in:
Adrian Sampson 2012-09-09 12:17:13 -07:00
parent 90b3dba085
commit dc054907d5
4 changed files with 25 additions and 11 deletions

View file

@ -166,10 +166,7 @@ def _regexp(expr, val):
"""
if expr is None:
return False
if val is None:
val = u''
if not isinstance(val, basestring):
val = unicode(val)
val = util.as_string(val)
try:
res = re.search(expr, val)
except re.error:
@ -436,7 +433,7 @@ class SubstringQuery(FieldQuery):
return clause, subvals
def match(self, item):
value = getattr(item, self.field) or ''
value = util.as_string(getattr(item, self.field))
return self.pattern.lower() in value.lower()
class RegexpQuery(FieldQuery):
@ -451,11 +448,7 @@ class RegexpQuery(FieldQuery):
return clause, subvals
def match(self, item):
value = getattr(item, self.field) or ''
if value is None:
value = u''
elif not isinstance(value, basestring):
value = unicode(value)
value = util.as_string(getattr(item, self.field))
return self.regexp.search(value) is not None
class BooleanQuery(MatchQuery):

View file

@ -467,6 +467,15 @@ def str2bool(value):
else:
return False
def as_string(value):
"""Convert a value to a Unicode object for matching with a query.
None becomes the empty string.
"""
if value is None:
return u''
else:
return unicode(value)
def levenshtein(s1, s2):
"""A nice DP edit distance implementation from Wikibooks:
http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/

View file

@ -12,7 +12,7 @@ Changelog
* Fix album queries for ``artpath`` and other non-item fields.
* Null values in the database can now be matched with the empty-string regular
expression, ``^$``.
* Regular expressions more reliably match non-string values.
* Queries now correctly match non-string values in path format predicates.
* :doc:`/plugins/fetchart`: Fix a bug where cover art filenames could lack
a ``.jpg`` extension.
* :doc:`/plugins/lyrics`: Fix an exception with non-ASCII lyrics.

View file

@ -318,6 +318,18 @@ class MatchTest(unittest.TestCase):
q = beets.library.RegexpQuery('disc', '^6$')
self.assertTrue(q.match(self.item))
def test_substring_match_positive(self):
q = beets.library.SubstringQuery('album', 'album')
self.assertTrue(q.match(self.item))
def test_substring_match_negative(self):
q = beets.library.SubstringQuery('album', 'ablum')
self.assertFalse(q.match(self.item))
def test_substring_match_non_string_value(self):
q = beets.library.SubstringQuery('disc', '6')
self.assertTrue(q.match(self.item))
class PathQueryTest(unittest.TestCase, AssertsMixin):
def setUp(self):
self.lib = beets.library.Library(':memory:')