diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 001e84616..f6dadd686 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -25,6 +25,9 @@ import unicodedata from functools import reduce import six +if not six.PY2: + buffer = memoryview # sqlite won't accept memoryview in python 2 + class ParsingError(ValueError): """Abstract class for any unparseable user-requested album/query @@ -244,7 +247,7 @@ class BytesQuery(MatchQuery): def __init__(self, field, pattern): super(BytesQuery, self).__init__(field, pattern) - # Use a buffer representation of the pattern for SQLite + # Use a buffer/memoryview representation of the pattern for SQLite # matching. This instructs SQLite to treat the blob as binary # rather than encoded Unicode. if isinstance(self.pattern, (six.text_type, bytes)): diff --git a/beets/dbcore/types.py b/beets/dbcore/types.py index 2270d7c13..ef583672e 100644 --- a/beets/dbcore/types.py +++ b/beets/dbcore/types.py @@ -21,6 +21,9 @@ from . import query from beets.util import str2bool import six +if not six.PY2: + buffer = memoryview # sqlite won't accept memoryview in python 2 + # Abstract base. @@ -98,8 +101,8 @@ class Type(object): https://docs.python.org/2/library/sqlite3.html#sqlite-and-python-types Flexible fields have the type affinity `TEXT`. This means the - `sql_value` is either a `buffer` or a `unicode` object` and the - method must handle these in addition. + `sql_value` is either a `buffer`/`memoryview` or a `unicode` object` + and the method must handle these in addition. """ if isinstance(sql_value, buffer): sql_value = bytes(sql_value).decode('utf8', 'ignore') diff --git a/beets/library.py b/beets/library.py index f46092fe2..7821f93f4 100644 --- a/beets/library.py +++ b/beets/library.py @@ -35,6 +35,8 @@ from beets import dbcore from beets.dbcore import types import beets +if not six.PY2: + buffer = memoryview # sqlite won't accept memoryview in python 2 log = logging.getLogger('beets') @@ -159,8 +161,8 @@ class PathType(types.Type): return bytestring_path(value) elif isinstance(value, buffer): - # SQLite must store bytestings as buffers to avoid decoding. - # We unwrap buffers to bytes. + # SQLite must store bytestings as buffers/memoryview + # to avoid decoding. We unwrap buffers to bytes. return bytes(value) else: diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 5fe52d7b8..56504ec3f 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -633,9 +633,13 @@ def as_string(value): """Convert a value to a Unicode object for matching with a query. None becomes the empty string. Bytestrings are silently decoded. """ + buffer_types = memoryview + if six.PY2: + buffer_types = (buffer, memoryview) + if value is None: return u'' - elif isinstance(value, buffer): + elif isinstance(value, buffer_types): return bytes(value).decode('utf8', 'ignore') elif isinstance(value, bytes): return value.decode('utf8', 'ignore')