[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.
This commit is contained in:
Calum Lind 2017-02-22 13:40:17 +00:00
parent 52a85cb91c
commit b2db96e4df
27 changed files with 115 additions and 194 deletions

View File

@ -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

View File

@ -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 = []

View File

@ -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):

View File

@ -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:

View File

@ -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

View File

@ -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"""

View File

@ -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']:

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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])

View File

@ -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()

View File

@ -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')

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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]
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]
def sort_key2(s):
return state.get(s)[field].lower()
# 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)

View File

@ -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

View File

@ -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])

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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