replace unicode with six.text_type

This commit is contained in:
Johnny Robeson 2016-06-20 04:34:24 -04:00
parent 7b66dfec4b
commit e8afcbe7ec
56 changed files with 269 additions and 203 deletions

View file

@ -27,6 +27,7 @@ from beets.util import as_string
from beets.autotag import mb
from jellyfish import levenshtein_distance
from unidecode import unidecode
import six
log = logging.getLogger('beets')
@ -205,8 +206,8 @@ def _string_dist_basic(str1, str2):
transliteration/lowering to ASCII characters. Normalized by string
length.
"""
assert isinstance(str1, unicode)
assert isinstance(str2, unicode)
assert isinstance(str1, six.text_type)
assert isinstance(str2, six.text_type)
str1 = as_string(unidecode(str1))
str2 = as_string(unidecode(str2))
str1 = re.sub(r'[^a-z0-9]', '', str1.lower())

View file

@ -27,6 +27,7 @@ import beets.autotag.hooks
import beets
from beets import util
from beets import config
import six
VARIOUS_ARTISTS_ID = '89ad4ac3-39f7-470e-963a-56509c546377'
BASE_URL = 'http://musicbrainz.org/'
@ -69,7 +70,8 @@ def configure():
"""Set up the python-musicbrainz-ngs module according to settings
from the beets configuration. This should be called at startup.
"""
musicbrainzngs.set_hostname(config['musicbrainz']['host'].get(unicode))
hostname = config['musicbrainz']['host'].get(six.text_type)
musicbrainzngs.set_hostname(hostname)
musicbrainzngs.set_rate_limit(
config['musicbrainz']['ratelimit_interval'].as_number(),
config['musicbrainz']['ratelimit'].get(int),
@ -260,7 +262,7 @@ def album_info(release):
)
info.va = info.artist_id == VARIOUS_ARTISTS_ID
if info.va:
info.artist = config['va_name'].get(unicode)
info.artist = config['va_name'].get(six.text_type)
info.asin = release.get('asin')
info.releasegroup_id = release['release-group']['id']
info.country = release.get('country')
@ -329,7 +331,7 @@ def match_album(artist, album, tracks=None):
# Various Artists search.
criteria['arid'] = VARIOUS_ARTISTS_ID
if tracks is not None:
criteria['tracks'] = unicode(tracks)
criteria['tracks'] = six.text_type(tracks)
# Abort if we have no search terms.
if not any(criteria.itervalues()):

View file

@ -29,6 +29,7 @@ import beets
from beets.util.functemplate import Template
from beets.dbcore import types
from .query import MatchQuery, NullSort, TrueQuery
import six
class FormattedMapping(collections.Mapping):
@ -69,7 +70,7 @@ class FormattedMapping(collections.Mapping):
value = value.decode('utf8', 'ignore')
if self.for_path:
sep_repl = beets.config['path_sep_replace'].get(unicode)
sep_repl = beets.config['path_sep_replace'].get(six.text_type)
for sep in (os.path.sep, os.path.altsep):
if sep:
value = value.replace(sep, sep_repl)

View file

@ -23,6 +23,7 @@ from beets import util
from datetime import datetime, timedelta
import unicodedata
from functools import reduce
import six
class ParsingError(ValueError):
@ -246,8 +247,8 @@ class BytesQuery(MatchQuery):
# Use a buffer representation of the pattern for SQLite
# matching. This instructs SQLite to treat the blob as binary
# rather than encoded Unicode.
if isinstance(self.pattern, (unicode, bytes)):
if isinstance(self.pattern, unicode):
if isinstance(self.pattern, (six.text_type, bytes)):
if isinstance(self.pattern, six.text_type):
self.pattern = self.pattern.encode('utf8')
self.buf_pattern = buffer(self.pattern)
elif isinstance(self.pattern, buffer):
@ -793,7 +794,7 @@ class FieldSort(Sort):
def key(item):
field_val = item.get(self.field, '')
if self.case_insensitive and isinstance(field_val, unicode):
if self.case_insensitive and isinstance(field_val, six.text_type):
field_val = field_val.lower()
return field_val

View file

@ -19,6 +19,7 @@ from __future__ import division, absolute_import, print_function
from . import query
from beets.util import str2bool
import six
# Abstract base.
@ -37,7 +38,7 @@ class Type(object):
"""The `Query` subclass to be used when querying the field.
"""
model_type = unicode
model_type = six.text_type
"""The Python type that is used to represent the value in the model.
The model is guaranteed to return a value of this type if the field
@ -63,7 +64,7 @@ class Type(object):
if isinstance(value, bytes):
value = value.decode('utf8', 'ignore')
return unicode(value)
return six.text_type(value)
def parse(self, string):
"""Parse a (possibly human-written) string and return the
@ -102,7 +103,7 @@ class Type(object):
"""
if isinstance(sql_value, buffer):
sql_value = bytes(sql_value).decode('utf8', 'ignore')
if isinstance(sql_value, unicode):
if isinstance(sql_value, six.text_type):
return self.parse(sql_value)
else:
return self.normalize(sql_value)
@ -194,7 +195,7 @@ class Boolean(Type):
model_type = bool
def format(self, value):
return unicode(bool(value))
return six.text_type(bool(value))
def parse(self, string):
return str2bool(string)

View file

@ -14,6 +14,7 @@
# included in all copies or substantial portions of the Software.
from __future__ import division, absolute_import, print_function
import six
"""Provides the basic, interface-agnostic workflow for importing and
autotagging music files.
@ -640,7 +641,7 @@ class ImportTask(BaseImportTask):
changes['comp'] = False
else:
# VA.
changes['albumartist'] = config['va_name'].get(unicode)
changes['albumartist'] = config['va_name'].get(six.text_type)
changes['comp'] = True
elif self.choice_flag in (action.APPLY, action.RETAG):

View file

@ -124,14 +124,15 @@ class DateType(types.Float):
query = dbcore.query.DateQuery
def format(self, value):
return time.strftime(beets.config['time_format'].get(unicode),
return time.strftime(beets.config['time_format'].get(six.text_type),
time.localtime(value or 0))
def parse(self, string):
try:
# Try a formatted date string.
return time.mktime(
time.strptime(string, beets.config['time_format'].get(unicode))
time.strptime(string,
beets.config['time_format'].get(six.text_type))
)
except ValueError:
# Fall back to a plain timestamp number.
@ -153,7 +154,7 @@ class PathType(types.Type):
return normpath(bytestring_path(string))
def normalize(self, value):
if isinstance(value, unicode):
if isinstance(value, six.text_type):
# Paths stored internally as encoded bytes.
return bytestring_path(value)
@ -281,11 +282,11 @@ class FileOperationError(Exception):
"""
return u'{0}: {1}'.format(
util.displayable_path(self.path),
unicode(self.reason)
six.text_type(self.reason)
)
def __str__(self):
return unicode(self).encode('utf8')
return six.text_type(self).encode('utf8')
class ReadError(FileOperationError):
@ -331,7 +332,7 @@ class LibModel(dbcore.Model):
def __format__(self, spec):
if not spec:
spec = beets.config[self._format_config_key].get(unicode)
spec = beets.config[self._format_config_key].get(six.text_type)
result = self.evaluate_template(spec)
if isinstance(spec, bytes):
# if spec is a byte string then we must return a one as well
@ -517,7 +518,7 @@ class Item(LibModel):
"""
# Encode unicode paths and read buffers.
if key == 'path':
if isinstance(value, unicode):
if isinstance(value, six.text_type):
value = bytestring_path(value)
elif isinstance(value, buffer):
value = bytes(value)
@ -1061,7 +1062,8 @@ class Album(LibModel):
image = bytestring_path(image)
item_dir = item_dir or self.item_dir()
filename_tmpl = Template(beets.config['art_filename'].get(unicode))
filename_tmpl = Template(
beets.config['art_filename'].get(six.text_type))
subpath = self.evaluate_template(filename_tmpl, True)
if beets.config['asciify_paths']:
subpath = unidecode(subpath)
@ -1179,7 +1181,8 @@ def parse_query_string(s, model_cls):
The string is split into components using shell-like syntax.
"""
assert isinstance(s, unicode), u"Query is not unicode: {0!r}".format(s)
message = u"Query is not unicode: {0!r}".format(s)
assert isinstance(s, six.text_type), message
try:
parts = util.shlex_split(s)
except ValueError as exc:
@ -1405,7 +1408,7 @@ class DefaultTemplateFunctions(object):
def tmpl_time(s, fmt):
"""Format a time value using `strftime`.
"""
cur_fmt = beets.config['time_format'].get(unicode)
cur_fmt = beets.config['time_format'].get(six.text_type)
return time.strftime(fmt, time.strptime(s, cur_fmt))
def tmpl_aunique(self, keys=None, disam=None):

View file

@ -27,6 +27,7 @@ from copy import copy
from logging import * # noqa
import subprocess
import threading
import six
def logsafe(val):
@ -42,7 +43,7 @@ def logsafe(val):
example.
"""
# Already Unicode.
if isinstance(val, unicode):
if isinstance(val, six.text_type):
return val
# Bytestring: needs decoding.
@ -56,7 +57,7 @@ def logsafe(val):
# A "problem" object: needs a workaround.
elif isinstance(val, subprocess.CalledProcessError):
try:
return unicode(val)
return six.text_type(val)
except UnicodeDecodeError:
# An object with a broken __unicode__ formatter. Use __str__
# instead.

View file

@ -59,6 +59,7 @@ import enum
from beets import logging
from beets.util import displayable_path, syspath, as_string
import six
__all__ = ['UnreadableFileError', 'FileTypeError', 'MediaFile']
@ -131,7 +132,7 @@ def _safe_cast(out_type, val):
else:
# Process any other type as a string.
if not isinstance(val, basestring):
val = unicode(val)
val = six.text_type(val)
# Get a number from the front of the string.
val = re.match(r'[0-9]*', val.strip()).group(0)
if not val:
@ -146,13 +147,13 @@ def _safe_cast(out_type, val):
except ValueError:
return False
elif out_type == unicode:
elif out_type == six.text_type:
if isinstance(val, bytes):
return val.decode('utf8', 'ignore')
elif isinstance(val, unicode):
elif isinstance(val, six.text_type):
return val
else:
return unicode(val)
return six.text_type(val)
elif out_type == float:
if isinstance(val, int) or isinstance(val, float):
@ -161,7 +162,7 @@ def _safe_cast(out_type, val):
if isinstance(val, bytes):
val = val.decode('utf8', 'ignore')
else:
val = unicode(val)
val = six.text_type(val)
match = re.match(r'[\+-]?([0-9]+\.?[0-9]*|[0-9]*\.[0-9]+)',
val.strip())
if match:
@ -220,7 +221,7 @@ def _sc_decode(soundcheck):
"""
# We decode binary data. If one of the formats gives us a text
# string, interpret it as UTF-8.
if isinstance(soundcheck, unicode):
if isinstance(soundcheck, six.text_type):
soundcheck = soundcheck.encode('utf8')
# SoundCheck tags consist of 10 numbers, each represented by 8
@ -407,7 +408,8 @@ class StorageStyle(object):
"""List of mutagen classes the StorageStyle can handle.
"""
def __init__(self, key, as_type=unicode, suffix=None, float_places=2):
def __init__(self, key, as_type=six.text_type, suffix=None,
float_places=2):
"""Create a basic storage strategy. Parameters:
- `key`: The key on the Mutagen file object used to access the
@ -426,8 +428,8 @@ class StorageStyle(object):
self.float_places = float_places
# Convert suffix to correct string type.
if self.suffix and self.as_type is unicode \
and not isinstance(self.suffix, unicode):
if self.suffix and self.as_type is six.text_type \
and not isinstance(self.suffix, six.text_type):
self.suffix = self.suffix.decode('utf8')
# Getter.
@ -450,7 +452,7 @@ class StorageStyle(object):
"""Given a raw value stored on a Mutagen object, decode and
return the represented value.
"""
if self.suffix and isinstance(mutagen_value, unicode) \
if self.suffix and isinstance(mutagen_value, six.text_type) \
and mutagen_value.endswith(self.suffix):
return mutagen_value[:-len(self.suffix)]
else:
@ -472,17 +474,17 @@ class StorageStyle(object):
"""Convert the external Python value to a type that is suitable for
storing in a Mutagen file object.
"""
if isinstance(value, float) and self.as_type is unicode:
if isinstance(value, float) and self.as_type is six.text_type:
value = u'{0:.{1}f}'.format(value, self.float_places)
value = self.as_type(value)
elif self.as_type is unicode:
elif self.as_type is six.text_type:
if isinstance(value, bool):
# Store bools as 1/0 instead of True/False.
value = unicode(int(bool(value)))
value = six.text_type(int(bool(value)))
elif isinstance(value, bytes):
value = value.decode('utf8', 'ignore')
else:
value = unicode(value)
value = six.text_type(value)
else:
value = self.as_type(value)
@ -592,7 +594,7 @@ class MP4StorageStyle(StorageStyle):
def serialize(self, value):
value = super(MP4StorageStyle, self).serialize(value)
if self.key.startswith('----:') and isinstance(value, unicode):
if self.key.startswith('----:') and isinstance(value, six.text_type):
value = value.encode('utf8')
return value
@ -807,7 +809,7 @@ class MP3SlashPackStorageStyle(MP3StorageStyle):
def _fetch_unpacked(self, mutagen_file):
data = self.fetch(mutagen_file)
if data:
items = unicode(data).split('/')
items = six.text_type(data).split('/')
else:
items = []
packing_length = 2
@ -823,7 +825,7 @@ class MP3SlashPackStorageStyle(MP3StorageStyle):
items[0] = ''
if items[1] is None:
items.pop() # Do not store last value
self.store(mutagen_file, '/'.join(map(unicode, items)))
self.store(mutagen_file, '/'.join(map(six.text_type, items)))
def delete(self, mutagen_file):
if self.pack_pos == 0:
@ -1074,7 +1076,7 @@ class MediaField(object):
getting this property.
"""
self.out_type = kwargs.get('out_type', unicode)
self.out_type = kwargs.get('out_type', six.text_type)
self._styles = styles
def styles(self, mutagen_file):
@ -1113,7 +1115,7 @@ class MediaField(object):
return 0.0
elif self.out_type == bool:
return False
elif self.out_type == unicode:
elif self.out_type == six.text_type:
return u''
@ -1195,8 +1197,8 @@ class DateField(MediaField):
# Get the underlying data and split on hyphens and slashes.
datestring = super(DateField, self).__get__(mediafile, None)
if isinstance(datestring, basestring):
datestring = re.sub(r'[Tt ].*$', '', unicode(datestring))
items = re.split('[-/]', unicode(datestring))
datestring = re.sub(r'[Tt ].*$', '', six.text_type(datestring))
items = re.split('[-/]', six.text_type(datestring))
else:
items = []
@ -1233,7 +1235,7 @@ class DateField(MediaField):
date.append(u'{0:02d}'.format(int(month)))
if month and day:
date.append(u'{0:02d}'.format(int(day)))
date = map(unicode, date)
date = map(six.text_type, date)
super(DateField, self).__set__(mediafile, u'-'.join(date))
if hasattr(self, '_year_field'):
@ -1360,7 +1362,7 @@ class MediaFile(object):
try:
self.mgfile = mutagen.File(path)
except unreadable_exc as exc:
log.debug(u'header parsing failed: {0}', unicode(exc))
log.debug(u'header parsing failed: {0}', six.text_type(exc))
raise UnreadableFileError(path)
except IOError as exc:
if type(exc) == IOError:

View file

@ -42,6 +42,7 @@ from beets import config
from beets.util import confit, as_string
from beets.autotag import mb
from beets.dbcore import query as db_query
import six
# On Windows platforms, use colorama to support "ANSI" terminal colors.
if sys.platform == 'win32':
@ -140,7 +141,7 @@ def print_(*strings, **kwargs):
"""
end = kwargs.get('end')
if not strings or isinstance(strings[0], unicode):
if not strings or isinstance(strings[0], six.text_type):
txt = u' '.join(strings)
txt += u'\n' if end is None else end
else:
@ -148,7 +149,7 @@ def print_(*strings, **kwargs):
txt += b'\n' if end is None else end
# Always send bytes to the stdout stream.
if isinstance(txt, unicode):
if isinstance(txt, six.text_type):
txt = txt.encode(_out_encoding(), 'replace')
sys.stdout.write(txt)
@ -298,11 +299,11 @@ def input_options(options, require=False, prompt=None, fallback_prompt=None,
prompt_part_lengths = []
if numrange:
if isinstance(default, int):
default_name = unicode(default)
default_name = six.text_type(default)
default_name = colorize('action_default', default_name)
tmpl = '# selection (default %s)'
prompt_parts.append(tmpl % default_name)
prompt_part_lengths.append(len(tmpl % unicode(default)))
prompt_part_lengths.append(len(tmpl % six.text_type(default)))
else:
prompt_parts.append('# selection')
prompt_part_lengths.append(len(prompt_parts[-1]))
@ -522,7 +523,8 @@ def colorize(color_name, text):
if config['ui']['color']:
global COLORS
if not COLORS:
COLORS = dict((name, config['ui']['colors'][name].get(unicode))
COLORS = dict((name,
config['ui']['colors'][name].get(six.text_type))
for name in COLOR_NAMES)
# In case a 3rd party plugin is still passing the actual color ('red')
# instead of the abstract color name ('text_error')
@ -544,8 +546,8 @@ def _colordiff(a, b, highlight='text_highlight',
"""
if not isinstance(a, basestring) or not isinstance(b, basestring):
# Non-strings: use ordinary equality.
a = unicode(a)
b = unicode(b)
a = six.text_type(a)
b = six.text_type(b)
if a == b:
return a, b
else:
@ -593,7 +595,7 @@ def colordiff(a, b, highlight='text_highlight'):
if config['ui']['color']:
return _colordiff(a, b, highlight)
else:
return unicode(a), unicode(b)
return six.text_type(a), six.text_type(b)
def get_path_formats(subview=None):
@ -604,7 +606,7 @@ def get_path_formats(subview=None):
subview = subview or config['paths']
for query, view in subview.items():
query = PF_KEY_QUERIES.get(query, query) # Expand common queries.
path_formats.append((query, Template(view.get(unicode))))
path_formats.append((query, Template(view.get(six.text_type))))
return path_formats

View file

@ -38,6 +38,7 @@ from beets import library
from beets import config
from beets import logging
from beets.util.confit import _package_path
import six
VARIOUS_ARTISTS = u'Various Artists'
PromptChoice = namedtuple('ExtraChoice', ['short', 'long', 'callback'])
@ -163,7 +164,7 @@ def disambig_string(info):
else:
disambig.append(info.media)
if info.year:
disambig.append(unicode(info.year))
disambig.append(six.text_type(info.year))
if info.country:
disambig.append(info.country)
if info.label:
@ -236,9 +237,9 @@ def show_change(cur_artist, cur_album, match):
if mediums > 1:
return u'{0}-{1}'.format(medium, medium_index)
else:
return unicode(medium_index)
return six.text_type(medium_index)
else:
return unicode(index)
return six.text_type(index)
# Identify the album in question.
if cur_artist != match.info.artist or \

View file

@ -27,6 +27,7 @@ import subprocess
import platform
import shlex
from beets.util import hidden
import six
MAX_FILENAME_LENGTH = 200
@ -65,14 +66,14 @@ class HumanReadableException(Exception):
def _reasonstr(self):
"""Get the reason as a string."""
if isinstance(self.reason, unicode):
if isinstance(self.reason, six.text_type):
return self.reason
elif isinstance(self.reason, bytes):
return self.reason.decode('utf8', 'ignore')
elif hasattr(self.reason, 'strerror'): # i.e., EnvironmentError
return self.reason.strerror
else:
return u'"{0}"'.format(unicode(self.reason))
return u'"{0}"'.format(six.text_type(self.reason))
def get_message(self):
"""Create the human-readable description of the error, sans
@ -346,11 +347,11 @@ def displayable_path(path, separator=u'; '):
"""
if isinstance(path, (list, tuple)):
return separator.join(displayable_path(p) for p in path)
elif isinstance(path, unicode):
elif isinstance(path, six.text_type):
return path
elif not isinstance(path, bytes):
# A non-string object: just get its unicode representation.
return unicode(path)
return six.text_type(path)
try:
return path.decode(_fsencoding(), 'ignore')
@ -369,7 +370,7 @@ def syspath(path, prefix=True):
if os.path.__name__ != 'ntpath':
return path
if not isinstance(path, unicode):
if not isinstance(path, six.text_type):
# Beets currently represents Windows paths internally with UTF-8
# arbitrarily. But earlier versions used MBCS because it is
# reported as the FS encoding by Windows. Try both.
@ -639,7 +640,7 @@ def as_string(value):
elif isinstance(value, bytes):
return value.decode('utf8', 'ignore')
else:
return unicode(value)
return six.text_type(value)
def plurality(objs):
@ -765,7 +766,7 @@ def shlex_split(s):
# Shlex works fine.
return shlex.split(s)
elif isinstance(s, unicode):
elif isinstance(s, six.text_type):
# Work around a Python bug.
# http://bugs.python.org/issue6988
bs = s.encode('utf8')
@ -801,7 +802,7 @@ def _windows_long_path_name(short_path):
"""Use Windows' `GetLongPathNameW` via ctypes to get the canonical,
long path given a short filename.
"""
if not isinstance(short_path, unicode):
if not isinstance(short_path, six.text_type):
short_path = short_path.decode(_fsencoding())
import ctypes

View file

@ -25,6 +25,7 @@ import yaml
import collections
import re
from collections import OrderedDict
import six
UNIX_DIR_VAR = 'XDG_CONFIG_HOME'
UNIX_DIR_FALLBACK = '~/.config'
@ -44,7 +45,7 @@ REDACTED_TOMBSTONE = 'REDACTED'
# Utilities.
PY3 = sys.version_info[0] == 3
STRING = str if PY3 else unicode # noqa
STRING = str if PY3 else six.text_type # noqa
BASESTRING = str if PY3 else basestring # noqa
NUMERIC_TYPES = (int, float) if PY3 else (int, float, long) # noqa

View file

@ -35,6 +35,7 @@ import dis
import types
from .confit import NUMERIC_TYPES
import six
SYMBOL_DELIM = u'$'
FUNC_DELIM = u'%'
@ -190,8 +191,8 @@ class Call(object):
except Exception as exc:
# Function raised exception! Maybe inlining the name of
# the exception will help debug.
return u'<%s>' % unicode(exc)
return unicode(out)
return u'<%s>' % six.text_type(exc)
return six.text_type(out)
else:
return self.original
@ -246,7 +247,7 @@ class Expression(object):
out.append(part)
else:
out.append(part.evaluate(env))
return u''.join(map(unicode, out))
return u''.join(map(six.text_type, out))
def translate(self):
"""Compile the expression to a list of Python AST expressions, a
@ -563,7 +564,7 @@ if __name__ == '__main__':
import timeit
_tmpl = Template(u'foo $bar %baz{foozle $bar barzle} $bar')
_vars = {'bar': 'qux'}
_funcs = {'baz': unicode.upper}
_funcs = {'baz': six.text_type.upper}
interp_time = timeit.timeit('_tmpl.interpret(_vars, _funcs)',
'from __main__ import _tmpl, _vars, _funcs',
number=10000)

View file

@ -20,6 +20,7 @@ import os
import stat
import ctypes
import sys
import six
def _is_hidden_osx(path):
@ -74,7 +75,7 @@ def is_hidden(path):
work out if a file is hidden.
"""
# Convert the path to unicode if it is not already.
if not isinstance(path, unicode):
if not isinstance(path, six.text_type):
path = path.decode('utf-8')
# Run platform specific functions depending on the platform

View file

@ -27,6 +27,7 @@ import shlex
import os
import errno
import sys
import six
class BadFiles(BeetsPlugin):
@ -97,7 +98,7 @@ class BadFiles(BeetsPlugin):
if not checker:
continue
path = item.path
if not isinstance(path, unicode):
if not isinstance(path, six.text_type):
path = item.path.decode(sys.getfilesystemencoding())
status, errors, output = checker(path)
if status > 0:

View file

@ -18,6 +18,7 @@ from __future__ import division, absolute_import, print_function
import json
import re
import six
from datetime import datetime, timedelta
from requests_oauthlib import OAuth1Session
@ -42,15 +43,15 @@ class BeatportAPIError(Exception):
class BeatportObject(object):
def __init__(self, data):
self.beatport_id = data['id']
self.name = unicode(data['name'])
self.name = six.text_type(data['name'])
if 'releaseDate' in data:
self.release_date = datetime.strptime(data['releaseDate'],
'%Y-%m-%d')
if 'artists' in data:
self.artists = [(x['id'], unicode(x['name']))
self.artists = [(x['id'], six.text_type(x['name']))
for x in data['artists']]
if 'genres' in data:
self.genres = [unicode(x['name'])
self.genres = [six.text_type(x['name'])
for x in data['genres']]
@ -209,7 +210,7 @@ class BeatportRelease(BeatportObject):
)
def __repr__(self):
return unicode(self).encode('utf8')
return six.text_type(self).encode('utf8')
def __init__(self, data):
BeatportObject.__init__(self, data)
@ -231,14 +232,14 @@ class BeatportTrack(BeatportObject):
.format(artist_str, self.name, self.mix_name))
def __repr__(self):
return unicode(self).encode('utf8')
return six.text_type(self).encode('utf8')
def __init__(self, data):
BeatportObject.__init__(self, data)
if 'title' in data:
self.title = unicode(data['title'])
self.title = six.text_type(data['title'])
if 'mixName' in data:
self.mix_name = unicode(data['mixName'])
self.mix_name = six.text_type(data['mixName'])
self.length = timedelta(milliseconds=data.get('lengthMs', 0) or 0)
if not self.length:
try:
@ -266,8 +267,8 @@ class BeatportPlugin(BeetsPlugin):
self.register_listener('import_begin', self.setup)
def setup(self, session=None):
c_key = self.config['apikey'].get(unicode)
c_secret = self.config['apisecret'].get(unicode)
c_key = self.config['apikey'].get(six.text_type)
c_secret = self.config['apisecret'].get(six.text_type)
# Get the OAuth token from a file or log in.
try:

View file

@ -35,6 +35,7 @@ from beets.util import bluelet
from beets.library import Item
from beets import dbcore
from beets.mediafile import MediaFile
import six
PROTOCOL_VERSION = '0.13.0'
BUFSIZE = 1024
@ -305,12 +306,12 @@ class BaseServer(object):
playlist, playlistlength, and xfade.
"""
yield (
u'volume: ' + unicode(self.volume),
u'repeat: ' + unicode(int(self.repeat)),
u'random: ' + unicode(int(self.random)),
u'playlist: ' + unicode(self.playlist_version),
u'playlistlength: ' + unicode(len(self.playlist)),
u'xfade: ' + unicode(self.crossfade),
u'volume: ' + six.text_type(self.volume),
u'repeat: ' + six.text_type(int(self.repeat)),
u'random: ' + six.text_type(int(self.random)),
u'playlist: ' + six.text_type(self.playlist_version),
u'playlistlength: ' + six.text_type(len(self.playlist)),
u'xfade: ' + six.text_type(self.crossfade),
)
if self.current_index == -1:
@ -323,8 +324,8 @@ class BaseServer(object):
if self.current_index != -1: # i.e., paused or playing
current_id = self._item_id(self.playlist[self.current_index])
yield u'song: ' + unicode(self.current_index)
yield u'songid: ' + unicode(current_id)
yield u'song: ' + six.text_type(self.current_index)
yield u'songid: ' + six.text_type(current_id)
if self.error:
yield u'error: ' + self.error
@ -468,8 +469,8 @@ class BaseServer(object):
Also a dummy implementation.
"""
for idx, track in enumerate(self.playlist):
yield u'cpos: ' + unicode(idx)
yield u'Id: ' + unicode(track.id)
yield u'cpos: ' + six.text_type(idx)
yield u'Id: ' + six.text_type(track.id)
def cmd_currentsong(self, conn):
"""Sends information about the currently-playing song.
@ -573,7 +574,7 @@ class Connection(object):
lines = [lines]
out = NEWLINE.join(lines) + NEWLINE
log.debug('{}', out[:-1]) # Don't log trailing newline.
if isinstance(out, unicode):
if isinstance(out, six.text_type):
out = out.encode('utf8')
return self.sock.sendall(out)
@ -771,28 +772,28 @@ class Server(BaseServer):
def _item_info(self, item):
info_lines = [
u'file: ' + item.destination(fragment=True),
u'Time: ' + unicode(int(item.length)),
u'Time: ' + six.text_type(int(item.length)),
u'Title: ' + item.title,
u'Artist: ' + item.artist,
u'Album: ' + item.album,
u'Genre: ' + item.genre,
]
track = unicode(item.track)
track = six.text_type(item.track)
if item.tracktotal:
track += u'/' + unicode(item.tracktotal)
track += u'/' + six.text_type(item.tracktotal)
info_lines.append(u'Track: ' + track)
info_lines.append(u'Date: ' + unicode(item.year))
info_lines.append(u'Date: ' + six.text_type(item.year))
try:
pos = self._id_to_index(item.id)
info_lines.append(u'Pos: ' + unicode(pos))
info_lines.append(u'Pos: ' + six.text_type(pos))
except ArgumentNotFoundError:
# Don't include position if not in playlist.
pass
info_lines.append(u'Id: ' + unicode(item.id))
info_lines.append(u'Id: ' + six.text_type(item.id))
return info_lines
@ -917,7 +918,7 @@ class Server(BaseServer):
for item in self._all_items(self._resolve_path(path)):
self.playlist.append(item)
if send_id:
yield u'Id: ' + unicode(item.id)
yield u'Id: ' + six.text_type(item.id)
self.playlist_version += 1
def cmd_add(self, conn, path):
@ -938,11 +939,11 @@ class Server(BaseServer):
if self.current_index > -1:
item = self.playlist[self.current_index]
yield u'bitrate: ' + unicode(item.bitrate / 1000)
yield u'bitrate: ' + six.text_type(item.bitrate / 1000)
# Missing 'audio'.
(pos, total) = self.player.time()
yield u'time: ' + unicode(pos) + u':' + unicode(total)
yield u'time: ' + six.text_type(pos) + u':' + six.text_type(total)
# Also missing 'updating_db'.
@ -957,13 +958,13 @@ class Server(BaseServer):
artists, albums, songs, totaltime = tx.query(statement)[0]
yield (
u'artists: ' + unicode(artists),
u'albums: ' + unicode(albums),
u'songs: ' + unicode(songs),
u'uptime: ' + unicode(int(time.time() - self.startup_time)),
u'artists: ' + six.text_type(artists),
u'albums: ' + six.text_type(albums),
u'songs: ' + six.text_type(songs),
u'uptime: ' + six.text_type(int(time.time() - self.startup_time)),
u'playtime: ' + u'0', # Missing.
u'db_playtime: ' + unicode(int(totaltime)),
u'db_update: ' + unicode(int(self.updated_time)),
u'db_playtime: ' + six.text_type(int(totaltime)),
u'db_update: ' + six.text_type(int(self.updated_time)),
)
# Searching.
@ -1059,7 +1060,7 @@ class Server(BaseServer):
rows = tx.query(statement, subvals)
for row in rows:
yield show_tag_canon + u': ' + unicode(row[0])
yield show_tag_canon + u': ' + six.text_type(row[0])
def cmd_count(self, conn, tag, value):
"""Returns the number and total time of songs matching the
@ -1071,8 +1072,8 @@ class Server(BaseServer):
for item in self.lib.items(dbcore.query.MatchQuery(key, value)):
songs += 1
playtime += item.length
yield u'songs: ' + unicode(songs)
yield u'playtime: ' + unicode(int(playtime))
yield u'songs: ' + six.text_type(songs)
yield u'playtime: ' + six.text_type(int(playtime))
# "Outputs." Just a dummy implementation because we don't control
# any outputs.
@ -1180,11 +1181,12 @@ class BPDPlugin(BeetsPlugin):
)
def func(lib, opts, args):
host = args.pop(0) if args else self.config['host'].get(unicode)
host = self.config['host'].get(six.text_type)
host = args.pop(0) if args else host
port = args.pop(0) if args else self.config['port'].get(int)
if args:
raise beets.ui.UserError(u'too many arguments')
password = self.config['password'].get(unicode)
password = self.config['password'].get(six.text_type)
volume = self.config['volume'].get(int)
debug = opts.debug or False
self.start_bpd(lib, host, int(port), password, volume, debug)

View file

@ -19,6 +19,7 @@ music player.
from __future__ import division, absolute_import, print_function
import six
import sys
import time
from six.moves import _thread
@ -128,7 +129,7 @@ class GstPlayer(object):
path.
"""
self.player.set_state(Gst.State.NULL)
if isinstance(path, unicode):
if isinstance(path, six.text_type):
path = path.encode('utf8')
uri = 'file://' + urllib.parse.quote(path)
self.player.set_property("uri", uri)

View file

@ -26,6 +26,7 @@ from beets.util import confit
from beets.autotag import hooks
import acoustid
from collections import defaultdict
import six
API_KEY = '1vOwZtEn'
SCORE_THRESH = 0.5
@ -181,7 +182,7 @@ class AcoustidPlugin(plugins.BeetsPlugin):
def submit_cmd_func(lib, opts, args):
try:
apikey = config['acoustid']['apikey'].get(unicode)
apikey = config['acoustid']['apikey'].get(six.text_type)
except confit.NotFoundError:
raise ui.UserError(u'no Acoustid user API key provided')
submit_items(self._log, apikey, lib.items(ui.decargs(args)))

View file

@ -29,6 +29,7 @@ from beets.plugins import BeetsPlugin
from beets.util.confit import ConfigTypeError
from beets import art
from beets.util.artresizer import ArtResizer
import six
_fs_lock = threading.Lock()
_temp_files = [] # Keep track of temporary transcoded files for deletion.
@ -55,7 +56,7 @@ def get_format(fmt=None):
"""Return the command template and the extension from the config.
"""
if not fmt:
fmt = config['convert']['format'].get(unicode).lower()
fmt = config['convert']['format'].get(six.text_type).lower()
fmt = ALIASES.get(fmt, fmt)
try:
@ -74,14 +75,14 @@ def get_format(fmt=None):
# Convenience and backwards-compatibility shortcuts.
keys = config['convert'].keys()
if 'command' in keys:
command = config['convert']['command'].get(unicode)
command = config['convert']['command'].get(six.text_type)
elif 'opts' in keys:
# Undocumented option for backwards compatibility with < 1.3.1.
command = u'ffmpeg -i $source -y {0} $dest'.format(
config['convert']['opts'].get(unicode)
config['convert']['opts'].get(six.text_type)
)
if 'extension' in keys:
extension = config['convert']['extension'].get(unicode)
extension = config['convert']['extension'].get(six.text_type)
return (command.encode('utf8'), extension.encode('utf8'))
@ -389,7 +390,7 @@ class ConvertPlugin(BeetsPlugin):
path_formats = ui.get_path_formats()
if not opts.format:
opts.format = self.config['format'].get(unicode).lower()
opts.format = self.config['format'].get(six.text_type).lower()
pretend = opts.pretend if opts.pretend is not None else \
self.config['pretend'].get(bool)
@ -422,7 +423,7 @@ class ConvertPlugin(BeetsPlugin):
"""Transcode a file automatically after it is imported into the
library.
"""
fmt = self.config['format'].get(unicode).lower()
fmt = self.config['format'].get(six.text_type).lower()
if should_transcode(item, fmt):
command, ext = get_format()

View file

@ -34,6 +34,7 @@ import time
import json
import socket
import os
import six
# Silence spurious INFO log lines generated by urllib3.
@ -66,8 +67,8 @@ class DiscogsPlugin(BeetsPlugin):
def setup(self, session=None):
"""Create the `discogs_client` field. Authenticate if necessary.
"""
c_key = self.config['apikey'].get(unicode)
c_secret = self.config['apisecret'].get(unicode)
c_key = self.config['apikey'].get(six.text_type)
c_secret = self.config['apisecret'].get(six.text_type)
# Get the OAuth token from a file or log in.
try:
@ -225,7 +226,7 @@ class DiscogsPlugin(BeetsPlugin):
result.data['formats'][0].get('descriptions', [])) or None
va = result.data['artists'][0]['name'].lower() == 'various'
if va:
artist = config['va_name'].get(unicode)
artist = config['va_name'].get(six.text_type)
year = result.data['year']
label = result.data['labels'][0]['name']
mediums = len(set(t.medium for t in tracks))

View file

@ -23,6 +23,7 @@ from beets.plugins import BeetsPlugin
from beets.ui import decargs, print_, vararg_callback, Subcommand, UserError
from beets.util import command_output, displayable_path, subprocess
from beets.library import Item, Album
import six
PLUGIN = 'duplicates'
@ -264,7 +265,7 @@ class DuplicatesPlugin(BeetsPlugin):
# between a bytes object and the empty Unicode
# string ''.
return v is not None and \
(v != '' if isinstance(v, unicode) else True)
(v != '' if isinstance(v, six.text_type) else True)
fields = kind.all_keys()
key = lambda x: sum(1 for f in fields if truthy(getattr(x, f)))
else:

View file

@ -27,6 +27,7 @@ import subprocess
import yaml
from tempfile import NamedTemporaryFile
import os
import six
# These "safe" types can avoid the format/parse cycle that most fields go
@ -82,7 +83,7 @@ def load(s):
# Convert all keys to strings. They started out as strings,
# but the user may have inadvertently messed this up.
out.append({unicode(k): v for k, v in d.items()})
out.append({six.text_type(k): v for k, v in d.items()})
except yaml.YAMLError as e:
raise ParseError(u'invalid YAML: {}'.format(e))
@ -141,7 +142,7 @@ def apply_(obj, data):
else:
# Either the field was stringified originally or the user changed
# it from a safe type to an unsafe one. Parse it as a string.
obj.set_parse(key, unicode(value))
obj.set_parse(key, six.text_type(value))
class EditPlugin(plugins.BeetsPlugin):

View file

@ -32,6 +32,7 @@ from beets import config
from beets.util.artresizer import ArtResizer
from beets.util import confit
from beets.util import syspath, bytestring_path
import six
try:
import itunes
@ -696,7 +697,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
confit.String(pattern=self.PAT_PERCENT)]))
self.margin_px = None
self.margin_percent = None
if type(self.enforce_ratio) is unicode:
if type(self.enforce_ratio) is six.text_type:
if self.enforce_ratio[-1] == u'%':
self.margin_percent = float(self.enforce_ratio[:-1]) / 100
elif self.enforce_ratio[-2:] == u'px':

View file

@ -22,6 +22,7 @@ from beets import plugins
from beets.util import displayable_path
import os
import re
import six
# Filename field extraction patterns.
@ -132,7 +133,7 @@ def apply_matches(d):
# Apply the title and track.
for item in d:
if bad_title(item.title):
item.title = unicode(d[item][title_field])
item.title = six.text_type(d[item][title_field])
if 'track' in d[item] and item.track == 0:
item.track = int(d[item]['track'])

View file

@ -22,6 +22,7 @@ import re
from beets import plugins
from beets import ui
from beets.util import displayable_path
import six
def split_on_feat(artist):
@ -137,7 +138,7 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
# Only update the title if it does not already contain a featured
# artist and if we do not drop featuring information.
if not drop_feat and not contains_feat(item.title):
feat_format = self.config['format'].get(unicode)
feat_format = self.config['format'].get(six.text_type)
new_format = feat_format.format(feat_part)
new_title = u"{0} {1}".format(item.title, new_format)
self._log.info(u'title: {0} -> {1}', item.title, new_title)

View file

@ -21,6 +21,7 @@ import subprocess
from beets.plugins import BeetsPlugin
from beets.ui import _arg_encoding
from beets.util import shlex_split
import six
class CodingFormatter(string.Formatter):
@ -79,8 +80,8 @@ class HookPlugin(BeetsPlugin):
for hook_index in range(len(hooks)):
hook = self.config['hooks'][hook_index]
hook_event = hook['event'].get(unicode)
hook_command = hook['command'].get(unicode)
hook_event = hook['event'].get(six.text_type)
hook_command = hook['command'].get(six.text_type)
self.create_and_register_hook(hook_event, hook_command)

View file

@ -14,6 +14,7 @@
# included in all copies or substantial portions of the Software.
from __future__ import division, absolute_import, print_function
import six
"""Write paths of imported files in various formats to ease later import in a
music player. Also allow printing the new file locations to stdout in case
@ -119,7 +120,7 @@ class ImportFeedsPlugin(BeetsPlugin):
if 'm3u' in formats:
m3u_basename = bytestring_path(
self.config['m3u_name'].get(unicode))
self.config['m3u_name'].get(six.text_type))
m3u_path = os.path.join(feedsdir, m3u_basename)
_write_m3u(m3u_path, paths)

View file

@ -22,6 +22,7 @@ import itertools
from beets.plugins import BeetsPlugin
from beets import config
import six
FUNC_NAME = u'__INLINE_FUNC__'
@ -32,7 +33,7 @@ class InlineError(Exception):
def __init__(self, code, exc):
super(InlineError, self).__init__(
(u"error in inline path field code:\n"
u"%s\n%s: %s") % (code, type(exc).__name__, unicode(exc))
u"%s\n%s: %s") % (code, type(exc).__name__, six.text_type(exc))
)
@ -64,14 +65,14 @@ class InlinePlugin(BeetsPlugin):
for key, view in itertools.chain(config['item_fields'].items(),
config['pathfields'].items()):
self._log.debug(u'adding item field {0}', key)
func = self.compile_inline(view.get(unicode), False)
func = self.compile_inline(view.get(six.text_type), False)
if func is not None:
self.template_fields[key] = func
# Album fields.
for key, view in config['album_fields'].items():
self._log.debug(u'adding album field {0}', key)
func = self.compile_inline(view.get(unicode), True)
func = self.compile_inline(view.get(six.text_type), True)
if func is not None:
self.album_template_fields[key] = func

View file

@ -23,6 +23,7 @@ import subprocess
from beets import ui
from beets import util
from beets.plugins import BeetsPlugin
import six
class KeyFinderPlugin(BeetsPlugin):
@ -52,7 +53,7 @@ class KeyFinderPlugin(BeetsPlugin):
def find_key(self, items, write=False):
overwrite = self.config['overwrite'].get(bool)
bin = util.bytestring_path(self.config['bin'].get(unicode))
bin = util.bytestring_path(self.config['bin'].get(six.text_type))
for item in items:
if item['initial_key'] and not overwrite:

View file

@ -14,6 +14,7 @@
# included in all copies or substantial portions of the Software.
from __future__ import division, absolute_import, print_function
import six
"""Gets genres for imported music based on Last.fm tags.
@ -71,7 +72,7 @@ def flatten_tree(elem, path, branches):
for sub in elem:
flatten_tree(sub, path, branches)
else:
branches.append(path + [unicode(elem)])
branches.append(path + [six.text_type(elem)])
def find_parents(candidate, branches):
@ -186,7 +187,7 @@ class LastGenrePlugin(plugins.BeetsPlugin):
# the original tags list
tags = [x.title() for x in tags if self._is_allowed(x)]
return self.config['separator'].get(unicode).join(
return self.config['separator'].get(six.text_type).join(
tags[:self.config['count'].get(int)]
)
@ -221,7 +222,8 @@ class LastGenrePlugin(plugins.BeetsPlugin):
if any(not s for s in args):
return None
key = u'{0}.{1}'.format(entity, u'-'.join(unicode(a) for a in args))
key = u'{0}.{1}'.format(entity,
u'-'.join(six.text_type(a) for a in args))
if key in self._genre_cache:
return self._genre_cache[key]
else:
@ -297,7 +299,7 @@ class LastGenrePlugin(plugins.BeetsPlugin):
result = None
if isinstance(obj, library.Item):
result = self.fetch_artist_genre(obj)
elif obj.albumartist != config['va_name'].get(unicode):
elif obj.albumartist != config['va_name'].get(six.text_type):
result = self.fetch_album_artist_genre(obj)
else:
# For "Various Artists", pick the most popular track genre.

View file

@ -23,6 +23,7 @@ from beets import dbcore
from beets import config
from beets import plugins
from beets.dbcore import types
import six
API_URL = 'http://ws.audioscrobbler.com/2.0/'
@ -111,7 +112,7 @@ class CustomUser(pylast.User):
def import_lastfm(lib, log):
user = config['lastfm']['user'].get(unicode)
user = config['lastfm']['user'].get(six.text_type)
per_page = config['lastimport']['per_page'].get(int)
if not user:

View file

@ -27,6 +27,7 @@ import unicodedata
import warnings
from six.moves.html_parser import HTMLParseError
from six.moves import urllib
import six
try:
from bs4 import SoupStrainer, BeautifulSoup
@ -177,7 +178,7 @@ class Backend(object):
@staticmethod
def _encode(s):
"""Encode the string for inclusion in a URL"""
if isinstance(s, unicode):
if isinstance(s, six.text_type):
for char, repl in URL_CHARACTERS.items():
s = s.replace(char, repl)
s = s.encode('utf8', 'ignore')
@ -250,7 +251,7 @@ class Genius(Backend):
"""Fetch lyrics from Genius via genius-api."""
def __init__(self, config, log):
super(Genius, self).__init__(config, log)
self.api_key = config['genius_api_key'].get(unicode)
self.api_key = config['genius_api_key'].get(six.text_type)
self.headers = {'Authorization': "Bearer %s" % self.api_key}
def search_genius(self, artist, title):
@ -461,8 +462,8 @@ class Google(Backend):
"""Fetch lyrics from Google search results."""
def __init__(self, config, log):
super(Google, self).__init__(config, log)
self.api_key = config['google_API_key'].get(unicode)
self.engine_id = config['google_engine_ID'].get(unicode)
self.api_key = config['google_API_key'].get(six.text_type)
self.engine_id = config['google_engine_ID'].get(six.text_type)
def is_lyrics(self, text, artist=None):
"""Determine whether the text seems to be valid lyrics.
@ -503,7 +504,7 @@ class Google(Backend):
try:
text = unicodedata.normalize('NFKD', text).encode('ascii',
'ignore')
text = unicode(re.sub('[-\s]+', ' ', text.decode('utf-8')))
text = six.text_type(re.sub('[-\s]+', ' ', text.decode('utf-8')))
except UnicodeDecodeError:
self._log.exception(u"Failing to normalize '{0}'", text)
return text

View file

@ -22,6 +22,7 @@ from beets import config
import musicbrainzngs
import re
import six
SUBMISSION_CHUNK_SIZE = 200
UUID_REGEX = r'^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$'
@ -57,8 +58,8 @@ class MusicBrainzCollectionPlugin(BeetsPlugin):
super(MusicBrainzCollectionPlugin, self).__init__()
config['musicbrainz']['pass'].redact = True
musicbrainzngs.auth(
config['musicbrainz']['user'].get(unicode),
config['musicbrainz']['pass'].get(unicode),
config['musicbrainz']['user'].get(six.text_type),
config['musicbrainz']['pass'].get(six.text_type),
)
self.config.add({'auto': False})
if self.config['auto']:

View file

@ -27,6 +27,7 @@ from beets import plugins
from beets import library
from beets.util import displayable_path
from beets.dbcore import types
import six
# If we lose the connection, how many times do we want to retry and how
# much time should we wait between retries?
@ -49,7 +50,7 @@ def is_url(path):
# see http://www.tarmack.eu/code/mpdunicode.py for the general idea
class MPDClient(mpd.MPDClient):
def _write_command(self, command, args=[]):
args = [unicode(arg).encode('utf-8') for arg in args]
args = [six.text_type(arg).encode('utf-8') for arg in args]
super(MPDClient, self)._write_command(command, args)
def _read_line(self):
@ -64,14 +65,14 @@ class MPDClientWrapper(object):
self._log = log
self.music_directory = (
mpd_config['music_directory'].get(unicode))
mpd_config['music_directory'].get(six.text_type))
self.client = MPDClient()
def connect(self):
"""Connect to the MPD.
"""
host = mpd_config['host'].get(unicode)
host = mpd_config['host'].get(six.text_type)
port = mpd_config['port'].get(int)
if host[0] in ['/', '~']:
@ -83,7 +84,7 @@ class MPDClientWrapper(object):
except socket.error as e:
raise ui.UserError(u'could not connect to MPD: {0}'.format(e))
password = mpd_config['password'].get(unicode)
password = mpd_config['password'].get(six.text_type)
if password:
try:
self.client.password(password)

View file

@ -27,6 +27,7 @@ from beets.plugins import BeetsPlugin
import os
import socket
from beets import config
import six
# No need to introduce a dependency on an MPD library for such a
@ -86,9 +87,9 @@ class MPDUpdatePlugin(BeetsPlugin):
def update(self, lib):
self.update_mpd(
config['mpd']['host'].get(unicode),
config['mpd']['host'].get(six.text_type),
config['mpd']['port'].get(int),
config['mpd']['password'].get(unicode),
config['mpd']['password'].get(six.text_type),
)
def update_mpd(self, host='localhost', port=6600, password=None):
@ -101,7 +102,7 @@ class MPDUpdatePlugin(BeetsPlugin):
s = BufferedSocket(host, port)
except socket.error as e:
self._log.warning(u'MPD connection failed: {0}',
unicode(e.strerror))
six.text_type(e.strerror))
return
resp = s.readline()

View file

@ -27,6 +27,7 @@ from beets import logging
from beets import ui
from beets.plugins import BeetsPlugin
from beets.util import syspath, command_output, displayable_path
import six
# Utilities.
@ -102,7 +103,7 @@ class Bs1770gainBackend(Backend):
'method': 'replaygain',
})
self.chunk_at = config['chunk_at'].as_number()
self.method = b'--' + bytes(config['method'].get(unicode))
self.method = b'--' + bytes(config['method'].get(six.text_type))
cmd = b'bs1770gain'
try:
@ -256,7 +257,7 @@ class CommandBackend(Backend):
'noclip': True,
})
self.command = config["command"].get(unicode)
self.command = config["command"].get(six.text_type)
if self.command:
# Explicit executable path.
@ -809,7 +810,7 @@ class ReplayGainPlugin(BeetsPlugin):
})
self.overwrite = self.config['overwrite'].get(bool)
backend_name = self.config['backend'].get(unicode)
backend_name = self.config['backend'].get(six.text_type)
if backend_name not in self.backends:
raise ui.UserError(
u"Selected ReplayGain backend {0} is not supported. "

View file

@ -24,6 +24,7 @@ from collections import defaultdict
from beets.plugins import BeetsPlugin
from beets import ui
from beets import library
import six
def rewriter(field, rules):
@ -51,7 +52,7 @@ class RewritePlugin(BeetsPlugin):
# Gather all the rewrite rules for each field.
rules = defaultdict(list)
for key, view in self.config.items():
value = view.get(unicode)
value = view.get(six.text_type)
try:
fieldname, pattern = key.split(None, 1)
except ValueError:

View file

@ -9,6 +9,7 @@ from beets.plugins import BeetsPlugin
from beets.ui import decargs
from beets import ui
from requests.exceptions import HTTPError
import six
class SpotifyPlugin(BeetsPlugin):
@ -170,6 +171,6 @@ class SpotifyPlugin(BeetsPlugin):
else:
for item in ids:
print(unicode.encode(self.open_url + item))
print(six.text_type.encode(self.open_url + item))
else:
self._log.warn(u'No Spotify tracks found from beets query')

View file

@ -19,6 +19,7 @@ from __future__ import division, absolute_import, print_function
import re
from beets.plugins import BeetsPlugin
import six
__author__ = 'baobab@heresiarch.info'
__version__ = '1.1'
@ -81,7 +82,7 @@ class ThePlugin(BeetsPlugin):
if self.config['strip']:
return r
else:
fmt = self.config['format'].get(unicode)
fmt = self.config['format'].get(six.text_type)
return fmt.format(r, t.strip()).strip()
else:
return u''

View file

@ -35,6 +35,7 @@ from beets.plugins import BeetsPlugin
from beets.ui import Subcommand, decargs
from beets import util
from beets.util.artresizer import ArtResizer, get_im_version, get_pil_version
import six
BASE_DIR = os.path.join(BaseDirectory.xdg_cache_home, "thumbnails")
@ -169,8 +170,9 @@ class ThumbnailsPlugin(BeetsPlugin):
"""Write required metadata to the thumbnail
See http://standards.freedesktop.org/thumbnail-spec/latest/x142.html
"""
mtime = os.stat(album.artpath).st_mtime
metadata = {"Thumb::URI": self.get_uri(album.artpath),
"Thumb::MTime": unicode(os.stat(album.artpath).st_mtime)}
"Thumb::MTime": six.text_type(mtime)}
try:
self.write_metadata(image_path, metadata)
except Exception:

View file

@ -25,6 +25,7 @@ from flask import g
from werkzeug.routing import BaseConverter, PathConverter
import os
import json
import six
# Utilities.
@ -321,7 +322,7 @@ class WebPlugin(BeetsPlugin):
}
CORS(app)
# Start the web application.
app.run(host=self.config['host'].get(unicode),
app.run(host=self.config['host'].get(six.text_type),
port=self.config['port'].get(int),
debug=opts.debug, threaded=True)
cmd.func = func

View file

@ -22,6 +22,7 @@ from beets.plugins import BeetsPlugin
from beets.mediafile import MediaFile
from beets.importer import action
from beets.util import confit
import six
__author__ = 'baobab@heresiarch.info'
__version__ = '0.10'
@ -113,7 +114,7 @@ class ZeroPlugin(BeetsPlugin):
if patterns is True:
return True
for p in patterns:
if re.search(p, unicode(field), flags=re.IGNORECASE):
if re.search(p, six.text_type(field), flags=re.IGNORECASE):
return True
return False

View file

@ -56,6 +56,7 @@ from beets import util
# TODO Move AutotagMock here
from test import _common
import six
class LogCapture(logging.Handler):
@ -65,7 +66,7 @@ class LogCapture(logging.Handler):
self.messages = []
def emit(self, record):
self.messages.append(unicode(record.msg))
self.messages.append(six.text_type(record.msg))
@contextmanager
@ -121,7 +122,7 @@ def has_program(cmd, args=['--version']):
"""
full_cmd = [cmd] + args
for i, elem in enumerate(full_cmd):
if isinstance(elem, unicode):
if isinstance(elem, six.text_type):
full_cmd[i] = elem.encode(_arg_encoding())
try:
with open(os.devnull, 'wb') as devnull:

View file

@ -14,6 +14,7 @@ from beets import config
from test._common import unittest
from test.helper import TestHelper, capture_stdout
from beets.library import Library
import six
class ConfigCommandTest(unittest.TestCase, TestHelper):
@ -114,8 +115,8 @@ class ConfigCommandTest(unittest.TestCase, TestHelper):
execlp.side_effect = OSError('here is problem')
self.run_command('config', '-e')
self.assertIn('Could not edit configuration',
unicode(user_error.exception))
self.assertIn('here is problem', unicode(user_error.exception))
six.text_type(user_error.exception))
self.assertIn('here is problem', six.text_type(user_error.exception))
def test_edit_invalid_config_file(self):
self.lib = Library(':memory:')

View file

@ -26,6 +26,7 @@ from test import _common
from test._common import unittest
from beets import dbcore
from tempfile import mkstemp
import six
# Fixture: concrete database and model classes. For migration tests, we
@ -350,7 +351,7 @@ class FormatTest(unittest.TestCase):
model = TestModel1()
model.other_field = u'caf\xe9'.encode('utf8')
value = model.formatted().get('other_field')
self.assertTrue(isinstance(value, unicode))
self.assertTrue(isinstance(value, six.text_type))
self.assertEqual(value, u'caf\xe9')
def test_format_unset_field(self):

View file

@ -38,6 +38,7 @@ from beets import config
from beets.mediafile import MediaFile
from beets.util import syspath, bytestring_path
from test.helper import TestHelper
import six
# Shortcut to path normalization.
np = util.normpath
@ -964,7 +965,7 @@ class PathStringTest(_common.TestCase):
def test_sanitize_path_returns_unicode(self):
path = u'b\xe1r?'
new_path = util.sanitize_path(path)
self.assertTrue(isinstance(new_path, unicode))
self.assertTrue(isinstance(new_path, six.text_type))
def test_unicode_artpath_becomes_bytestring(self):
alb = self.lib.add_album([self.i])
@ -1051,7 +1052,7 @@ class TemplateTest(_common.LibTestCase):
album.tagada = u'togodo'
self.assertEqual(u"{0}".format(album), u"foö bar")
self.assertEqual(u"{0:$tagada}".format(album), u"togodo")
self.assertEqual(unicode(album), u"foö bar")
self.assertEqual(six.text_type(album), u"foö bar")
self.assertEqual(bytes(album), b"fo\xc3\xb6 bar")
config['format_item'] = 'bar $foo'
@ -1174,7 +1175,8 @@ class LibraryFieldTypesTest(unittest.TestCase):
t = beets.library.DateType()
# format
time_local = time.strftime(beets.config['time_format'].get(unicode),
time_format = beets.config['time_format'].get(six.text_type)
time_local = time.strftime(time_format,
time.localtime(123456789))
self.assertEqual(time_local, t.format(123456789))
# parse

View file

@ -29,6 +29,7 @@ from beetsplug import lyrics
from beets.library import Item
from beets.util import confit, bytestring_path
from beets import logging
import six
log = logging.getLogger('beets.test_lyrics')
raw_backend = lyrics.Backend({}, log)
@ -354,7 +355,7 @@ class LyricsGooglePluginTest(unittest.TestCase):
present in the title."""
from bs4 import SoupStrainer, BeautifulSoup
s = self.source
url = unicode(s['url'] + s['path'])
url = six.text_type(s['url'] + s['path'])
html = raw_backend.fetch_url(url)
soup = BeautifulSoup(html, "html.parser",
parse_only=SoupStrainer('title'))

View file

@ -33,6 +33,7 @@ from beets.mediafile import MediaFile, MediaField, Image, \
from beets.library import Item
from beets.plugins import BeetsPlugin
from beets.util import bytestring_path
import six
class ArtTestMixin(object):
@ -353,13 +354,13 @@ class ExtendedFieldTestMixin(object):
with self.assertRaises(ValueError) as cm:
MediaFile.add_field('somekey', True)
self.assertIn(u'must be an instance of MediaField',
unicode(cm.exception))
six.text_type(cm.exception))
def test_overwrite_property(self):
with self.assertRaises(ValueError) as cm:
MediaFile.add_field('artist', MediaField())
self.assertIn(u'property "artist" already exists',
unicode(cm.exception))
six.text_type(cm.exception))
class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin,

View file

@ -26,6 +26,7 @@ from test.helper import TestHelper
from beets.util import bytestring_path
import beets.mediafile
import six
_sc = beets.mediafile._safe_cast
@ -127,8 +128,8 @@ class InvalidValueToleranceTest(unittest.TestCase):
self.assertAlmostEqual(_sc(float, u'-1.234'), -1.234)
def test_safe_cast_special_chars_to_unicode(self):
us = _sc(unicode, 'caf\xc3\xa9')
self.assertTrue(isinstance(us, unicode))
us = _sc(six.text_type, 'caf\xc3\xa9')
self.assertTrue(isinstance(us, six.text_type))
self.assertTrue(us.startswith(u'caf'))
def test_safe_cast_float_with_no_numbers(self):
@ -350,7 +351,7 @@ class ID3v23Test(unittest.TestCase, TestHelper):
mf.year = 2013
mf.save()
frame = mf.mgfile['TDRC']
self.assertTrue('2013' in unicode(frame))
self.assertTrue('2013' in six.text_type(frame))
self.assertTrue('TYER' not in mf.mgfile)
finally:
self._delete_test()
@ -361,7 +362,7 @@ class ID3v23Test(unittest.TestCase, TestHelper):
mf.year = 2013
mf.save()
frame = mf.mgfile['TYER']
self.assertTrue('2013' in unicode(frame))
self.assertTrue('2013' in six.text_type(frame))
self.assertTrue('TDRC' not in mf.mgfile)
finally:
self._delete_test()

View file

@ -33,6 +33,7 @@ from beets.dbcore.query import (NoneQuery, ParsingError,
from beets.library import Library, Item
from beets import util
import platform
import six
class TestHelper(helper.TestHelper):
@ -301,12 +302,13 @@ class GetTest(DummyDataTestCase):
def test_invalid_query(self):
with self.assertRaises(InvalidQueryArgumentTypeError) as raised:
dbcore.query.NumericQuery('year', u'199a')
self.assertIn(u'not an int', unicode(raised.exception))
self.assertIn(u'not an int', six.text_type(raised.exception))
with self.assertRaises(InvalidQueryArgumentTypeError) as raised:
dbcore.query.RegexpQuery('year', u'199(')
self.assertIn(u'not a regular expression', unicode(raised.exception))
self.assertIn(u'unbalanced parenthesis', unicode(raised.exception))
exception = six.text_type(raised.exception)
self.assertIn(u'not a regular expression', exception)
self.assertIn(u'unbalanced parenthesis', exception)
self.assertIsInstance(raised.exception, ParsingError)

View file

@ -21,6 +21,7 @@ import warnings
from test._common import unittest
from beets.util import functemplate
import six
def _normexpr(expr):
@ -227,7 +228,7 @@ class EvalTest(unittest.TestCase):
u'baz': u'BaR',
}
functions = {
u'lower': unicode.lower,
u'lower': six.text_type.lower,
u'len': len,
}
return functemplate.Template(template).substitute(values, functions)

View file

@ -39,6 +39,7 @@ from beets import config
from beets import plugins
from beets.util.confit import ConfigError
from beets import util
import six
class ListTest(unittest.TestCase):
@ -1257,15 +1258,15 @@ class CommonOptionsParserTest(unittest.TestCase, TestHelper):
config['format_item'].set('$foo')
self.assertEqual(parser.parse_args([]), ({'path': None}, []))
self.assertEqual(config['format_item'].get(unicode), u'$foo')
self.assertEqual(config['format_item'].get(six.text_type), u'$foo')
self.assertEqual(parser.parse_args([u'-p']),
({'path': True, 'format': u'$path'}, []))
self.assertEqual(parser.parse_args(['--path']),
({'path': True, 'format': u'$path'}, []))
self.assertEqual(config['format_item'].get(unicode), u'$path')
self.assertEqual(config['format_album'].get(unicode), u'$path')
self.assertEqual(config['format_item'].get(six.text_type), u'$path')
self.assertEqual(config['format_album'].get(six.text_type), u'$path')
def test_format_option(self):
parser = ui.CommonOptionsParser()
@ -1274,15 +1275,15 @@ class CommonOptionsParserTest(unittest.TestCase, TestHelper):
config['format_item'].set('$foo')
self.assertEqual(parser.parse_args([]), ({'format': None}, []))
self.assertEqual(config['format_item'].get(unicode), u'$foo')
self.assertEqual(config['format_item'].get(six.text_type), u'$foo')
self.assertEqual(parser.parse_args([u'-f', u'$bar']),
({'format': u'$bar'}, []))
self.assertEqual(parser.parse_args([u'--format', u'$baz']),
({'format': u'$baz'}, []))
self.assertEqual(config['format_item'].get(unicode), u'$baz')
self.assertEqual(config['format_album'].get(unicode), u'$baz')
self.assertEqual(config['format_item'].get(six.text_type), u'$baz')
self.assertEqual(config['format_album'].get(six.text_type), u'$baz')
def test_format_option_with_target(self):
with self.assertRaises(KeyError):
@ -1297,8 +1298,8 @@ class CommonOptionsParserTest(unittest.TestCase, TestHelper):
self.assertEqual(parser.parse_args([u'-f', u'$bar']),
({'format': u'$bar'}, []))
self.assertEqual(config['format_item'].get(unicode), u'$bar')
self.assertEqual(config['format_album'].get(unicode), u'$album')
self.assertEqual(config['format_item'].get(six.text_type), u'$bar')
self.assertEqual(config['format_album'].get(six.text_type), u'$album')
def test_format_option_with_album(self):
parser = ui.CommonOptionsParser()
@ -1309,15 +1310,15 @@ class CommonOptionsParserTest(unittest.TestCase, TestHelper):
config['format_album'].set('$album')
parser.parse_args([u'-f', u'$bar'])
self.assertEqual(config['format_item'].get(unicode), u'$bar')
self.assertEqual(config['format_album'].get(unicode), u'$album')
self.assertEqual(config['format_item'].get(six.text_type), u'$bar')
self.assertEqual(config['format_album'].get(six.text_type), u'$album')
parser.parse_args([u'-a', u'-f', u'$foo'])
self.assertEqual(config['format_item'].get(unicode), u'$bar')
self.assertEqual(config['format_album'].get(unicode), u'$foo')
self.assertEqual(config['format_item'].get(six.text_type), u'$bar')
self.assertEqual(config['format_album'].get(six.text_type), u'$foo')
parser.parse_args([u'-f', u'$foo2', u'-a'])
self.assertEqual(config['format_album'].get(unicode), u'$foo2')
self.assertEqual(config['format_album'].get(six.text_type), u'$foo2')
def test_add_all_common_options(self):
parser = ui.CommonOptionsParser()

View file

@ -26,6 +26,7 @@ from test import test_importer
from beets.ui.commands import TerminalImportSession
from beets import importer
from beets import config
import six
class TestTerminalImportSession(TerminalImportSession):
@ -69,7 +70,7 @@ class TestTerminalImportSession(TerminalImportSession):
self.io.addinput(u'S')
elif isinstance(choice, int):
self.io.addinput(u'M')
self.io.addinput(unicode(choice))
self.io.addinput(six.text_type(choice))
self._add_choice_input()
else:
raise Exception(u'Unknown choice %s' % choice)

View file

@ -26,6 +26,7 @@ from mock import patch, Mock
from test._common import unittest
from test import _common
from beets import util
import six
class UtilTest(unittest.TestCase):
@ -122,7 +123,7 @@ class PathConversionTest(_common.TestCase):
with _common.platform_windows():
path = os.path.join(u'a', u'b', u'c')
outpath = util.syspath(path)
self.assertTrue(isinstance(outpath, unicode))
self.assertTrue(isinstance(outpath, six.text_type))
self.assertTrue(outpath.startswith(u'\\\\?\\'))
def test_syspath_windows_format_unc_path(self):
@ -131,7 +132,7 @@ class PathConversionTest(_common.TestCase):
path = '\\\\server\\share\\file.mp3'
with _common.platform_windows():
outpath = util.syspath(path)
self.assertTrue(isinstance(outpath, unicode))
self.assertTrue(isinstance(outpath, six.text_type))
self.assertEqual(outpath, u'\\\\?\\UNC\\server\\share\\file.mp3')
def test_syspath_posix_unchanged(self):