use print_function __future__ import

All code should now use Python 3-style "print"s.
This commit is contained in:
Adrian Sampson 2012-05-13 21:08:27 -07:00
parent f6b37d2c8c
commit 429af42e14
15 changed files with 77 additions and 64 deletions

View file

@ -12,16 +12,13 @@
# The above copyright notice and this permission notice shall be # The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software. # included in all copies or substantial portions of the Software.
"""Finding album art for tagged albums.""" """Finding album art for tagged albums.
"""
import urllib import urllib
import sys
import logging import logging
import os import os
import re import re
from beets.autotag.mb import album_for_id
IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg'] IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg']
COVER_NAMES = ['cover', 'front', 'art', 'album', 'folder'] COVER_NAMES = ['cover', 'front', 'art', 'album', 'folder']
@ -134,19 +131,3 @@ def art_for_album(album, path):
else: else:
log.debug('No ASIN available: no art found.') log.debug('No ASIN available: no art found.')
return None return None
# Smoke test.
if __name__ == '__main__':
aid = sys.argv[1]
album = album_for_id(aid)
if not album:
print 'album not found'
else:
fn = art_for_album(album, None)
if fn:
print fn
print len(open(fn).read())/1024
else:
print 'no art found'

View file

@ -15,6 +15,8 @@
"""Provides the basic, interface-agnostic workflow for importing and """Provides the basic, interface-agnostic workflow for importing and
autotagging music files. autotagging music files.
""" """
from __future__ import print_function
import os import os
import logging import logging
import pickle import pickle
@ -55,7 +57,7 @@ def tag_log(logfile, status, path):
reflect the reason the album couldn't be tagged. reflect the reason the album couldn't be tagged.
""" """
if logfile: if logfile:
print >>logfile, '%s %s' % (status, path) print('{0} {1}'.format(status, path), file=logfile)
logfile.flush() logfile.flush()
def log_choice(config, task, duplicate=False): def log_choice(config, task, duplicate=False):

View file

@ -16,6 +16,8 @@
interface. To invoke the CLI, just call beets.ui.main(). The actual interface. To invoke the CLI, just call beets.ui.main(). The actual
CLI commands are implemented in the ui.commands module. CLI commands are implemented in the ui.commands module.
""" """
from __future__ import print_function
import os import os
import locale import locale
import optparse import optparse
@ -106,7 +108,7 @@ def print_(*strings):
txt = u'' txt = u''
if isinstance(txt, unicode): if isinstance(txt, unicode):
txt = txt.encode(_encoding(), 'replace') txt = txt.encode(_encoding(), 'replace')
print txt print(txt)
def input_options(options, require=False, prompt=None, fallback_prompt=None, def input_options(options, require=False, prompt=None, fallback_prompt=None,
numrange=None, default=None, color=False, max_width=72): numrange=None, default=None, color=False, max_width=72):

View file

@ -15,6 +15,8 @@
"""This module provides the default commands for beets' command-line """This module provides the default commands for beets' command-line
interface. interface.
""" """
from __future__ import print_function
import logging import logging
import sys import sys
import os import os
@ -87,10 +89,10 @@ def _showdiff(field, oldval, newval, color):
fields_cmd = ui.Subcommand('fields', fields_cmd = ui.Subcommand('fields',
help='show fields available for queries and format strings') help='show fields available for queries and format strings')
def fields_func(lib, config, opts, args): def fields_func(lib, config, opts, args):
print "Available item fields:" print("Available item fields:")
print " " + "\n ".join([key for key in library.ITEM_KEYS]) print(" " + "\n ".join([key for key in library.ITEM_KEYS]))
print "\nAvailable album fields:" print("\nAvailable album fields:")
print " " + "\n ".join([key for key in library.ALBUM_KEYS]) print(" " + "\n ".join([key for key in library.ALBUM_KEYS]))
fields_cmd.func = fields_func fields_cmd.func = fields_func
default_commands.append(fields_cmd) default_commands.append(fields_cmd)
@ -651,7 +653,7 @@ def import_files(lib, paths, copy, move, write, autot, logpath, art, threaded,
except IOError: except IOError:
raise ui.UserError(u"could not open log file for writing: %s" % raise ui.UserError(u"could not open log file for writing: %s" %
displayable_path(logpath)) displayable_path(logpath))
print >>logfile, 'import started', time.asctime() print('import started', time.asctime(), file=logfile)
else: else:
logfile = None logfile = None
@ -690,7 +692,7 @@ def import_files(lib, paths, copy, move, write, autot, logpath, art, threaded,
finally: finally:
# If we were logging, close the file. # If we were logging, close the file.
if logfile: if logfile:
print >>logfile, '' print('', file=logfile)
logfile.close() logfile.close()
# Emit event. # Emit event.
@ -1035,16 +1037,16 @@ default_commands.append(stats_cmd)
# version: Show current beets version. # version: Show current beets version.
def show_version(lib, config, opts, args): def show_version(lib, config, opts, args):
print 'beets version %s' % beets.__version__ print_('beets version %s' % beets.__version__)
# Show plugins. # Show plugins.
names = [] names = []
for plugin in plugins.find_plugins(): for plugin in plugins.find_plugins():
modname = plugin.__module__ modname = plugin.__module__
names.append(modname.split('.')[-1]) names.append(modname.split('.')[-1])
if names: if names:
print 'plugins:', ', '.join(names) print_('plugins:', ', '.join(names))
else: else:
print 'no plugins loaded' print_('no plugins loaded')
version_cmd = ui.Subcommand('version', version_cmd = ui.Subcommand('version',
help='output version information') help='output version information')
version_cmd.func = show_version version_cmd.func = show_version

View file

@ -120,7 +120,7 @@ class Enumerated(object):
>>> class Garment(Enumerated): >>> class Garment(Enumerated):
... values = 'hat glove belt poncho lederhosen suspenders' ... values = 'hat glove belt poncho lederhosen suspenders'
... def wear(self): ... def wear(self):
... print 'now wearing a ' + self.name ... print('now wearing a ' + self.name)
... ...
>>> Garment.poncho.wear() >>> Garment.poncho.wear()
now wearing a poncho now wearing a poncho

View file

@ -25,6 +25,8 @@ library: unknown symbols are left intact.
This is sort of like a tiny, horrible degeneration of a real templating This is sort of like a tiny, horrible degeneration of a real templating
engine like Jinja2 or Mustache. engine like Jinja2 or Mustache.
""" """
from __future__ import print_function
import re import re
import ast import ast
import dis import dis
@ -548,9 +550,9 @@ if __name__ == '__main__':
interp_time = timeit.timeit('_tmpl.interpret(_vars, _funcs)', interp_time = timeit.timeit('_tmpl.interpret(_vars, _funcs)',
'from __main__ import _tmpl, _vars, _funcs', 'from __main__ import _tmpl, _vars, _funcs',
number=10000) number=10000)
print interp_time print(interp_time)
comp_time = timeit.timeit('_tmpl.substitute(_vars, _funcs)', comp_time = timeit.timeit('_tmpl.substitute(_vars, _funcs)',
'from __main__ import _tmpl, _vars, _funcs', 'from __main__ import _tmpl, _vars, _funcs',
number=10000) number=10000)
print comp_time print(comp_time)
print 'Speedup:', interp_time / comp_time print('Speedup:', interp_time / comp_time)

View file

@ -30,6 +30,8 @@ up a bottleneck stage by dividing its work among multiple threads.
To do so, pass an iterable of coroutines to the Pipeline constructor To do so, pass an iterable of coroutines to the Pipeline constructor
in place of any single coroutine. in place of any single coroutine.
""" """
from __future__ import print_function
import Queue import Queue
from threading import Thread, Lock from threading import Thread, Lock
import sys import sys
@ -392,20 +394,20 @@ if __name__ == '__main__':
# in parallel. # in parallel.
def produce(): def produce():
for i in range(5): for i in range(5):
print 'generating %i' % i print('generating %i' % i)
time.sleep(1) time.sleep(1)
yield i yield i
def work(): def work():
num = yield num = yield
while True: while True:
print 'processing %i' % num print('processing %i' % num)
time.sleep(2) time.sleep(2)
num = yield num*2 num = yield num*2
def consume(): def consume():
while True: while True:
num = yield num = yield
time.sleep(1) time.sleep(1)
print 'received %i' % num print('received %i' % num)
ts_start = time.time() ts_start = time.time()
Pipeline([produce(), work(), consume()]).run_sequential() Pipeline([produce(), work(), consume()]).run_sequential()
ts_seq = time.time() ts_seq = time.time()
@ -413,21 +415,21 @@ if __name__ == '__main__':
ts_par = time.time() ts_par = time.time()
Pipeline([produce(), (work(), work()), consume()]).run_parallel() Pipeline([produce(), (work(), work()), consume()]).run_parallel()
ts_end = time.time() ts_end = time.time()
print 'Sequential time:', ts_seq - ts_start print('Sequential time:', ts_seq - ts_start)
print 'Parallel time:', ts_par - ts_seq print('Parallel time:', ts_par - ts_seq)
print 'Multiply-parallel time:', ts_end - ts_par print('Multiply-parallel time:', ts_end - ts_par)
print print()
# Test a pipeline that raises an exception. # Test a pipeline that raises an exception.
def exc_produce(): def exc_produce():
for i in range(10): for i in range(10):
print 'generating %i' % i print('generating %i' % i)
time.sleep(1) time.sleep(1)
yield i yield i
def exc_work(): def exc_work():
num = yield num = yield
while True: while True:
print 'processing %i' % num print('processing %i' % num)
time.sleep(3) time.sleep(3)
if num == 3: if num == 3:
raise Exception() raise Exception()
@ -437,5 +439,5 @@ if __name__ == '__main__':
num = yield num = yield
#if num == 4: #if num == 4:
# raise Exception() # raise Exception()
print 'received %i' % num print('received %i' % num)
Pipeline([exc_produce(), exc_work(), exc_consume()]).run_parallel(1) Pipeline([exc_produce(), exc_work(), exc_consume()]).run_parallel(1)

View file

@ -12,6 +12,10 @@
# The above copyright notice and this permission notice shall be # The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software. # included in all copies or substantial portions of the Software.
"""Some simple performance benchmarks for beets.
"""
from __future__ import print_function
from beets.plugins import BeetsPlugin from beets.plugins import BeetsPlugin
from beets import ui from beets import ui
from beets import vfs from beets import vfs
@ -34,7 +38,7 @@ def benchmark(lib, prof):
'paths.withaunique.prof') 'paths.withaunique.prof')
else: else:
interval = timeit.timeit(_build_tree, number=1) interval = timeit.timeit(_build_tree, number=1)
print 'With %aunique:', interval print('With %aunique:', interval)
# And with %aunique replaceed with a "cheap" no-op function. # And with %aunique replaceed with a "cheap" no-op function.
lib.path_formats = [ lib.path_formats = [
@ -46,7 +50,7 @@ def benchmark(lib, prof):
'paths.withoutaunique.prof') 'paths.withoutaunique.prof')
else: else:
interval = timeit.timeit(_build_tree, number=1) interval = timeit.timeit(_build_tree, number=1)
print 'Without %aunique:', interval print('Without %aunique:', interval)
class BenchmarkPlugin(BeetsPlugin): class BenchmarkPlugin(BeetsPlugin):
"""A plugin for performing some simple performance benchmarks. """A plugin for performing some simple performance benchmarks.

View file

@ -16,6 +16,7 @@
Beets library. Attempts to implement a compatible protocol to allow Beets library. Attempts to implement a compatible protocol to allow
use of the wide range of MPD clients. use of the wide range of MPD clients.
""" """
from __future__ import print_function
import bluelet import bluelet
import re import re
@ -536,7 +537,7 @@ class BaseServer(object):
"""Memory profiling for debugging.""" """Memory profiling for debugging."""
from guppy import hpy from guppy import hpy
heap = hpy().heap() heap = hpy().heap()
print heap print(heap)
class Connection(object): class Connection(object):
"""A connection between a client and the server. Handles input and """A connection between a client and the server. Handles input and
@ -789,9 +790,9 @@ class Server(BaseServer):
""" """
# Path is ignored. Also, the real MPD does this asynchronously; # Path is ignored. Also, the real MPD does this asynchronously;
# this is done inline. # this is done inline.
print 'Building directory tree...' print('Building directory tree...')
self.tree = vfs.libtree(self.lib) self.tree = vfs.libtree(self.lib)
print '... done.' print('... done.')
self.updated_time = time.time() self.updated_time = time.time()

View file

@ -15,6 +15,7 @@
"""A wrapper for the GStreamer Python bindings that exposes a simple """A wrapper for the GStreamer Python bindings that exposes a simple
music player. music player.
""" """
from __future__ import print_function
import gst import gst
import sys import sys
@ -83,7 +84,7 @@ class GstPlayer(object):
# error # error
self.player.set_state(gst.STATE_NULL) self.player.set_state(gst.STATE_NULL)
err, debug = message.parse_error() err, debug = message.parse_error()
print "Error: " + str(err) print("Error: " + str(err))
self.playing = False self.playing = False
def _set_volume(self, volume): def _set_volume(self, volume):

View file

@ -14,6 +14,8 @@
"""Fetches, embeds, and displays lyrics. """Fetches, embeds, and displays lyrics.
""" """
from __future__ import print_function
import urllib import urllib
import re import re
import logging import logging
@ -83,7 +85,7 @@ def extract_text(html, starttag):
parts.append(html[pos:match.start()]) parts.append(html[pos:match.start()])
break break
else: else:
print 'no closing tag found!' print('no closing tag found!')
return return
lyrics = ''.join(parts) lyrics = ''.join(parts)

View file

@ -12,6 +12,8 @@
#ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF #ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import print_function
from beets.plugins import BeetsPlugin from beets.plugins import BeetsPlugin
from beets.ui import Subcommand from beets.ui import Subcommand
from beets import ui from beets import ui
@ -44,9 +46,9 @@ def update_collection(lib, config, opts, args):
albums = [a.mb_albumid for a in lib.albums() if a.mb_albumid] albums = [a.mb_albumid for a in lib.albums() if a.mb_albumid]
# Submit to MusicBrainz. # Submit to MusicBrainz.
print 'Updating MusicBrainz collection {0}...'.format(collection_id) print('Updating MusicBrainz collection {0}...'.format(collection_id))
submit_albums(collection_id, albums) submit_albums(collection_id, albums)
print '...MusicBrainz collection updated.' print('...MusicBrainz collection updated.')
update_mb_collection_cmd = Subcommand('mbupdate', update_mb_collection_cmd = Subcommand('mbupdate',
help='Update MusicBrainz collection') help='Update MusicBrainz collection')

View file

@ -20,6 +20,7 @@ Put something like the following in your .beetsconfig to configure:
port = 6600 port = 6600
password = seekrit password = seekrit
""" """
from __future__ import print_function
from beets.plugins import BeetsPlugin from beets.plugins import BeetsPlugin
from beets import ui from beets import ui
@ -60,20 +61,20 @@ def update_mpd(host='localhost', port=6600, password=None):
"""Sends the "update" command to the MPD server indicated, """Sends the "update" command to the MPD server indicated,
possibly authenticating with a password first. possibly authenticating with a password first.
""" """
print 'Updating MPD database...' print('Updating MPD database...')
s = BufferedSocket() s = BufferedSocket()
s.connect(host, port) s.connect(host, port)
resp = s.readline() resp = s.readline()
if 'OK MPD' not in resp: if 'OK MPD' not in resp:
print 'MPD connection failed:', repr(resp) print('MPD connection failed:', repr(resp))
return return
if password: if password:
s.send('password "%s"\n' % password) s.send('password "%s"\n' % password)
resp = s.readline() resp = s.readline()
if 'OK' not in resp: if 'OK' not in resp:
print 'Authentication failed:', repr(resp) print('Authentication failed:', repr(resp))
s.send('close\n') s.send('close\n')
s.close() s.close()
return return
@ -81,11 +82,11 @@ def update_mpd(host='localhost', port=6600, password=None):
s.send('update\n') s.send('update\n')
resp = s.readline() resp = s.readline()
if 'updating_db' not in resp: if 'updating_db' not in resp:
print 'Update failed:', repr(resp) print('Update failed:', repr(resp))
s.send('close\n') s.send('close\n')
s.close() s.close()
print '... updated.' print('... updated.')
options = { options = {
'host': 'localhost', 'host': 'localhost',

View file

@ -12,14 +12,13 @@
# The above copyright notice and this permission notice shall be # The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software. # included in all copies or substantial portions of the Software.
"""Get a random song or album from the library.
"""
from beets.plugins import BeetsPlugin from beets.plugins import BeetsPlugin
from beets.ui import Subcommand, decargs, print_ from beets.ui import Subcommand, decargs, print_
from beets.util.functemplate import Template from beets.util.functemplate import Template
import random import random
"""Get a random song or album from the library.
"""
def random_item(lib, config, opts, args): def random_item(lib, config, opts, args):
query = decargs(args) query = decargs(args)
path = opts.path path = opts.path

View file

@ -16,6 +16,7 @@
""" """
import os import os
import shutil import shutil
import StringIO
import _common import _common
from _common import unittest from _common import unittest
@ -827,6 +828,17 @@ class ArtFetchTest(unittest.TestCase, _common.ExtraAsserts):
art.art_for_album = lambda a, b: artdest art.art_for_album = lambda a, b: artdest
self._fetch_art(True) self._fetch_art(True)
class TagLogTest(unittest.TestCase):
def test_tag_log_line(self):
sio = StringIO.StringIO()
importer.tag_log(sio, 'status', 'path')
assert 'status path' in sio.getvalue()
def test_tag_log_unicode(self):
sio = StringIO.StringIO()
importer.tag_log(sio, 'status', 'caf\xc3\xa9')
assert 'status caf' in sio.getvalue()
def suite(): def suite():
return unittest.TestLoader().loadTestsFromName(__name__) return unittest.TestLoader().loadTestsFromName(__name__)