summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCalum Lind <calumlind+deluge@gmail.com>2017-02-22 13:40:17 +0000
committerCalum Lind <calumlind+deluge@gmail.com>2017-02-23 00:35:43 +0000
commitb2db96e4df86ef38d79b9c304d527e793597260c (patch)
treea123a1fdcb73eb66f6aca87bf3ccf6048e80a69c
parent52a85cb91cc3f536941133bfff1ef26f6855e151 (diff)
downloaddeluge-b2db96e4df86ef38d79b9c304d527e793597260c.tar.gz
deluge-b2db96e4df86ef38d79b9c304d527e793597260c.tar.bz2
deluge-b2db96e4df86ef38d79b9c304d527e793597260c.zip
[Py2to3] Refactor out usage of unicode and basestring
- Python 3 renames `unicode` type to `str` and introduces `bytes` type. - Python 2.7 has `bytes` but is only an alias for `str` so restricted to comparisons but helps keep compatibility. - To test for unicode string on Py2 and Py3 uses the "''.__class__" type. - Remove usage of utf8encode and just encode, problems with bytes being passed in code will be picked up faster. - Where possible refactor out isinstance for try..except duck-typing.
-rw-r--r--deluge/common.py57
-rw-r--r--deluge/component.py8
-rw-r--r--deluge/config.py19
-rw-r--r--deluge/core/core.py2
-rw-r--r--deluge/core/filtermanager.py2
-rw-r--r--deluge/core/torrent.py20
-rw-r--r--deluge/core/torrentmanager.py11
-rw-r--r--deluge/metafile.py50
-rw-r--r--deluge/plugins/AutoAdd/deluge/plugins/autoadd/core.py4
-rw-r--r--deluge/plugins/Blocklist/deluge/plugins/blocklist/common.py6
-rw-r--r--deluge/plugins/Execute/deluge/plugins/execute/core.py13
-rw-r--r--deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py2
-rw-r--r--deluge/tests/test_config.py2
-rw-r--r--deluge/tests/test_plugin_metadata.py2
-rw-r--r--deluge/ui/console/cmdline/commands/info.py3
-rw-r--r--deluge/ui/console/main.py10
-rw-r--r--deluge/ui/console/modes/cmdline.py5
-rw-r--r--deluge/ui/console/modes/torrentlist/torrentactions.py13
-rw-r--r--deluge/ui/console/modes/torrentlist/torrentview.py15
-rw-r--r--deluge/ui/console/utils/colors.py13
-rw-r--r--deluge/ui/console/utils/format_utils.py18
-rw-r--r--deluge/ui/console/widgets/inputpane.py2
-rw-r--r--deluge/ui/gtkui/listview.py3
-rw-r--r--deluge/ui/gtkui/preferences.py16
-rw-r--r--deluge/ui/translations_util.py1
-rw-r--r--deluge/ui/web/auth.py10
-rw-r--r--deluge/ui/web/json_api.py2
27 files changed, 115 insertions, 194 deletions
diff --git a/deluge/common.py b/deluge/common.py
index 048d48142..b8f7ff528 100644
--- a/deluge/common.py
+++ b/deluge/common.py
@@ -241,7 +241,7 @@ def show_file(path, timestamp=None):
timestamp = int(time.time())
startup_id = '%s_%u_%s-dbus_TIME%d' % (os.path.basename(sys.argv[0]), os.getpid(), os.uname()[1], timestamp)
if DBUS_FILEMAN:
- paths = [urlparse.urljoin('file:', urllib.pathname2url(utf8_encoded(path)))]
+ paths = [urlparse.urljoin('file:', urllib.pathname2url(path))]
DBUS_FILEMAN.ShowItems(paths, startup_id, dbus_interface='org.freedesktop.FileManager1')
else:
env = os.environ.copy()
@@ -518,12 +518,16 @@ def parse_human_size(size):
if len(tokens) == 1:
return int(tokens[0])
# Otherwise we expect to find two tokens: A number and a unit.
- if len(tokens) == 2 and isinstance(tokens[1], basestring):
- normalized_unit = tokens[1].lower()
- # Try to match the first letter of the unit.
- for unit in size_units:
- if normalized_unit.startswith(unit['prefix'].lower()):
- return int(tokens[0] * unit['divider'])
+ if len(tokens) == 2:
+ try:
+ normalized_unit = tokens[1].lower()
+ except AttributeError:
+ pass
+ else:
+ # Try to match the first letter of the unit.
+ for unit in size_units:
+ if normalized_unit.startswith(unit['prefix'].lower()):
+ return int(tokens[0] * unit['divider'])
# We failed to parse the size specification.
msg = 'Failed to parse size! (input %r was tokenized as %r)'
raise InvalidSize(msg % (size, tokens))
@@ -801,7 +805,7 @@ def decode_bytes(byte_str, encoding='utf8'):
"""
if not byte_str:
return ''
- elif isinstance(byte_str, unicode):
+ elif not isinstance(byte_str, bytes):
return byte_str
encodings = [lambda: ('utf8', 'strict'),
@@ -820,25 +824,6 @@ def decode_bytes(byte_str, encoding='utf8'):
return ''
-def utf8_encoded(s, encoding='utf8'):
- """
- Returns a utf8 encoded string of s
-
- :param s: (unicode) string to (re-)encode
- :type s: basestring
- :param encoding: the encoding to use in the decoding
- :type encoding: string
- :returns: a utf8 encoded string of s
- :rtype: str
-
- """
- if isinstance(s, str):
- s = decode_bytes(s, encoding).encode('utf8')
- elif isinstance(s, unicode):
- s = s.encode('utf8')
- return s
-
-
def utf8_encode_structure(data):
"""Recursively convert all unicode keys and values in a data structure to utf8.
@@ -851,14 +836,16 @@ def utf8_encode_structure(data):
input type: The data with unicode keys and values converted to utf8.
"""
- if isinstance(data, unicode):
- return data.encode('utf8')
- elif isinstance(data, (list, tuple)):
+ if isinstance(data, (list, tuple)):
return type(data)(map(utf8_encode_structure, data))
elif isinstance(data, dict):
return dict(map(utf8_encode_structure, data.items()))
- else:
- return data
+ elif not isinstance(data, bytes):
+ try:
+ return data.encode('utf8')
+ except AttributeError:
+ pass
+ return data
@functools.total_ordering
@@ -993,7 +980,11 @@ def set_env_variable(name, value):
http://sourceforge.net/p/gramps/code/HEAD/tree/branches/maintenance/gramps32/src/TransUtils.py
'''
# Update Python's copy of the environment variables
- os.environ[name] = value
+ try:
+ os.environ[name] = value
+ except UnicodeEncodeError:
+ # Python 2
+ os.environ[name] = value.encode('utf8')
if windows_check():
from ctypes import windll
diff --git a/deluge/component.py b/deluge/component.py
index 274c86df9..476311410 100644
--- a/deluge/component.py
+++ b/deluge/component.py
@@ -307,7 +307,7 @@ class ComponentRegistry(object):
# Start all the components if names is empty
if not names:
names = self.components.keys()
- elif isinstance(names, basestring):
+ elif not isinstance(names, (list, tuple)):
names = [names]
def on_depends_started(result, name):
@@ -341,7 +341,7 @@ class ComponentRegistry(object):
"""
if not names:
names = self.components.keys()
- elif isinstance(names, basestring):
+ elif not isinstance(names, (list, tuple)):
names = [names]
def on_dependents_stopped(result, name):
@@ -379,7 +379,7 @@ class ComponentRegistry(object):
"""
if not names:
names = self.components.keys()
- elif isinstance(names, basestring):
+ elif not isinstance(names, (list, tuple)):
names = [names]
deferreds = []
@@ -405,7 +405,7 @@ class ComponentRegistry(object):
"""
if not names:
names = self.components.keys()
- elif isinstance(names, basestring):
+ elif not isinstance(names, (list, tuple)):
names = [names]
deferreds = []
diff --git a/deluge/config.py b/deluge/config.py
index a5bfa01c0..ae867989a 100644
--- a/deluge/config.py
+++ b/deluge/config.py
@@ -47,7 +47,7 @@ import logging
import os
import shutil
-from deluge.common import decode_bytes, get_default_config_dir, utf8_encoded
+from deluge.common import get_default_config_dir
log = logging.getLogger(__name__)
callLater = None # Necessary for the config tests
@@ -172,8 +172,10 @@ class Config(object):
5
"""
- if isinstance(value, basestring):
- value = utf8_encoded(value)
+ try:
+ value = value.encode('utf8')
+ except AttributeError:
+ pass
if key not in self.__config:
self.__config[key] = value
@@ -188,10 +190,7 @@ class Config(object):
self.__config[key], type(None)) and not isinstance(self.__config[key], type(value)):
try:
oldtype = type(self.__config[key])
- if isinstance(self.__config[key], unicode):
- value = oldtype(value, 'utf8')
- else:
- value = oldtype(value)
+ value = oldtype(value)
except ValueError:
log.warning('Value Type "%s" invalid for key: %s', type(value), key)
raise
@@ -244,9 +243,9 @@ class Config(object):
5
"""
- if isinstance(self.__config[key], basestring):
- return decode_bytes(self.__config[key])
- else:
+ try:
+ return self.__config[key].decode('utf8')
+ except AttributeError:
return self.__config[key]
def get(self, key, default=None):
diff --git a/deluge/core/core.py b/deluge/core/core.py
index f0d2eb523..52cacafdf 100644
--- a/deluge/core/core.py
+++ b/deluge/core/core.py
@@ -710,7 +710,7 @@ class Core(component.Component):
if 'owner' in options and not self.core.authmanager.has_account(options['owner']):
raise DelugeError('Username "%s" is not known.' % options['owner'])
- if isinstance(torrent_ids, basestring):
+ if not isinstance(torrent_ids, (list, tuple)):
torrent_ids = [torrent_ids]
for torrent_id in torrent_ids:
diff --git a/deluge/core/filtermanager.py b/deluge/core/filtermanager.py
index e5c7b936d..7919b0c5e 100644
--- a/deluge/core/filtermanager.py
+++ b/deluge/core/filtermanager.py
@@ -133,7 +133,7 @@ class FilterManager(component.Component):
# Sanitize input: filter-value must be a list of strings
for key, value in filter_dict.items():
- if isinstance(value, basestring):
+ if not isinstance(value, (list, tuple)):
filter_dict[key] = [value]
# Optimized filter for id
diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py
index f4b9261fe..66250317e 100644
--- a/deluge/core/torrent.py
+++ b/deluge/core/torrent.py
@@ -26,7 +26,7 @@ from twisted.internet.defer import Deferred, DeferredList
import deluge.component as component
from deluge._libtorrent import lt
-from deluge.common import decode_bytes, utf8_encoded
+from deluge.common import decode_bytes
from deluge.configmanager import ConfigManager, get_config_dir
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.decorators import deprecated
@@ -1126,12 +1126,12 @@ class Torrent(object):
return False
try:
- # libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
+ # lt needs utf8 byte-string. Otherwise if wstrings enabled, unicode string.
# Keyword argument flags=2 (dont_replace) dont overwrite target files but delete source.
try:
- self.handle.move_storage(dest, flags=2)
+ self.handle.move_storage(dest.encode('utf8'), flags=2)
except TypeError:
- self.handle.move_storage(utf8_encoded(dest), flags=2)
+ self.handle.move_storage(dest, flags=2)
except RuntimeError as ex:
log.error('Error calling libtorrent move_storage: %s', ex)
return False
@@ -1252,13 +1252,13 @@ class Torrent(object):
filenames (list): A list of (index, filename) pairs.
"""
for index, filename in filenames:
- # Make sure filename is a unicode object
+ # Make sure filename is a sanitized unicode string.
filename = sanitize_filepath(decode_bytes(filename))
- # libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
+ # lt needs utf8 byte-string. Otherwise if wstrings enabled, unicode string.
try:
- self.handle.rename_file(index, filename)
+ self.handle.rename_file(index, filename.encode('utf8'))
except TypeError:
- self.handle.rename_file(index, utf8_encoded(filename))
+ self.handle.rename_file(index, filename)
def rename_folder(self, folder, new_folder):
"""Renames a folder within a torrent.
@@ -1292,9 +1292,9 @@ class Torrent(object):
)
new_path = _file['path'].replace(folder, new_folder, 1)
try:
- self.handle.rename_file(_file['index'], new_path)
+ self.handle.rename_file(_file['index'], new_path.encode('utf8'))
except TypeError:
- self.handle.rename_file(_file['index'], utf8_encoded(new_path))
+ self.handle.rename_file(_file['index'], new_path)
def on_folder_rename_complete(dummy_result, torrent, folder, new_folder):
"""Folder rename complete"""
diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py
index 81d075117..2233bc4d6 100644
--- a/deluge/core/torrentmanager.py
+++ b/deluge/core/torrentmanager.py
@@ -24,7 +24,7 @@ from twisted.internet.task import LoopingCall
import deluge.component as component
from deluge._libtorrent import lt
-from deluge.common import decode_bytes, get_magnet_info, utf8_encoded
+from deluge.common import decode_bytes, get_magnet_info
from deluge.configmanager import ConfigManager, get_config_dir
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.core.torrent import Torrent, TorrentOptions, sanitize_filepath
@@ -332,10 +332,9 @@ class TorrentManager(component.Component):
add_torrent_params['name'] = name
torrent_id = str(torrent_info.info_hash())
elif magnet:
- magnet = utf8_encoded(magnet)
magnet_info = get_magnet_info(magnet)
if magnet_info:
- add_torrent_params['url'] = magnet
+ add_torrent_params['url'] = magnet.encode('utf8')
add_torrent_params['name'] = magnet_info['name']
torrent_id = magnet_info['info_hash']
else:
@@ -362,9 +361,9 @@ class TorrentManager(component.Component):
if log.isEnabledFor(logging.DEBUG):
log.debug('renaming file index %s to %s', index, fname)
try:
- torrent_info.rename_file(index, fname)
+ torrent_info.rename_file(index, fname.encode('utf8'))
except TypeError:
- torrent_info.rename_file(index, utf8_encoded(fname))
+ torrent_info.rename_file(index, fname)
add_torrent_params['ti'] = torrent_info
if not options['owner']:
@@ -376,7 +375,7 @@ class TorrentManager(component.Component):
log.debug('options: %s', options)
# Fill in the rest of the add_torrent_params dictionary.
- add_torrent_params['save_path'] = utf8_encoded(options['download_location'])
+ add_torrent_params['save_path'] = options['download_location'].encode('utf8')
if options['name']:
add_torrent_params['name'] = options['name']
if options['pre_allocate_storage']:
diff --git a/deluge/metafile.py b/deluge/metafile.py
index 412e62788..1362d5b37 100644
--- a/deluge/metafile.py
+++ b/deluge/metafile.py
@@ -15,7 +15,6 @@ from __future__ import division, unicode_literals
import logging
import os.path
-import sys
import time
from hashlib import sha1 as sha
@@ -40,22 +39,6 @@ def gmtime():
return time.mktime(time.gmtime())
-def get_filesystem_encoding():
- return sys.getfilesystemencoding()
-
-
-def decode_from_filesystem(path):
- encoding = get_filesystem_encoding()
- if encoding is None:
- assert isinstance(path, unicode), 'Path should be unicode not %s' % type(path)
- decoded_path = path
- else:
- assert isinstance(path, str), 'Path should be str not %s' % type(path)
- decoded_path = path.decode(encoding)
-
- return decoded_path
-
-
def dummy(*v):
pass
@@ -140,23 +123,6 @@ def calcsize(path):
def makeinfo(path, piece_length, progress, name=None, content_type=None, private=False):
# HEREDAVE. If path is directory, how do we assign content type?
- def to_utf8(name):
- if isinstance(name, unicode):
- u = name
- else:
- try:
- u = decode_from_filesystem(name)
- except Exception:
- raise Exception('Could not convert file/directory name %r to '
- 'Unicode. Either the assumed filesystem '
- 'encoding "%s" is wrong or the filename contains '
- 'illegal bytes.' % (name, get_filesystem_encoding()))
-
- if u.translate(noncharacter_translate) != u:
- raise Exception('File/directory name "%s" contains reserved '
- 'unicode values that do not correspond to '
- 'characters.' % name)
- return u.encode('utf-8')
path = os.path.abspath(path)
piece_count = 0
if os.path.isdir(path):
@@ -178,7 +144,7 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private
for p, f in subs:
pos = 0
size = os.path.getsize(f)
- p2 = [to_utf8(n) for n in p]
+ p2 = [n.encode('utf8') for n in p]
if content_type:
fs.append({'length': size, 'path': p2,
'content_type': content_type}) # HEREDAVE. bad for batch!
@@ -204,16 +170,13 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private
piece_count += 1
progress(piece_count, num_pieces)
- if name is not None:
- assert isinstance(name, unicode)
- name = to_utf8(name)
- else:
- name = to_utf8(os.path.split(path)[1])
+ if not name:
+ name = os.path.split(path)[1]
return {'pieces': ''.join(pieces),
'piece length': piece_length,
'files': fs,
- 'name': name,
+ 'name': name.encode('utf8'),
'private': private}
else:
size = os.path.getsize(path)
@@ -234,15 +197,16 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private
p = size
progress(piece_count, num_pieces)
h.close()
+ name = os.path.split(path)[1].encode('utf8')
if content_type is not None:
return {'pieces': ''.join(pieces),
'piece length': piece_length, 'length': size,
- 'name': to_utf8(os.path.split(path)[1]),
+ 'name': name,
'content_type': content_type,
'private': private}
return {'pieces': ''.join(pieces),
'piece length': piece_length, 'length': size,
- 'name': to_utf8(os.path.split(path)[1]),
+ 'name': name,
'private': private}
diff --git a/deluge/plugins/AutoAdd/deluge/plugins/autoadd/core.py b/deluge/plugins/AutoAdd/deluge/plugins/autoadd/core.py
index 9bfbbb46b..19fa0f2a2 100644
--- a/deluge/plugins/AutoAdd/deluge/plugins/autoadd/core.py
+++ b/deluge/plugins/AutoAdd/deluge/plugins/autoadd/core.py
@@ -394,8 +394,8 @@ class Core(CorePluginBase):
def _make_unicode(self, options):
opts = {}
for key in options:
- if isinstance(options[key], str):
- options[key] = unicode(options[key], 'utf8')
+ if isinstance(options[key], bytes):
+ options[key] = options[key].decode('utf8')
opts[key] = options[key]
return opts
diff --git a/deluge/plugins/Blocklist/deluge/plugins/blocklist/common.py b/deluge/plugins/Blocklist/deluge/plugins/blocklist/common.py
index 05c45a933..5e0a4989f 100644
--- a/deluge/plugins/Blocklist/deluge/plugins/blocklist/common.py
+++ b/deluge/plugins/Blocklist/deluge/plugins/blocklist/common.py
@@ -145,17 +145,17 @@ class IP(object):
# return IP(q1, q2, q3, q4)
def __lt__(self, other):
- if isinstance(other, basestring):
+ if isinstance(other, ''.__class__):
other = IP.parse(other)
return self.long < other.long
def __gt__(self, other):
- if isinstance(other, basestring):
+ if isinstance(other, ''.__class__):
other = IP.parse(other)
return self.long > other.long
def __eq__(self, other):
- if isinstance(other, basestring):
+ if isinstance(other, ''.__class__):
other = IP.parse(other)
return self.long == other.long
diff --git a/deluge/plugins/Execute/deluge/plugins/execute/core.py b/deluge/plugins/Execute/deluge/plugins/execute/core.py
index 886920d56..5d8ed1591 100644
--- a/deluge/plugins/Execute/deluge/plugins/execute/core.py
+++ b/deluge/plugins/Execute/deluge/plugins/execute/core.py
@@ -17,7 +17,7 @@ import time
from twisted.internet.utils import getProcessOutputAndValue
import deluge.component as component
-from deluge.common import utf8_encoded, windows_check
+from deluge.common import windows_check
from deluge.configmanager import ConfigManager
from deluge.core.rpcserver import export
from deluge.event import DelugeEvent
@@ -85,8 +85,7 @@ class Core(CorePluginBase):
# Get and store the torrent info before it is removed
torrent = component.get('TorrentManager').torrents[torrent_id]
info = torrent.get_status(['name', 'download_location'])
- self.preremoved_cache[torrent_id] = [utf8_encoded(torrent_id), utf8_encoded(info['name']),
- utf8_encoded(info['download_location'])]
+ self.preremoved_cache[torrent_id] = [torrent_id, info['name'], info['download_location']]
def execute_commands(self, torrent_id, event, *arg):
if event == 'added' and arg[0]:
@@ -99,9 +98,8 @@ class Core(CorePluginBase):
info = torrent.get_status(['name', 'download_location'])
# Grab the torrent name and download location
# getProcessOutputAndValue requires args to be str
- torrent_id = utf8_encoded(torrent_id)
- torrent_name = utf8_encoded(info['name'])
- download_location = utf8_encoded(info['download_location'])
+ torrent_name = info['name']
+ download_location = info['download_location']
log.debug('Running commands for %s', event)
@@ -120,7 +118,8 @@ class Core(CorePluginBase):
command = os.path.expandvars(command[EXECUTE_COMMAND])
command = os.path.expanduser(command)
- cmd_args = [torrent_id, torrent_name, download_location]
+ cmd_args = [torrent_id.encode('utf8'), torrent_name.encode('utf8'),
+ download_location.encode('utf8')]
if windows_check():
# Escape ampersand on windows (see #2784)
cmd_args = [cmd_arg.replace('&', '^^^&') for cmd_arg in cmd_args]
diff --git a/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py b/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
index 829bdbd48..7ff0a725b 100644
--- a/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
+++ b/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
@@ -151,7 +151,7 @@ class GtkUiNotifications(CustomNotifications):
'handler was: %s' % result)
def handle_custom_sound_notification(self, result, eventtype):
- if isinstance(result, basestring):
+ if isinstance(result, ''.__class__):
if not result and eventtype in self.config['custom_sounds']:
return defer.maybeDeferred(
self.__play_sound, self.config['custom_sounds'][eventtype])
diff --git a/deluge/tests/test_config.py b/deluge/tests/test_config.py
index 78bfd20b7..6445b305a 100644
--- a/deluge/tests/test_config.py
+++ b/deluge/tests/test_config.py
@@ -47,7 +47,7 @@ class ConfigTestCase(unittest.TestCase):
self.assertEquals(config['unicode'], 'ВИДЕОФИЛЬМЫ')
config['unicode'] = b'foostring'
- self.assertTrue(isinstance(config.get_item('unicode'), unicode))
+ self.assertFalse(isinstance(config.get_item('unicode'), bytes))
config._save_timer.cancel()
diff --git a/deluge/tests/test_plugin_metadata.py b/deluge/tests/test_plugin_metadata.py
index dafa9d635..63bbb9ab5 100644
--- a/deluge/tests/test_plugin_metadata.py
+++ b/deluge/tests/test_plugin_metadata.py
@@ -24,7 +24,7 @@ class PluginManagerBaseTestCase(BaseTestCase):
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
for p in pm.get_available_plugins():
for key, value in pm.get_plugin_info(p).items():
- self.assertTrue(isinstance('%s: %s' % (key, value), basestring))
+ self.assertTrue(isinstance('%s: %s' % (key, value), ''.__class__))
def test_get_plugin_info_invalid_name(self):
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
diff --git a/deluge/ui/console/cmdline/commands/info.py b/deluge/ui/console/cmdline/commands/info.py
index 84838713f..fc80d1aba 100644
--- a/deluge/ui/console/cmdline/commands/info.py
+++ b/deluge/ui/console/cmdline/commands/info.py
@@ -212,9 +212,6 @@ class Command(BaseCommand):
def tlen(string):
return strwidth(format_utils.remove_formatting(string))
- if not isinstance(col_filename, unicode):
- col_filename = unicode(col_filename, 'utf-8')
-
col_all_info = col_size + col_progress + col_priority
# Check how much space we've got left after writing all the info
space_left = cols - tlen(col_all_info)
diff --git a/deluge/ui/console/main.py b/deluge/ui/console/main.py
index cce63d662..7b7904c0a 100644
--- a/deluge/ui/console/main.py
+++ b/deluge/ui/console/main.py
@@ -371,8 +371,7 @@ Please use commands from the command line, e.g.:\n
no matches are found.
"""
- if not isinstance(string, unicode):
- string = unicode(string, self.encoding)
+ deluge.common.decode_bytes(string, self.encoding)
if string == '*' or string == '':
return [tid for tid, name in self.torrents]
@@ -387,8 +386,7 @@ Please use commands from the command line, e.g.:\n
matches = []
for tid, name in self.torrents:
- if not isinstance(name, unicode):
- name = unicode(name, self.encoding)
+ deluge.common.decode_bytes(name, self.encoding)
if getattr(tid, match_func, None)(string) or getattr(name, match_func, None)(string):
matches.append(tid)
return matches
@@ -423,7 +421,7 @@ Please use commands from the command line, e.g.:\n
component.get('CmdLine').add_line(s, False)
self.events.append(s)
else:
- print(colors.strip_colors(deluge.common.utf8_encoded(s)))
+ print(colors.strip_colors(s.encode('utf8')))
def write_event(self, s):
if self.interactive:
@@ -434,7 +432,7 @@ Please use commands from the command line, e.g.:\n
component.get('CmdLine').add_line(s, False)
self.events.append(s)
else:
- print(colors.strip_colors(deluge.common.utf8_encoded(s)))
+ print(colors.strip_colors(s.encode('utf8')))
def _migrate_config_1_to_2(self, config):
"""Create better structure by moving most settings out of dict root
diff --git a/deluge/ui/console/modes/cmdline.py b/deluge/ui/console/modes/cmdline.py
index 0eb134e6c..287791a52 100644
--- a/deluge/ui/console/modes/cmdline.py
+++ b/deluge/ui/console/modes/cmdline.py
@@ -417,10 +417,7 @@ class CmdLine(BaseMode, Commander):
# Write the line
with open(self.history_file[active_file], 'a', encoding='utf8') as _file:
- if isinstance(text, unicode):
- text = text.encode(self.encoding)
- _file.write(text)
- _file.write(os.linesep)
+ _file.write(text + '\n')
# And increment line counter
self._hf_lines[active_file] += 1
diff --git a/deluge/ui/console/modes/torrentlist/torrentactions.py b/deluge/ui/console/modes/torrentlist/torrentactions.py
index d855aaa95..404d2c27d 100644
--- a/deluge/ui/console/modes/torrentlist/torrentactions.py
+++ b/deluge/ui/console/modes/torrentlist/torrentactions.py
@@ -131,17 +131,14 @@ def action_torrent_info(mode=None, torrent_ids=None, **kwargs):
for field in torrent_options:
caption = '{!info!}' + TORRENT_DATA_FIELD[field]['name']
value = options[field]
- field_type = type(value)
- if field_type in [str, unicode]:
- if not isinstance(value, basestring):
- value = str(value)
+ if isinstance(value, ''.__class__):
option_popup.add_text_input(field, caption, value)
- elif field_type == bool:
- choices = (['Yes', 'No'], [True, False], [True, False].index(options[field]))
+ elif isinstance(value, bool):
+ choices = (['Yes', 'No'], [True, False], [True, False].index(value))
option_popup.add_select_input(field, caption, choices[0], choices[1], choices[2])
- elif field_type == float:
+ elif isinstance(value, float):
option_popup.add_float_spin_input(field, caption, value=value, min_val=-1)
- elif field_type == int:
+ elif isinstance(value, int):
option_popup.add_int_spin_input(field, caption, value=value, min_val=-1)
mode.push_popup(option_popup)
diff --git a/deluge/ui/console/modes/torrentlist/torrentview.py b/deluge/ui/console/modes/torrentlist/torrentview.py
index 98b18f1ec..6ef1d7e83 100644
--- a/deluge/ui/console/modes/torrentlist/torrentview.py
+++ b/deluge/ui/console/modes/torrentlist/torrentview.py
@@ -237,18 +237,15 @@ class TorrentView(InputKeyHandler):
# and if it's a string
first_element = state[state.keys()[0]]
if field in first_element:
- is_string = isinstance(first_element[field], basestring)
-
def sort_key(s):
- return state.get(s)[field]
-
- def sort_key2(s):
- return state.get(s)[field].lower()
+ try:
+ # Sort case-insensitively but preserve A>a order.
+ return state.get(s)[field].lower()
+ except AttributeError:
+ # Not a string.
+ return state.get(s)[field]
- # If it's a string, sort case-insensitively but preserve A>a order
to_sort = sorted(to_sort, _queue_sort, sort_key, reverse)
- if is_string:
- to_sort = sorted(to_sort, _queue_sort, sort_key2, reverse)
if field == 'eta':
to_sort = sorted(to_sort, key=lambda s: state.get(s)['eta'] == 0)
diff --git a/deluge/ui/console/utils/colors.py b/deluge/ui/console/utils/colors.py
index 50ec6d40c..17119e71a 100644
--- a/deluge/ui/console/utils/colors.py
+++ b/deluge/ui/console/utils/colors.py
@@ -131,7 +131,7 @@ def strip_colors(line):
return line
-def get_line_length(line, encoding='UTF-8'):
+def get_line_length(line):
"""
Returns the string length without the color formatting.
@@ -139,9 +139,6 @@ def get_line_length(line, encoding='UTF-8'):
if line.count('{!') != line.count('!}'):
raise BadColorString('Number of {! is not equal to number of !}')
- if isinstance(line, unicode):
- line = line.encode(encoding, 'replace')
-
# Remove all the color tags
line = strip_colors(line)
@@ -150,7 +147,7 @@ def get_line_length(line, encoding='UTF-8'):
return len(line)
-def get_line_width(line, encoding='UTF-8'):
+def get_line_width(line):
"""
Get width of string considering double width characters
@@ -158,9 +155,6 @@ def get_line_width(line, encoding='UTF-8'):
if line.count('{!') != line.count('!}'):
raise BadColorString('Number of {! is not equal to number of !}')
- if isinstance(line, unicode):
- line = line.encode(encoding, 'replace')
-
# Remove all the color tags
line = strip_colors(line)
@@ -180,9 +174,6 @@ def parse_color_string(s, encoding='UTF-8'):
if s.count('{!') != s.count('!}'):
raise BadColorString('Number of {! is not equal to number of !}')
- if isinstance(s, unicode):
- s = s.encode(encoding, 'replace')
-
ret = []
last_color_attr = None
# Keep track of where the strings
diff --git a/deluge/ui/console/utils/format_utils.py b/deluge/ui/console/utils/format_utils.py
index f259061d6..ac7fc2539 100644
--- a/deluge/ui/console/utils/format_utils.py
+++ b/deluge/ui/console/utils/format_utils.py
@@ -11,8 +11,7 @@ from __future__ import unicode_literals
import re
from collections import deque
-from unicodedata import normalize as ud_normalize
-from unicodedata import east_asian_width
+from unicodedata import east_asian_width, normalize
import deluge.common
from deluge.ui.common import FILE_PRIORITY
@@ -88,7 +87,7 @@ def trim_string(string, w, have_dbls):
idx = 0
while width < w:
chrs.append(string[idx])
- if east_asian_width(string[idx]) in ['W', 'F']:
+ if east_asian_width(string[idx]) in 'WF':
width += 2
else:
width += 1
@@ -102,14 +101,13 @@ def trim_string(string, w, have_dbls):
def format_column(col, lim):
- dbls = 0
- # Chosen over isinstance(col, unicode) and col.__class__ == unicode
- # for speed - it's ~3 times faster for non-unicode strings and ~1.5
- # for unicode strings.
- if col.__class__ is unicode:
+ try:
# might have some double width chars
- col = ud_normalize('NFC', col)
+ col = normalize('NFC', col)
dbls = sum(east_asian_width(c) in 'WF' for c in col)
+ except TypeError:
+ dbls = 0
+
size = len(col) + dbls
if size >= lim - 1:
return trim_string(col, lim, dbls > 0)
@@ -239,8 +237,6 @@ def strwidth(string):
"""
Measure width of a string considering asian double width characters
"""
- if not isinstance(string, unicode):
- string = unicode(string, 'utf-8')
return sum([1 + (east_asian_width(char) in ['W', 'F']) for char in string])
diff --git a/deluge/ui/console/widgets/inputpane.py b/deluge/ui/console/widgets/inputpane.py
index e76708f21..cf53b48ea 100644
--- a/deluge/ui/console/widgets/inputpane.py
+++ b/deluge/ui/console/widgets/inputpane.py
@@ -299,7 +299,7 @@ class BaseInputPane(InputKeyHandler):
if ipt.default_col != -1:
default_col = int(ipt.default_col)
- if isinstance(ipt.default_col, basestring) and ipt.default_col[0] in ['+', '-']:
+ if isinstance(ipt.default_col, ''.__class__) and ipt.default_col[0] in ['+', '-']:
col += default_col
cursor_offset += default_col
field_width -= default_col # Increase to col must be reflected here
diff --git a/deluge/ui/gtkui/listview.py b/deluge/ui/gtkui/listview.py
index e61162a6f..2b3f7b1e5 100644
--- a/deluge/ui/gtkui/listview.py
+++ b/deluge/ui/gtkui/listview.py
@@ -15,6 +15,7 @@ import gtk
from gobject import SIGNAL_RUN_LAST, TYPE_NONE, signal_new
from gtk.gdk import Event # pylint: disable=ungrouped-imports
+from deluge.common import decode_bytes
from deluge.ui.gtkui.common import load_pickled_state_file, save_pickled_state_file
signal_new('button-press-event', gtk.TreeViewColumn, SIGNAL_RUN_LAST, TYPE_NONE, (Event,))
@@ -320,7 +321,7 @@ class ListView(object):
try:
self.columns[name].column.set_visible(widget.get_active())
except KeyError:
- self.columns[unicode(name)].column.set_visible(widget.get_active())
+ self.columns[decode_bytes(name)].column.set_visible(widget.get_active())
return
def on_treeview_header_right_clicked(self, column, event):
diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py
index ab5954cc7..2e424549c 100644
--- a/deluge/ui/gtkui/preferences.py
+++ b/deluge/ui/gtkui/preferences.py
@@ -401,20 +401,20 @@ class Preferences(component.Component):
# Update the widgets accordingly
for key in core_widgets:
modifier = core_widgets[key][0]
- if isinstance(key, basestring):
+ try:
widget = self.builder.get_object(key)
- else:
+ except TypeError:
widget = key
widget.set_sensitive(self.is_connected)
if self.is_connected:
value = core_widgets[key][1]
- from types import FunctionType
- if isinstance(value, FunctionType):
- value = value()
- elif isinstance(value, basestring):
+ try:
value = self.core_config[value]
+ except KeyError:
+ if callable(value):
+ value = value()
elif modifier:
value = {'active': False, 'not_active': False, 'value': 0, 'text': '', 'path_chooser': ''}[modifier]
@@ -433,9 +433,9 @@ class Preferences(component.Component):
if self.is_connected:
for key in core_widgets:
- if isinstance(key, basestring):
+ try:
widget = self.builder.get_object(key)
- else:
+ except TypeError:
widget = key
# Update the toggle status if necessary
self.on_toggle(widget)
diff --git a/deluge/ui/translations_util.py b/deluge/ui/translations_util.py
index 6803d55a2..656cabd1c 100644
--- a/deluge/ui/translations_util.py
+++ b/deluge/ui/translations_util.py
@@ -70,7 +70,6 @@ def set_language(lang):
:param lang: the language, e.g. "en", "de" or "en_GB"
:type lang: str
"""
- lang = str(lang)
# Necessary to set these environment variables for GtkBuilder
deluge.common.set_env_variable('LANGUAGE', lang) # Windows/Linux
deluge.common.set_env_variable('LANG', lang) # For OSX
diff --git a/deluge/ui/web/auth.py b/deluge/ui/web/auth.py
index be862a11d..d5a439d42 100644
--- a/deluge/ui/web/auth.py
+++ b/deluge/ui/web/auth.py
@@ -18,8 +18,6 @@ from email.utils import formatdate
from twisted.internet.task import LoopingCall
-from deluge.common import utf8_encoded
-
log = logging.getLogger(__name__)
@@ -143,7 +141,7 @@ class Auth(JSONComponent):
log.debug('Received a password via the 1.2-dev auth method')
m = hashlib.md5()
m.update(config['pwd_salt'])
- m.update(utf8_encoded(password))
+ m.update(password.encode('utf8'))
if m.hexdigest() == config['pwd_md5']:
# We want to move the password over to sha1 and remove
# the old passwords from the config file.
@@ -163,7 +161,7 @@ class Auth(JSONComponent):
from base64 import decodestring
m = hashlib.md5()
m.update(decodestring(config['old_pwd_salt']))
- m.update(utf8_encoded(password))
+ m.update(password.encode('utf8'))
if m.digest() == decodestring(config['old_pwd_md5']):
# We want to move the password over to sha1 and remove
@@ -179,7 +177,7 @@ class Auth(JSONComponent):
log.debug('Received a password via the 1.2 auth method')
s = hashlib.sha1()
s.update(config['pwd_salt'])
- s.update(utf8_encoded(password))
+ s.update(password.encode('utf8'))
if s.hexdigest() == config['pwd_sha1']:
return True
@@ -249,7 +247,7 @@ class Auth(JSONComponent):
log.debug('Changing password')
salt = hashlib.sha1(os.urandom(32)).hexdigest()
s = hashlib.sha1(salt)
- s.update(utf8_encoded(new_password))
+ s.update(new_password.encode('utf8'))
self.config['pwd_salt'] = salt
self.config['pwd_sha1'] = s.hexdigest()
return True
diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py
index 96cf80aaf..0e66408c8 100644
--- a/deluge/ui/web/json_api.py
+++ b/deluge/ui/web/json_api.py
@@ -897,8 +897,6 @@ class WebApi(JSONComponent):
if key in ['sessions', 'pwd_salt', 'pwd_sha1']:
log.warn('Ignored attempt to overwrite web config key: %s', key)
continue
- if isinstance(config[key], basestring):
- config[key] = config[key].encode('utf8')
web_config[key] = config[key]
@export