diff --git a/plugins/Admin/plugin.py b/plugins/Admin/plugin.py index d5057475d..4c8411695 100644 --- a/plugins/Admin/plugin.py +++ b/plugins/Admin/plugin.py @@ -151,7 +151,7 @@ class Admin(callbacks.Plugin): networkGroup.channels().add(channel) if key: networkGroup.channels.key.get(channel).setValue(key) - maxchannels = irc.state.supported.get('maxchannels', sys.maxint) + maxchannels = irc.state.supported.get('maxchannels', sys.maxsize) if len(irc.state.channels) + 1 > maxchannels: irc.error(_('I\'m already too close to maximum number of ' 'channels for this network.'), Raise=True) @@ -351,7 +351,7 @@ class Admin(callbacks.Plugin): """ # XXX Add the expirations. if ircdb.ignores.hostmasks: - irc.reply(format('%L', (map(repr,ircdb.ignores.hostmasks)))) + irc.reply(format('%L', (list(map(repr,ircdb.ignores.hostmasks))))) else: irc.reply(_('I\'m not currently globally ignoring anyone.')) list = wrap(list) diff --git a/plugins/Aka/plugin.py b/plugins/Aka/plugin.py index cc28ed190..9d82647a9 100644 --- a/plugins/Aka/plugin.py +++ b/plugins/Aka/plugin.py @@ -349,7 +349,7 @@ class RecursiveAlias(AkaError): dollarRe = re.compile(r'\$(\d+)') def findBiggestDollar(alias): dollars = dollarRe.findall(alias) - dollars = map(int, dollars) + dollars = list(map(int, dollars)) dollars.sort() if dollars: return dollars[-1] @@ -359,7 +359,7 @@ def findBiggestDollar(alias): atRe = re.compile(r'@(\d+)') def findBiggestAt(alias): ats = atRe.findall(alias) - ats = map(int, ats) + ats = list(map(int, ats)) ats.sort() if ats: return ats[-1] @@ -396,15 +396,15 @@ class Aka(callbacks.Plugin): def listCommands(self): channel = dynamic.channel or 'global' - return list(set(map(callbacks.formatCommand, + return list(set(list(map(callbacks.formatCommand, self._db.get_aka_list(channel) + - self._db.get_aka_list('global')) + + self._db.get_aka_list('global'))) + ['add', 'remove', 'lock', 'unlock', 'importaliasdatabase'])) def getCommand(self, args, check_other_plugins=True): canonicalName = callbacks.canonicalName # All the code from here to the 'for' loop is copied from callbacks.py - assert args == map(canonicalName, args) + assert args == list(map(canonicalName, args)) first = args[0] for cb in self.cbs: if first == cb.canonicalName(): @@ -439,7 +439,7 @@ class Aka(callbacks.Plugin): args = getArgs(args, required=biggestDollar, optional=biggestAt, wildcard=wildcard) max_len = conf.supybot.reply.maximumLength() - args = list(map(lambda x:x[:max_len], args)) + args = list([x[:max_len] for x in args]) def regexpReplace(m): idx = int(m.group(1)) return args[idx-1] @@ -649,7 +649,7 @@ class Aka(callbacks.Plugin): if errors: irc.error(format(_('Error occured when importing the %n: %L'), (len(errors), 'following', 'command'), - map(lambda x:'%s (%s)' % x, errors.items()))) + ['%s (%s)' % x for x in errors.items()])) else: irc.replySuccess() importaliasdatabase = wrap(importaliasdatabase, ['owner']) diff --git a/plugins/Alias/plugin.py b/plugins/Alias/plugin.py index 187e5674a..d5d3084f3 100644 --- a/plugins/Alias/plugin.py +++ b/plugins/Alias/plugin.py @@ -57,13 +57,13 @@ def getChannel(msg, args=()): 'variable ' \ 'supybot.reply.requireChannelCommandsToBeSentInChannel ' \ 'to False.' - raise callbacks.Error, s + raise callbacks.Error(s) return args.pop(0) elif ircutils.isChannel(msg.args[0]): return msg.args[0] else: - raise callbacks.Error, 'Command must be sent in a channel or ' \ - 'include a channel in its arguments.' + raise callbacks.Error('Command must be sent in a channel or ' \ + 'include a channel in its arguments.') def getArgs(args, required=1, optional=0, wildcard=0): if len(args) < required: @@ -87,7 +87,7 @@ class RecursiveAlias(AliasError): dollarRe = re.compile(r'\$(\d+)') def findBiggestDollar(alias): dollars = dollarRe.findall(alias) - dollars = map(int, dollars) + dollars = list(map(int, dollars)) dollars.sort() if dollars: return dollars[-1] @@ -97,7 +97,7 @@ def findBiggestDollar(alias): atRe = re.compile(r'@(\d+)') def findBiggestAt(alias): ats = atRe.findall(alias) - ats = map(int, ats) + ats = list(map(int, ats)) ats.sort() if ats: return ats[-1] @@ -163,12 +163,12 @@ def makeNewAlias(name, alias): biggestAt = findBiggestAt(original) wildcard = '$*' in original if biggestAt and wildcard: - raise AliasError, 'Can\'t mix $* and optional args (@1, etc.)' + raise AliasError('Can\'t mix $* and optional args (@1, etc.)') if original.count('$*') > 1: - raise AliasError, 'There can be only one $* in an alias.' + raise AliasError('There can be only one $* in an alias.') testTokens = callbacks.tokenize(original) if testTokens and isinstance(testTokens[0], list): - raise AliasError, 'Commands may not be the result of nesting.' + raise AliasError('Commands may not be the result of nesting.') def f(self, irc, msg, args): alias = original.replace('$nick', msg.nick) if '$channel' in original: @@ -179,7 +179,7 @@ def makeNewAlias(name, alias): args = getArgs(args, required=biggestDollar, optional=biggestAt, wildcard=wildcard) max_len = conf.supybot.reply.maximumLength() - args = list(map(lambda x:x[:max_len], args)) + args = list([x[:max_len] for x in args]) def regexpReplace(m): idx = int(m.group(1)) return args[idx-1] @@ -272,7 +272,7 @@ class Alias(callbacks.Plugin): for (alias, (command, locked, _)) in self.aliases.items(): try: self.addAlias(irc, alias, command, locked) - except Exception, e: + except Exception as e: self.log.exception('Exception when trying to add alias %s. ' 'Removing from the Alias database.', alias) del self.aliases[alias] @@ -333,21 +333,21 @@ class Alias(callbacks.Plugin): realName = callbacks.canonicalName(name) if name != realName: s = format(_('That name isn\'t valid. Try %q instead.'), realName) - raise AliasError, s + raise AliasError(s) name = realName if self.isCommandMethod(name): if realName not in self.aliases: s = 'You can\'t overwrite commands in this plugin.' - raise AliasError, s + raise AliasError(s) if name in self.aliases: (currentAlias, locked, _) = self.aliases[name] if locked and currentAlias != alias: - raise AliasError, format('Alias %q is locked.', name) + raise AliasError(format('Alias %q is locked.', name)) try: f = makeNewAlias(name, alias) f = types.MethodType(f, self) except RecursiveAlias: - raise AliasError, 'You can\'t define a recursive alias.' + raise AliasError('You can\'t define a recursive alias.') if '.' in name or '|' in name: aliasGroup = self.registryValue('escapedaliases', value=False) confname = escapeAlias(name) @@ -374,9 +374,9 @@ class Alias(callbacks.Plugin): else: conf.supybot.plugins.Alias.aliases.unregister(name) else: - raise AliasError, 'That alias is locked.' + raise AliasError('That alias is locked.') else: - raise AliasError, 'There is no such alias.' + raise AliasError('There is no such alias.') @internationalizeDocstring def add(self, irc, msg, args, name, alias): @@ -397,7 +397,7 @@ class Alias(callbacks.Plugin): self.log.info('Adding alias %q for %q (from %s)', name, alias, msg.prefix) irc.replySuccess() - except AliasError, e: + except AliasError as e: irc.error(str(e)) add = wrap(add, ['commandName', 'text']) @@ -411,7 +411,7 @@ class Alias(callbacks.Plugin): self.removeAlias(name) self.log.info('Removing alias %q (from %s)', name, msg.prefix) irc.replySuccess() - except AliasError, e: + except AliasError as e: irc.error(str(e)) remove = wrap(remove, ['commandName']) diff --git a/plugins/Channel/plugin.py b/plugins/Channel/plugin.py index fd591ad28..44020c1cb 100644 --- a/plugins/Channel/plugin.py +++ b/plugins/Channel/plugin.py @@ -279,7 +279,7 @@ class Channel(callbacks.Plugin): irc.error(_('I cowardly refuse to kick myself.'), Raise=True) if not reason: reason = msg.nick - kicklen = irc.state.supported.get('kicklen', sys.maxint) + kicklen = irc.state.supported.get('kicklen', sys.maxsize) if len(reason) > kicklen: irc.error(_('The reason you gave is longer than the allowed ' 'length for a KICK reason on this server.'), @@ -667,7 +667,7 @@ class Channel(callbacks.Plugin): irc.reply(s) else: L = sorted(c.ignores) - irc.reply(utils.str.commaAndify(map(repr, L))) + irc.reply(utils.str.commaAndify(list(map(repr, L)))) list = wrap(list, ['op']) class capability(callbacks.Commands): @@ -808,7 +808,7 @@ class Channel(callbacks.Plugin): 'called %s.'), plugin.name(), command) elif command: # findCallbackForCommand - if filter(None, irc.findCallbacksForArgs([command])): + if list(filter(None, irc.findCallbacksForArgs([command]))): s = '-%s' % command else: failMsg = format(_('No plugin or command named %s could be ' @@ -847,7 +847,7 @@ class Channel(callbacks.Plugin): 'called %s.'), plugin.name(), command) elif command: # findCallbackForCommand - if filter(None, irc.findCallbacksForArgs([command])): + if list(filter(None, irc.findCallbacksForArgs([command]))): s = '-%s' % command else: failMsg = format(_('No plugin or command named %s could be ' diff --git a/plugins/ChannelLogger/plugin.py b/plugins/ChannelLogger/plugin.py index 1c3c157c7..9b411dacd 100644 --- a/plugins/ChannelLogger/plugin.py +++ b/plugins/ChannelLogger/plugin.py @@ -98,7 +98,7 @@ class ChannelLogger(callbacks.Plugin): for log in self._logs(): try: log.flush() - except ValueError, e: + except ValueError as e: if e.args[0] != 'I/O operation on a closed file': self.log.exception('Odd exception:') diff --git a/plugins/ChannelStats/plugin.py b/plugins/ChannelStats/plugin.py index 1826873fa..fde2c3448 100644 --- a/plugins/ChannelStats/plugin.py +++ b/plugins/ChannelStats/plugin.py @@ -135,7 +135,7 @@ class StatsDB(plugins.ChannelUserDB): return v.values() def deserialize(self, channel, id, L): - L = map(int, L) + L = list(map(int, L)) if id == 'channelStats': return ChannelStat(*L) else: @@ -336,9 +336,9 @@ class ChannelStats(callbacks.Plugin): v = eval(expr, e, e) except ZeroDivisionError: v = float('inf') - except NameError, e: + except NameError as e: irc.errorInvalid(_('stat variable'), str(e).split()[1]) - except Exception, e: + except Exception as e: irc.error(utils.exnToString(e), Raise=True) if id == 0: users.append((v, irc.nick)) diff --git a/plugins/Conditional/plugin.py b/plugins/Conditional/plugin.py index e724fea79..ecba0ff01 100644 --- a/plugins/Conditional/plugin.py +++ b/plugins/Conditional/plugin.py @@ -65,7 +65,7 @@ class Conditional(callbacks.Plugin): tokens = callbacks.tokenize(command) try: self.Proxy(irc.irc, msg, tokens) - except Exception, e: + except Exception as e: self.log.exception('Uncaught exception in requested function:') @internationalizeDocstring diff --git a/plugins/Config/plugin.py b/plugins/Config/plugin.py index 3aaa07c3f..8c4d11ab9 100644 --- a/plugins/Config/plugin.py +++ b/plugins/Config/plugin.py @@ -51,7 +51,7 @@ _ = PluginInternationalization('Config') def getWrapper(name): parts = registry.split(name) if not parts or parts[0] not in ('supybot', 'users'): - raise InvalidRegistryName, name + raise InvalidRegistryName(name) group = getattr(conf, parts.pop(0)) while parts: try: @@ -60,7 +60,7 @@ def getWrapper(name): # that we have a useful error message for the user. except (registry.NonExistentRegistryEntry, registry.InvalidRegistryName): - raise registry.InvalidRegistryName, name + raise registry.InvalidRegistryName(name) return group def getCapability(name): @@ -99,7 +99,7 @@ def getConfigVar(irc, msg, args, state): group = getWrapper(name) state.args.append(group) del args[0] - except registry.InvalidRegistryName, e: + except registry.InvalidRegistryName as e: state.errorInvalid(_('configuration variable'), str(e)) addConverter('configVar', getConfigVar) @@ -114,7 +114,7 @@ class Config(callbacks.Plugin): def callCommand(self, command, irc, msg, *args, **kwargs): try: super(Config, self).callCommand(command, irc, msg, *args, **kwargs) - except registry.InvalidRegistryValue, e: + except registry.InvalidRegistryValue as e: irc.error(str(e)) def _list(self, group): diff --git a/plugins/Dict/local/dictclient.py b/plugins/Dict/local/dictclient.py index 64cef4097..c6f48f4f6 100644 --- a/plugins/Dict/local/dictclient.py +++ b/plugins/Dict/local/dictclient.py @@ -65,15 +65,15 @@ class Connection: code, text = self.getresultcode() if code < 200 or code >= 300: - raise Exception, "Got '%s' when 200-class response expected" % \ - line + raise Exception("Got '%s' when 200-class response expected" % \ + line) return [code, text] def get100block(self): """Used when expecting multiple lines of text -- gets the block part only. Does not get any codes or anything! Returns a string.""" data = [] - while 1: + while True: line = self.rfile.readline().decode('utf8').strip() if line == '.': break @@ -86,8 +86,8 @@ class Connection: finalcode]""" code, text = self.getresultcode() if code < 100 or code >= 200: - raise Exception, "Got '%s' when 100-class response expected" % \ - code + raise Exception("Got '%s' when 100-class response expected" % \ + code) bodylines = self.get100block().split("\n") @@ -149,7 +149,7 @@ class Connection: if not hasattr(self, 'dbobjs'): self.dbobjs = {} - if self.dbobjs.has_key(dbname): + if dbname in self.dbobjs: return self.dbobjs[dbname] # We use self.dbdescs explicitly since we don't want to @@ -157,7 +157,7 @@ class Connection: if dbname != '*' and dbname != '!' and \ not dbname in self.dbdescs.keys(): - raise Exception, "Invalid database name '%s'" % dbname + raise Exception("Invalid database name '%s'" % dbname) self.dbobjs[dbname] = Database(self, dbname) return self.dbobjs[dbname] @@ -181,7 +181,7 @@ class Connection: if database != '*' and database != '!' and \ not database in self.getdbdescs(): - raise Exception, "Invalid database '%s' specified" % database + raise Exception("Invalid database '%s' specified" % database) self.sendcommand("DEFINE " + enquote(database) + " " + enquote(word)) code = self.getresultcode()[0] @@ -192,9 +192,9 @@ class Connection: # No definitions. return [] if code != 150: - raise Exception, "Unknown code %d" % code + raise Exception("Unknown code %d" % code) - while 1: + while True: code, text = self.getresultcode() if code != 151 or code is None: break @@ -217,10 +217,10 @@ class Connection: self.getstratdescs() # Prime the cache self.getdbdescs() # Prime the cache if not strategy in self.getstratdescs().keys(): - raise Exception, "Invalid strategy '%s'" % strategy + raise Exception("Invalid strategy '%s'" % strategy) if database != '*' and database != '!' and \ not database in self.getdbdescs().keys(): - raise Exception, "Invalid database name '%s'" % database + raise Exception("Invalid database name '%s'" % database) self.sendcommand("MATCH %s %s %s" % (enquote(database), enquote(strategy), @@ -230,7 +230,7 @@ class Connection: # No Matches return [] if code != 152: - raise Exception, "Unexpected code %d" % code + raise Exception("Unexpected code %d" % code) retval = [] @@ -239,7 +239,7 @@ class Connection: retval.append(Definition(self, self.getdbobj(matchdict), dequote(matchword))) if self.getresultcode()[0] != 250: - raise Exception, "Unexpected end-of-list code %d" % code + raise Exception("Unexpected end-of-list code %d" % code) return retval class Database: diff --git a/plugins/Dict/plugin.py b/plugins/Dict/plugin.py index 008b32f5d..3eed6de64 100644 --- a/plugins/Dict/plugin.py +++ b/plugins/Dict/plugin.py @@ -56,7 +56,7 @@ class Dict(callbacks.Plugin): dbs = list(conn.getdbdescs().keys()) dbs.sort() irc.reply(format('%L', dbs)) - except socket.error, e: + except socket.error as e: irc.error(utils.web.strError(e)) dictionaries = wrap(dictionaries) @@ -71,7 +71,7 @@ class Dict(callbacks.Plugin): conn = dictclient.Connection(server) dbs = conn.getdbdescs().keys() irc.reply(utils.iter.choice(dbs)) - except socket.error, e: + except socket.error as e: irc.error(utils.web.strError(e)) random = wrap(random) @@ -85,7 +85,7 @@ class Dict(callbacks.Plugin): try: server = conf.supybot.plugins.Dict.server() conn = dictclient.Connection(server) - except socket.error, e: + except socket.error as e: irc.error(utils.web.strError(e), Raise=True) dbs = set(conn.getdbdescs()) if words[0] in dbs: @@ -139,7 +139,7 @@ class Dict(callbacks.Plugin): try: server = conf.supybot.plugins.Dict.server() conn = dictclient.Connection(server) - except socket.error, e: + except socket.error as e: irc.error(utils.web.strError(e), Raise=True) dictionary = 'moby-thes' diff --git a/plugins/Factoids/plugin.py b/plugins/Factoids/plugin.py index 34d3e2f58..9b5e604b0 100644 --- a/plugins/Factoids/plugin.py +++ b/plugins/Factoids/plugin.py @@ -244,7 +244,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler): def getCommandHelp(self, command, simpleSyntax=None): method = self.getCommandMethod(command) - if method.im_func.func_name == 'learn': + if method.im_func.__name__ == 'learn': chan = None if dynamic.msg is not None: chan = dynamic.msg.args[0] @@ -352,7 +352,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler): return [] flkeys = [line[0] for line in flkeys] dl_metrics = [dameraulevenshtein(key, sourcekey) for sourcekey in flkeys] - dict_metrics = dict(zip(flkeys, dl_metrics)) + dict_metrics = dict(list(zip(flkeys, dl_metrics))) if min(dl_metrics) <= 2: return [key for key,item in dict_metrics.iteritems() if item <= 2] if min(dl_metrics) <= 3: diff --git a/plugins/Filter/plugin.py b/plugins/Filter/plugin.py index 0dc8732c6..c34b012a7 100644 --- a/plugins/Filter/plugin.py +++ b/plugins/Filter/plugin.py @@ -241,8 +241,8 @@ class Filter(callbacks.Plugin): irc.reply(text) lithp = wrap(lithp, ['text']) - _leettrans = utils.str.MultipleReplacer(dict(zip('oOaAeElBTiIts', - '004433187!1+5'))) + _leettrans = utils.str.MultipleReplacer(dict(list(zip('oOaAeElBTiIts', + '004433187!1+5')))) _leetres = [(re.compile(r'\b(?:(?:[yY][o0O][oO0uU])|u)\b'), 'j00'), (re.compile(r'fear'), 'ph33r'), (re.compile(r'[aA][tT][eE]'), '8'), @@ -416,7 +416,7 @@ class Filter(callbacks.Plugin): if sys.version_info[0] < 3: text = text.decode('utf-8') colors = utils.iter.cycle(['04', '07', '08', '03', '02', '12', '06']) - L = [self._color(c, fg=colors.next()) for c in text] + L = [self._color(c, fg=next(colors)) for c in text] if sys.version_info[0] < 3: L = [c.encode('utf-8') for c in L] irc.reply(''.join(L) + '\x03') @@ -662,7 +662,7 @@ class Filter(callbacks.Plugin): irc.reply(text) shrink = wrap(shrink, ['text']) - _azn_trans = utils.str.MultipleReplacer(dict(zip('rlRL', 'lrLR'))) + _azn_trans = utils.str.MultipleReplacer(dict(list(zip('rlRL', 'lrLR')))) @internationalizeDocstring def azn(self, irc, msg, args, text): """ diff --git a/plugins/Format/plugin.py b/plugins/Format/plugin.py index f18968b28..4417b2a17 100644 --- a/plugins/Format/plugin.py +++ b/plugins/Format/plugin.py @@ -102,7 +102,7 @@ class Format(callbacks.Plugin): if len(bad) != len(good): irc.error(_(' must be the same length as ' '.'), Raise=True) - irc.reply(utils.str.MultipleReplacer(dict(zip(bad, good)))(text)) + irc.reply(utils.str.MultipleReplacer(dict(list(zip(bad, good))))(text)) translate = wrap(translate, ['something', 'something', 'text']) @internationalizeDocstring @@ -208,7 +208,7 @@ class Format(callbacks.Plugin): try: s %= tuple(args) irc.reply(s) - except TypeError, e: + except TypeError as e: self.log.debug(utils.exnToString(e)) irc.error(_('Not enough arguments for the format string.'), Raise=True) diff --git a/plugins/Games/plugin.py b/plugins/Games/plugin.py index 7ab02bb79..1ab43e628 100644 --- a/plugins/Games/plugin.py +++ b/plugins/Games/plugin.py @@ -30,7 +30,7 @@ import re import random -from itertools import imap + import supybot.utils as utils from supybot.commands import * @@ -62,7 +62,7 @@ class Games(callbacks.Plugin): For example, 2d6 will roll 2 six-sided dice; 10d10 will roll 10 ten-sided dice. """ - (dice, sides) = imap(int, m.groups()) + (dice, sides) = list(map(int, m.groups())) if dice > 1000: irc.error(_('You can\'t roll more than 1000 dice.')) elif sides > 100: diff --git a/plugins/Google/plugin.py b/plugins/Google/plugin.py index 4c95513ba..5e4c4a41e 100644 --- a/plugins/Google/plugin.py +++ b/plugins/Google/plugin.py @@ -120,7 +120,7 @@ class Google(callbacks.PluginRegexp): headers=headers).decode('utf8') data = json.loads(text) if data['responseStatus'] != 200: - raise callbacks.Error, _('We broke The Google!') + raise callbacks.Error(_('We broke The Google!')) return data def formatData(self, data, bold=True, max=0, onetoone=False): @@ -143,7 +143,7 @@ class Google(callbacks.PluginRegexp): results.append(url) if sys.version_info[0] < 3: repl = lambda x:x if isinstance(x, unicode) else unicode(x, 'utf8') - results = map(repl, results) + results = list(map(repl, results)) if not results: return [_('No matches found.')] elif onetoone: @@ -162,7 +162,7 @@ class Google(callbacks.PluginRegexp): data = self.search(text, msg.args[0], {'smallsearch': True}) if data['responseData']['results']: url = data['responseData']['results'][0]['unescapedUrl'] - if opts.has_key('snippet'): + if 'snippet' in opts: snippet = data['responseData']['results'][0]['content'] snippet = " | " + utils.web.htmlToText(snippet, tagReplace='') else: diff --git a/plugins/Internet/plugin.py b/plugins/Internet/plugin.py index 8128b4b61..2e09a1623 100644 --- a/plugins/Internet/plugin.py +++ b/plugins/Internet/plugin.py @@ -82,7 +82,7 @@ class Internet(callbacks.Plugin): try: sock = utils.net.getSocket('%s.whois-servers.net' % usertld) sock.connect(('%s.whois-servers.net' % usertld, 43)) - except socket.error, e: + except socket.error as e: irc.error(str(e)) return sock.settimeout(5) @@ -130,7 +130,7 @@ class Internet(callbacks.Plugin): status = 'unknown' try: t = telnetlib.Telnet('whois.pir.org', 43) - except socket.error, e: + except socket.error as e: irc.error(str(e)) return t.write(b'registrar ') diff --git a/plugins/Karma/plugin.py b/plugins/Karma/plugin.py index 42c03ac95..3e4370a4a 100644 --- a/plugins/Karma/plugin.py +++ b/plugins/Karma/plugin.py @@ -88,12 +88,12 @@ class SqliteKarmaDB(object): if len(results) == 0: return None else: - return map(int, results[0]) + return list(map(int, results[0])) def gets(self, channel, things): db = self._getDb(channel) cursor = db.cursor() - normalizedThings = dict(zip(map(lambda s: s.lower(), things), things)) + normalizedThings = dict(list(zip([s.lower() for s in things], things))) criteria = ' OR '.join(['normalized=?'] * len(normalizedThings)) sql = """SELECT name, added-subtracted FROM karma WHERE %s ORDER BY added-subtracted DESC""" % criteria @@ -167,7 +167,7 @@ class SqliteKarmaDB(object): elif kind == 'active': orderby = 'added+subtracted' else: - raise ValueError, 'invalid kind' + raise ValueError('invalid kind') sql = """SELECT name, %s FROM karma ORDER BY %s DESC LIMIT %s""" % \ (orderby, orderby, limit) db = self._getDb(channel) diff --git a/plugins/Lart/plugin.py b/plugins/Lart/plugin.py index aed197614..4bc3f5ee3 100644 --- a/plugins/Lart/plugin.py +++ b/plugins/Lart/plugin.py @@ -56,7 +56,7 @@ class Lart(plugins.ChannelIdDatabasePlugin): only necessary if the message isn't sent in the channel itself. """ if ' for ' in text: - (target, reason) = map(str.strip, text.split(' for ', 1)) + (target, reason) = list(map(str.strip, text.split(' for ', 1))) else: (target, reason) = (text, '') if id is not None: diff --git a/plugins/Later/plugin.py b/plugins/Later/plugin.py index 01c3f7667..24e38fc99 100644 --- a/plugins/Later/plugin.py +++ b/plugins/Later/plugin.py @@ -69,7 +69,7 @@ class Later(callbacks.Plugin): def _openNotes(self): try: fd = open(self.filename) - except EnvironmentError, e: + except EnvironmentError as e: self.log.warning('Couldn\'t open %s: %s', self.filename, e) return reader = csv.reader(fd) diff --git a/plugins/Math/local/convertcore.py b/plugins/Math/local/convertcore.py index 75d38fa11..f64420127 100644 --- a/plugins/Math/local/convertcore.py +++ b/plugins/Math/local/convertcore.py @@ -937,12 +937,12 @@ class UnitGroup: while tmpList: count += 1 if count > 5000: - raise UnitDataError, 'Circular unit definition' + raise UnitDataError('Circular unit definition') unit = tmpList.pop(0) if unit.equiv == '!': self.reducedList.append(copy.copy(unit)) elif not unit.equiv: - raise UnitDataError, 'Invalid conversion for "%s"' % unit.name + raise UnitDataError('Invalid conversion for "%s"' % unit.name) else: if unit.fromEqn: self.linear = 0 @@ -1029,7 +1029,7 @@ class UnitGroup: except OverflowError: return 1e9999 except: - raise UnitDataError, 'Bad equation for %s' % self.unitList[0].name + raise UnitDataError('Bad equation for %s' % self.unitList[0].name) def convertStr(self, num, toGroup): "Return formatted string of converted number" @@ -1063,7 +1063,7 @@ class UnitData(dict): lines = f.readlines() f.close() except IOError: - raise UnitDataError, 'Can not read "units.dat" file' + raise UnitDataError('Can not read "units.dat" file') for i in range(len(lines)): # join continuation lines delta = 1 while lines[i].rstrip().endswith('\\'): @@ -1087,7 +1087,7 @@ class UnitData(dict): self.sortedKeys.sort() if len(self.sortedKeys) < len(units): - raise UnitDataError, 'Duplicate unit names found' + raise UnitDataError('Duplicate unit names found') return (types, typeUnits) @@ -1132,7 +1132,7 @@ class Unit: self.toEqn = self.toEqn.strip() self.fromEqn = self.fromEqn.strip() except AttributeError: - raise UnitDataError, 'Bad equation for "%s"' % self.name + raise UnitDataError('Bad equation for "%s"' % self.name) else: # split factor and equiv unit for linear parts = self.equiv.split(None, 1) if len(parts) > 1 and re.search('[^\d\.eE\+\-\*/]', parts[0]) \ diff --git a/plugins/Math/plugin.py b/plugins/Math/plugin.py index 8877e2dfc..123f4b0ff 100644 --- a/plugins/Math/plugin.py +++ b/plugins/Math/plugin.py @@ -219,9 +219,9 @@ class Math(callbacks.Plugin): irc.error(_('The answer exceeded %s or so.') % maxFloat) except TypeError: irc.error(_('Something in there wasn\'t a valid number.')) - except NameError, e: + except NameError as e: irc.error(_('%s is not a defined function.') % str(e).split()[1]) - except Exception, e: + except Exception as e: irc.error(str(e)) calc = wrap(calc, ['text']) @@ -253,9 +253,9 @@ class Math(callbacks.Plugin): irc.error(_('The answer exceeded %s or so.') % maxFloat) except TypeError: irc.error(_('Something in there wasn\'t a valid number.')) - except NameError, e: + except NameError as e: irc.error(_('%s is not a defined function.') % str(e).split()[1]) - except Exception, e: + except Exception as e: irc.error(utils.exnToString(e)) icalc = wrap(icalc, [('checkCapability', 'trusted'), 'text']) @@ -308,7 +308,7 @@ class Math(callbacks.Plugin): if len(stack) == 1: irc.reply(str(self._complexToString(complex(stack[0])))) else: - s = ', '.join(map(self._complexToString, map(complex, stack))) + s = ', '.join(map(self._complexToString, list(map(complex, stack)))) irc.reply(_('Stack: [%s]') % s) @internationalizeDocstring @@ -337,7 +337,7 @@ class Math(callbacks.Plugin): newNum = round(newNum, digits + 1 + zeros) newNum = self._floatToString(newNum) irc.reply(str(newNum)) - except convertcore.UnitDataError, ude: + except convertcore.UnitDataError as ude: irc.error(str(ude)) convert = wrap(convert, [optional('float', 1.0),'something','to','text']) diff --git a/plugins/Math/test.py b/plugins/Math/test.py index 9c22e30d3..bce6b77f9 100644 --- a/plugins/Math/test.py +++ b/plugins/Math/test.py @@ -89,9 +89,9 @@ class MathTestCase(PluginTestCase): self.assertError('base 4 4') self.assertError('base 10 12 A') - print - print "If we have not fixed a bug with Math.base, the following ", - print "tests will hang the test-suite." + print() + print("If we have not fixed a bug with Math.base, the following ") + print("tests will hang the test-suite.") self.assertRegexp('base 2 10 [base 10 2 -12]', '-12') self.assertRegexp('base 16 2 [base 2 16 -110101]', '-110101') diff --git a/plugins/MessageParser/plugin.py b/plugins/MessageParser/plugin.py index 66382358a..825502959 100644 --- a/plugins/MessageParser/plugin.py +++ b/plugins/MessageParser/plugin.py @@ -128,7 +128,7 @@ class MessageParser(callbacks.Plugin, plugins.ChannelDBHandler): tokens = callbacks.tokenize(command) try: self.Proxy(irc.irc, msg, tokens) - except Exception, e: + except Exception as e: log.exception('Uncaught exception in function called by MessageParser:') def _checkManageCapabilities(self, irc, msg, channel): @@ -161,7 +161,7 @@ class MessageParser(callbacks.Plugin, plugins.ChannelDBHandler): cursor.execute("SELECT regexp, action FROM triggers") # Fetch results and prepend channel name or 'global'. This # prevents duplicating the following lines. - results.extend(map(lambda x: (channel,)+x, cursor.fetchall())) + results.extend([(channel,)+x for x in cursor.fetchall()]) if len(results) == 0: return max_triggers = self.registryValue('maxTriggers', channel) @@ -206,14 +206,14 @@ class MessageParser(callbacks.Plugin, plugins.ChannelDBHandler): cursor.execute("SELECT id, usage_count, locked FROM triggers WHERE regexp=?", (regexp,)) results = cursor.fetchall() if len(results) != 0: - (id, usage_count, locked) = map(int, results[0]) + (id, usage_count, locked) = list(map(int, results[0])) else: locked = 0 usage_count = 0 if not locked: try: re.compile(regexp) - except Exception, e: + except Exception as e: irc.error(_('Invalid python regexp: %s') % (e,)) return if ircdb.users.hasUser(msg.prefix): @@ -252,7 +252,7 @@ class MessageParser(callbacks.Plugin, plugins.ChannelDBHandler): cursor.execute(sql, (regexp,)) results = cursor.fetchall() if len(results) != 0: - (id, locked) = map(int, results[0]) + (id, locked) = list(map(int, results[0])) else: irc.error(_('There is no such regexp trigger.')) return diff --git a/plugins/Misc/plugin.py b/plugins/Misc/plugin.py index c04feb99d..401e93cbd 100644 --- a/plugins/Misc/plugin.py +++ b/plugins/Misc/plugin.py @@ -34,7 +34,7 @@ import imp import sys import json import time -from itertools import ifilter + import supybot @@ -52,6 +52,15 @@ from supybot import commands from supybot.i18n import PluginInternationalization, internationalizeDocstring _ = PluginInternationalization('Misc') +if sys.version_info[0] < 3: + from itertools import ifilter as filter + +def get_suffix(file): + for suffix in imp.get_suffixes(): + if file[-len(suffix[0]):] == suffix[0]: + return suffix + return None + def getPluginsInDirectory(directory): # get modules in a given directory plugins = [] @@ -275,7 +284,7 @@ class Misc(callbacks.Plugin): You may also want to use the 'list' command to list all available plugins and commands. """ - command = map(callbacks.canonicalName, command) + command = list(map(callbacks.canonicalName, command)) (maxL, cbs) = irc.findCallbacksForArgs(command) if maxL == command: if len(cbs) > 1: @@ -313,7 +322,7 @@ class Misc(callbacks.Plugin): newest = _('The newest versions available online are %s.') % \ ', '.join([_('%s (in %s)') % (y,x) for x,y in versions.items()]) - except utils.web.Error, e: + except utils.web.Error as e: self.log.info('Couldn\'t get website version: %s', e) newest = _('I couldn\'t fetch the newest version ' 'from the Limnoria repository.') @@ -439,11 +448,11 @@ class Misc(callbacks.Plugin): predicates.setdefault('regexp', []).append(f) elif option == 'nolimit': nolimit = True - iterable = ifilter(self._validLastMsg, reversed(irc.state.history)) + iterable = filter(self._validLastMsg, reversed(irc.state.history)) if skipfirst: # Drop the first message only if our current channel is the same as # the channel we've been instructed to look at. - iterable.next() + next(iterable) predicates = list(utils.iter.flatten(predicates.itervalues())) # Make sure the user can't get messages from channels they aren't in def userInChannel(m): diff --git a/plugins/Misc/test.py b/plugins/Misc/test.py index 3d4212114..86f2981b2 100644 --- a/plugins/Misc/test.py +++ b/plugins/Misc/test.py @@ -132,8 +132,8 @@ class MiscTestCase(ChannelPluginTestCase): if network: def testVersion(self): - print '*** This test should start passing when we have our '\ - 'threaded issues resolved.' + print('*** This test should start passing when we have our '\ + 'threaded issues resolved.') self.assertNotError('version') def testSource(self): diff --git a/plugins/MoobotFactoids/plugin.py b/plugins/MoobotFactoids/plugin.py index 2208277d8..cff4186ad 100755 --- a/plugins/MoobotFactoids/plugin.py +++ b/plugins/MoobotFactoids/plugin.py @@ -54,9 +54,9 @@ class OptionList(object): return '(%s' % ''.join(ret) #) elif token == ')': if '|' in ret: - L = map(''.join, + L = list(map(''.join, utils.iter.split('|'.__eq__, ret, - yieldEmpty=True)) + yieldEmpty=True))) return utils.iter.choice(L) else: return '(%s)' % ''.join(ret) @@ -376,8 +376,8 @@ class MoobotFactoids(callbacks.Plugin): self.log.debug('Invalid tokens for {add,replace}Factoid: %s.', tokens) s = _('Missing an \'is\' or \'_is_\'.') - raise ValueError, s - (key, newfact) = map(' '.join, utils.iter.split(p, tokens, maxsplit=1)) + raise ValueError(s) + (key, newfact) = list(map(' '.join, utils.iter.split(p, tokens, maxsplit=1))) key = self._sanitizeKey(key) return (key, newfact) @@ -387,7 +387,7 @@ class MoobotFactoids(callbacks.Plugin): id = self._getUserId(irc, msg.prefix) try: (key, fact) = self._getKeyAndFactoid(tokens) - except ValueError, e: + except ValueError as e: irc.error(str(e), Raise=True) # Check and make sure it's not in the DB already if self.db.getFactoid(channel, key): @@ -397,8 +397,8 @@ class MoobotFactoids(callbacks.Plugin): def changeFactoid(self, irc, msg, tokens): id = self._getUserId(irc, msg.prefix) - (key, regexp) = map(' '.join, - utils.iter.split('=~'.__eq__, tokens, maxsplit=1)) + (key, regexp) = list(map(' '.join, + utils.iter.split('=~'.__eq__, tokens, maxsplit=1))) channel = plugins.getChannel(msg.args[0]) # Check and make sure it's in the DB fact = self._getFactoid(irc, channel, key) @@ -406,7 +406,7 @@ class MoobotFactoids(callbacks.Plugin): # It's fair game if we get to here try: r = utils.str.perlReToReplacer(regexp) - except ValueError, e: + except ValueError as e: irc.errorInvalid('regexp', regexp, Raise=True) fact = fact[0] new_fact = r(fact) @@ -436,7 +436,7 @@ class MoobotFactoids(callbacks.Plugin): del tokens[0] # remove the "no," try: (key, fact) = self._getKeyAndFactoid(tokens) - except ValueError, e: + except ValueError as e: irc.error(str(e), Raise=True) _ = self._getFactoid(irc, channel, key) self._checkNotLocked(irc, channel, key) diff --git a/plugins/Network/plugin.py b/plugins/Network/plugin.py index 9e7750152..0abe49a68 100644 --- a/plugins/Network/plugin.py +++ b/plugins/Network/plugin.py @@ -50,8 +50,7 @@ class Network(callbacks.Plugin): if irc: return irc else: - raise callbacks.Error, \ - 'I\'m not currently connected to %s.' % network + raise callbacks.Error('I\'m not currently connected to %s.' % network) @internationalizeDocstring def connect(self, irc, msg, args, opts, network, server, password): diff --git a/plugins/News/plugin.py b/plugins/News/plugin.py index 5a9d5d95d..599225fd7 100644 --- a/plugins/News/plugin.py +++ b/plugins/News/plugin.py @@ -153,7 +153,7 @@ class News(callbacks.Plugin): try: record = self.db.get(channel, id) irc.reply(str(record)) - except dbi.NoRecordError, id: + except dbi.NoRecordError as id: irc.errorInvalid(_('news item id'), id) news = wrap(news, ['channeldb', additional('positiveInt')]) @@ -199,7 +199,7 @@ class News(callbacks.Plugin): try: record = self.db.getOld(channel, id) irc.reply(str(record)) - except dbi.NoRecordError, id: + except dbi.NoRecordError as id: irc.errorInvalid(_('news item id'), id) else: try: diff --git a/plugins/News/test.py b/plugins/News/test.py index 1181a0cca..7904f6582 100644 --- a/plugins/News/test.py +++ b/plugins/News/test.py @@ -48,10 +48,10 @@ class NewsTestCase(ChannelPluginTestCase): self.assertRegexp('news', 'subject.*subject2') self.assertNotError('add 5 subject3: foo3') self.assertRegexp('news', 'subject3') - print - print 'Sleeping to expire the news item (testAddnews)' + print() + print('Sleeping to expire the news item (testAddnews)') time.sleep(6) - print 'Done sleeping.' + print('Done sleeping.') self.assertNotRegexp('news', 'subject3') def testNews(self): @@ -77,10 +77,10 @@ class NewsTestCase(ChannelPluginTestCase): self.assertRegexp('old', 'No old news') self.assertNotError('add 5 foo: bar') self.assertRegexp('old', 'No old news') - print - print 'Sleeping to expire the news item (testOldnews)' + print() + print('Sleeping to expire the news item (testOldnews)') time.sleep(6) - print 'Done sleeping.' + print('Done sleeping.') self.assertNotError('old') diff --git a/plugins/Nickometer/plugin.py b/plugins/Nickometer/plugin.py index c7370a4bc..cf9da917d 100644 --- a/plugins/Nickometer/plugin.py +++ b/plugins/Nickometer/plugin.py @@ -119,8 +119,8 @@ class Nickometer(callbacks.Plugin): ('\\[rkx]0', 1000), ('\\0[rkx]', 1000)] - letterNumberTranslator = utils.str.MultipleReplacer(dict(zip( - '023457+8', 'ozeasttb'))) + letterNumberTranslator = utils.str.MultipleReplacer(dict(list(zip( + '023457+8', 'ozeasttb')))) for special in specialCost: tempNick = nick if special[0][0] != '\\': @@ -145,7 +145,7 @@ class Nickometer(callbacks.Plugin): '%s consecutive non-alphas ' % len(match)) # Remove balanced brackets ... - while 1: + while True: nickInitial = nick nick=re.sub('^([^()]*)(\()(.*)(\))([^()]*)$', '\1\3\5', nick, 1) nick=re.sub('^([^{}]*)(\{)(.*)(\})([^{}]*)$', '\1\3\5', nick, 1) @@ -163,7 +163,7 @@ class Nickometer(callbacks.Plugin): # Punish k3wlt0k k3wlt0k_weights = (5, 5, 2, 5, 2, 3, 1, 2, 2, 2) for i in range(len(k3wlt0k_weights)): - hits=re.findall(`i`, nick) + hits=re.findall(repr(i), nick) if (hits and len(hits)>0): score += self.punish(k3wlt0k_weights[i] * len(hits) * 30, '%s occurrences of %s ' % (len(hits), i)) @@ -225,7 +225,7 @@ class Nickometer(callbacks.Plugin): (1 - 1 / (1 + score / 5.0)) // 2 # if it's above 99.9%, show as many digits as is interesting - score_string=re.sub('(99\\.9*\\d|\\.\\d).*','\\1',`percentage`) + score_string=re.sub('(99\\.9*\\d|\\.\\d).*','\\1',repr(percentage)) irc.reply(_('The "lame nick-o-meter" reading for "%s" is %s%%.') % (originalNick, score_string)) diff --git a/plugins/Owner/plugin.py b/plugins/Owner/plugin.py index 56234b829..9983e3e95 100644 --- a/plugins/Owner/plugin.py +++ b/plugins/Owner/plugin.py @@ -142,9 +142,9 @@ class Owner(callbacks.Plugin): for network in conf.supybot.networks(): try: self._connect(network) - except socket.error, e: + except socket.error as e: self.log.error('Could not connect to %s: %s.', network, e) - except Exception, e: + except Exception as e: self.log.exception('Exception connecting to %s:', network) self.log.error('Could not connect to %s: %s.', network, e) @@ -169,8 +169,8 @@ class Owner(callbacks.Plugin): (server, port) = group.servers()[0] except (registry.NonExistentRegistryEntry, IndexError): if serverPort is None: - raise ValueError, 'connect requires a (server, port) ' \ - 'if the network is not registered.' + raise ValueError('connect requires a (server, port) ' \ + 'if the network is not registered.') conf.registerNetwork(network, password, ssl) serverS = '%s:%s' % serverPort conf.supybot.networks.get(network).servers.append(serverS) @@ -209,21 +209,21 @@ class Owner(callbacks.Plugin): m = plugin.loadPluginModule(name, ignoreDeprecation=True) plugin.loadPluginClass(irc, m) - except callbacks.Error, e: + except callbacks.Error as e: # This is just an error message. log.warning(str(e)) - except (plugins.NoSuitableDatabase, ImportError), e: + except (plugins.NoSuitableDatabase, ImportError) as e: s = 'Failed to load %s: %s' % (name, e) if not s.endswith('.'): s += '.' log.warning(s) - except Exception, e: + except Exception as e: log.exception('Failed to load %s:', name) else: # Let's import the module so configuration is preserved. try: _ = plugin.loadPluginModule(name) - except Exception, e: + except Exception as e: log.debug('Attempted to load %s to preserve its ' 'configuration, but load failed: %s', name, e) @@ -267,7 +267,7 @@ class Owner(callbacks.Plugin): try: tokens = callbacks.tokenize(s, channel=msg.args[0]) self.Proxy(irc, msg, tokens) - except SyntaxError, e: + except SyntaxError as e: irc.queueMsg(callbacks.error(msg, str(e))) def logmark(self, irc, msg, args, text): @@ -340,7 +340,7 @@ class Owner(callbacks.Plugin): """ try: m = ircmsgs.IrcMsg(s) - except Exception, e: + except Exception as e: irc.error(utils.exnToString(e)) else: irc.queueMsg(m) @@ -435,7 +435,7 @@ class Owner(callbacks.Plugin): irc.error('%s is deprecated. Use --deprecated ' 'to force it to load.' % name.capitalize()) return - except ImportError, e: + except ImportError as e: if str(e).endswith(' ' + name): irc.error('No plugin named %s exists.' % utils.str.dqrepr(name)) else: diff --git a/plugins/Plugin/plugin.py b/plugins/Plugin/plugin.py index 6bb7ac73d..79151f783 100644 --- a/plugins/Plugin/plugin.py +++ b/plugins/Plugin/plugin.py @@ -98,7 +98,7 @@ class Plugin(callbacks.Plugin): plugin = wrap(plugin, [many('something')]) def _findCallbacks(self, irc, command): - command = map(callbacks.canonicalName, command) + command = list(map(callbacks.canonicalName, command)) plugin_list = [] for cb in irc.callbacks: if not hasattr(cb, 'getCommand'): diff --git a/plugins/Praise/plugin.py b/plugins/Praise/plugin.py index f34ac8993..ad054bb94 100644 --- a/plugins/Praise/plugin.py +++ b/plugins/Praise/plugin.py @@ -61,7 +61,7 @@ class Praise(plugins.ChannelIdDatabasePlugin): sent in the channel itself. """ if ' for ' in text: - (target, reason) = map(str.strip, text.split(' for ', 1)) + (target, reason) = list(map(str.strip, text.split(' for ', 1))) else: (target, reason) = (text, '') if ircutils.strEqual(target, irc.nick): diff --git a/plugins/RSS/plugin.py b/plugins/RSS/plugin.py index 6bf887a9a..7807f4b70 100644 --- a/plugins/RSS/plugin.py +++ b/plugins/RSS/plugin.py @@ -181,7 +181,8 @@ class RSS(callbacks.Plugin): #oldresults = self.cachedFeeds[url] #oldheadlines = self.getHeadlines(oldresults) oldheadlines = self.cachedHeadlines[url] - oldheadlines = filter(lambda x: t - x[3] < self.registryValue('announce.cachePeriod'), oldheadlines) + oldheadlines = list(filter(lambda x: t - x[3] < + self.registryValue('announce.cachePeriod'), oldheadlines)) except KeyError: oldheadlines = [] newresults = self.getFeed(url) @@ -198,7 +199,7 @@ class RSS(callbacks.Plugin): for (i, headline) in enumerate(newheadlines): if normalize(headline) in oldheadlinesset: newheadlines[i] = None - newheadlines = filter(None, newheadlines) # Removes Nones. + newheadlines = list(filter(None, newheadlines)) # Removes Nones. number_of_headlines = len(oldheadlines) oldheadlines.extend(newheadlines) self.cachedHeadlines[url] = oldheadlines @@ -228,6 +229,7 @@ class RSS(callbacks.Plugin): channelnewheadlines = filter(filter_whitelist, channelnewheadlines) if len(blacklist) != 0: channelnewheadlines = filter(filter_blacklist, channelnewheadlines) + channelnewheadlines = list(channelnewheadlines) if len(channelnewheadlines) == 0: return bold = self.registryValue('bold', channel) @@ -284,10 +286,10 @@ class RSS(callbacks.Plugin): raise results['bozo_exception'] except feedparser.sgmllib.SGMLParseError: self.log.exception('Uncaught exception from feedparser:') - raise callbacks.Error, 'Invalid (unparsable) RSS feed.' + raise callbacks.Error('Invalid (unparsable) RSS feed.') except socket.timeout: return error('Timeout downloading feed.') - except Exception, e: + except Exception as e: # These seem mostly harmless. We'll need reports of a # kind that isn't. self.log.debug('Allowing bozo_exception %r through.', e) @@ -364,7 +366,7 @@ class RSS(callbacks.Plugin): self.locks[url] = threading.RLock() if self.isCommandMethod(name): s = format('I already have a command in this plugin named %s.',name) - raise callbacks.Error, s + raise callbacks.Error(s) def f(self, irc, msg, args): args.insert(0, url) self.rss(irc, msg, args) diff --git a/plugins/Relay/plugin.py b/plugins/Relay/plugin.py index dba7e4ea4..3224ac7e6 100644 --- a/plugins/Relay/plugin.py +++ b/plugins/Relay/plugin.py @@ -171,8 +171,8 @@ class Relay(callbacks.Plugin): utils.sortBy(ircutils.toLower, voices) utils.sortBy(ircutils.toLower, halfops) utils.sortBy(ircutils.toLower, usersS) - usersS = ', '.join(filter(None, map(', '.join, - (ops,halfops,voices,usersS)))) + usersS = ', '.join(filter(None, list(map(', '.join, + (ops,halfops,voices,usersS))))) users.append(format('%s (%i): %s', ircutils.bold(network), numUsers, usersS)) users.sort() diff --git a/plugins/Scheduler/plugin.py b/plugins/Scheduler/plugin.py index 226f12e45..28d34b631 100644 --- a/plugins/Scheduler/plugin.py +++ b/plugins/Scheduler/plugin.py @@ -58,12 +58,12 @@ class Scheduler(callbacks.Plugin): pkl = open(filename, 'rb') try: eventdict = pickle.load(pkl) - except Exception, e: + except Exception as e: self.log.debug('Unable to load pickled data: %s', e) return finally: pkl.close() - except IOError, e: + except IOError as e: self.log.debug('Unable to open pickle file: %s', e) return for name, event in eventdict.iteritems(): @@ -81,7 +81,7 @@ class Scheduler(callbacks.Plugin): elif event['type'] == 'repeat': # repeating event self._repeat(ircobj, event['msg'], name, event['time'], event['command'], False) - except AssertionError, e: + except AssertionError as e: if str(e) == 'An event with the same name has already been scheduled.': # we must be reloading the plugin, event is still scheduled self.log.info('Event %s already exists, adding to dict.' % (name,)) @@ -95,11 +95,11 @@ class Scheduler(callbacks.Plugin): pkl = os.fdopen(pklfd, 'wb') try: pickle.dump(self.events, pkl) - except Exception, e: + except Exception as e: self.log.warning('Unable to store pickled data: %s', e) pkl.close() shutil.move(tempfn, filename) - except (IOError, shutil.Error), e: + except (IOError, shutil.Error) as e: self.log.warning('File error: %s', e) def die(self): diff --git a/plugins/Seen/plugin.py b/plugins/Seen/plugin.py index 65542ae0e..f3491afa7 100644 --- a/plugins/Seen/plugin.py +++ b/plugins/Seen/plugin.py @@ -369,7 +369,7 @@ class Seen(callbacks.Plugin): msgs = [m for m in irc.state.history[i:end] if m.command == 'PRIVMSG' and ircutils.strEqual(m.args[0], channel)] if msgs: - irc.reply(format('%L', map(ircmsgs.prettyPrint, msgs))) + irc.reply(format('%L', list(map(ircmsgs.prettyPrint, msgs)))) else: irc.reply(format(_('Either %s didn\'t leave, ' 'or no messages were sent while %s was gone.'), nick, nick)) diff --git a/plugins/Services/config.py b/plugins/Services/config.py index 45d606e6a..67dd6014e 100644 --- a/plugins/Services/config.py +++ b/plugins/Services/config.py @@ -58,8 +58,7 @@ def configure(advanced): class ValidNickOrEmptyString(registry.String): def setValue(self, v): if v and not ircutils.isNick(v): - raise registry.InvalidRegistryValue, \ - 'Value must be a valid nick or the empty string.' + raise registry.InvalidRegistryValue('Value must be a valid nick or the empty string.') registry.String.setValue(self, v) class ValidNickSet(conf.ValidNicks): diff --git a/plugins/ShrinkUrl/config.py b/plugins/ShrinkUrl/config.py index 5bf421e79..675f6e28a 100644 --- a/plugins/ShrinkUrl/config.py +++ b/plugins/ShrinkUrl/config.py @@ -62,9 +62,8 @@ class ShrinkCycle(registry.SpaceSeparatedListOfStrings): if L: self.lastIndex = (self.lastIndex + 1) % len(L) return L[self.lastIndex] - raise ValueError, \ - 'No services have been configured for rotation. ' \ - 'See conf.supybot.plugins.ShrinkUrl.serviceRotation.' + raise ValueError('No services have been configured for rotation. ' \ + 'See conf.supybot.plugins.ShrinkUrl.serviceRotation.') ShrinkUrl = conf.registerPlugin('ShrinkUrl') conf.registerChannelValue(ShrinkUrl, 'shrinkSnarfer', diff --git a/plugins/ShrinkUrl/plugin.py b/plugins/ShrinkUrl/plugin.py index 3417c7ab6..f9981a2f9 100644 --- a/plugins/ShrinkUrl/plugin.py +++ b/plugins/ShrinkUrl/plugin.py @@ -98,7 +98,7 @@ class ShrinkUrl(callbacks.PluginRegexp): def callCommand(self, command, irc, msg, *args, **kwargs): try: self.__parent.callCommand(command, irc, msg, *args, **kwargs) - except utils.web.Error, e: + except utils.web.Error as e: irc.error(str(e)) def _outFilterThread(self, irc, msg): @@ -182,7 +182,7 @@ class ShrinkUrl(callbacks.PluginRegexp): self.db.set('ln', url, text) return text else: - raise ShrinkError, text + raise ShrinkError(text) @internationalizeDocstring def ln(self, irc, msg, args, url): @@ -195,7 +195,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(lnurl) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.error(str(e)) ln = thread(wrap(ln, ['url'])) @@ -207,7 +207,7 @@ class ShrinkUrl(callbacks.PluginRegexp): text = utils.web.getUrl('http://tinyurl.com/api-create.php?url=' + url) text = text.decode() if text.startswith('Error'): - raise ShrinkError, text[5:] + raise ShrinkError(text[5:]) self.db.set('tiny', url, text) return text @@ -222,7 +222,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(tinyurl) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.errorPossibleBug(str(e)) tiny = thread(wrap(tiny, ['url'])) @@ -236,7 +236,7 @@ class ShrinkUrl(callbacks.PluginRegexp): data = utils.web.urlencode({'long_url': url}) text = utils.web.getUrl(self._xrlApi, data=data).decode() if text.startswith('ERROR:'): - raise ShrinkError, text[6:] + raise ShrinkError(text[6:]) self.db.set('xrl', quotedurl, text) return text @@ -251,7 +251,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(xrlurl) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.error(str(e)) xrl = thread(wrap(xrl, ['url'])) @@ -271,7 +271,7 @@ class ShrinkUrl(callbacks.PluginRegexp): self.db.set('goo', url, googl) return googl else: - raise ShrinkError, text + raise ShrinkError(text) def goo(self, irc, msg, args, url): """ @@ -283,7 +283,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(goourl) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.error(str(e)) goo = thread(wrap(goo, ['url'])) @@ -301,7 +301,7 @@ class ShrinkUrl(callbacks.PluginRegexp): self.db.set('ur1', url, ur1ca) return ur1ca else: - raise ShrinkError, text + raise ShrinkError(text) def ur1(self, irc, msg, args, url): """ @@ -313,7 +313,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(ur1url) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.error(str(e)) ur1 = thread(wrap(ur1, ['url'])) @@ -325,7 +325,7 @@ class ShrinkUrl(callbacks.PluginRegexp): except KeyError: text = utils.web.getUrl(self._x0Api % url).decode() if text.startswith('ERROR:'): - raise ShrinkError, text[6:] + raise ShrinkError(text[6:]) self.db.set('x0', url, text) return text @@ -340,7 +340,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(x0url) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.error(str(e)) x0 = thread(wrap(x0, ['url'])) @@ -367,7 +367,7 @@ class ShrinkUrl(callbacks.PluginRegexp): m = irc.reply(expandurl) if m is not None: m.tag('shrunken') - except ShrinkError, e: + except ShrinkError as e: irc.error(str(e)) expand = thread(wrap(expand, ['url'])) diff --git a/plugins/String/plugin.py b/plugins/String/plugin.py index 8f001340c..a22a1b5cb 100644 --- a/plugins/String/plugin.py +++ b/plugins/String/plugin.py @@ -203,7 +203,7 @@ class String(callbacks.Plugin): try: v = process(f, text, timeout=t, pn=self.name(), cn='re') irc.reply(v) - except commands.ProcessTimeoutError, e: + except commands.ProcessTimeoutError as e: irc.error("ProcessTimeoutError: %s" % (e,)) re = thread(wrap(re, [first('regexpMatcher', 'regexpReplacer'), 'text'])) @@ -216,7 +216,7 @@ class String(callbacks.Plugin): encryption. """ chars = utils.iter.cycle(password) - ret = [chr(ord(c) ^ ord(chars.next())) for c in text] + ret = [chr(ord(c) ^ ord(next(chars))) for c in text] irc.reply(''.join(ret)) xor = wrap(xor, ['something', 'text']) diff --git a/plugins/Topic/plugin.py b/plugins/Topic/plugin.py index d83593d92..b21d07b51 100644 --- a/plugins/Topic/plugin.py +++ b/plugins/Topic/plugin.py @@ -105,7 +105,7 @@ addConverter('topicNumber', getTopicNumber) addConverter('canChangeTopic', canChangeTopic) def splitTopic(topic, separator): - return filter(None, topic.split(separator)) + return list(filter(None, topic.split(separator))) datadir = conf.supybot.directories.data() filename = conf.supybot.directories.data.dirize('Topic.pickle') @@ -125,10 +125,10 @@ class Topic(callbacks.Plugin): self.redos = pickle.load(pkl) self.lastTopics = pickle.load(pkl) self.watchingFor332 = pickle.load(pkl) - except Exception, e: + except Exception as e: self.log.debug('Unable to load pickled data: %s', e) pkl.close() - except IOError, e: + except IOError as e: self.log.debug('Unable to open pickle file: %s', e) world.flushers.append(self._flush) @@ -145,11 +145,11 @@ class Topic(callbacks.Plugin): pickle.dump(self.redos, pkl) pickle.dump(self.lastTopics, pkl) pickle.dump(self.watchingFor332, pkl) - except Exception, e: + except Exception as e: self.log.warning('Unable to store pickled data: %s', e) pkl.close() shutil.move(tempfn, filename) - except (IOError, shutil.Error), e: + except (IOError, shutil.Error) as e: self.log.warning('File error: %s', e) def _splitTopic(self, topic, channel): diff --git a/plugins/Unix/plugin.py b/plugins/Unix/plugin.py index 436e25162..4816f2b21 100644 --- a/plugins/Unix/plugin.py +++ b/plugins/Unix/plugin.py @@ -153,7 +153,7 @@ class Unix(callbacks.Plugin): stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - except OSError, e: + except OSError as e: irc.error(e, Raise=True) ret = inst.poll() if ret is not None: @@ -214,13 +214,13 @@ class Unix(callbacks.Plugin): stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(os.devnull)) - except OSError, e: + except OSError as e: irc.error(_('It seems the configured fortune command was ' 'not available.'), Raise=True) (out, err) = inst.communicate() inst.wait() lines = out.splitlines() - lines = map(str.rstrip, lines) + lines = list(map(str.rstrip, lines)) lines = filter(None, lines) irc.replies(lines, joiner=' ') else: @@ -294,7 +294,7 @@ class Unix(callbacks.Plugin): inst = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(os.devnull)) - except OSError, e: + except OSError as e: irc.error('It seems the configured ping command was ' 'not available (%s).' % e, Raise=True) result = inst.communicate() @@ -327,7 +327,7 @@ class Unix(callbacks.Plugin): stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(os.devnull)) - except OSError, e: + except OSError as e: irc.error('It seems the configured uptime command was ' 'not available.', Raise=True) (out, err) = inst.communicate() @@ -355,7 +355,7 @@ class Unix(callbacks.Plugin): stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(os.devnull)) - except OSError, e: + except OSError as e: irc.error('It seems the configured uptime command was ' 'not available.', Raise=True) (out, err) = inst.communicate() @@ -384,7 +384,7 @@ class Unix(callbacks.Plugin): inst = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(os.devnull)) - except OSError, e: + except OSError as e: irc.error('It seems the requested command was ' 'not available (%s).' % e, Raise=True) result = inst.communicate() diff --git a/plugins/User/plugin.py b/plugins/User/plugin.py index e0f0c4b93..bbab7552c 100644 --- a/plugins/User/plugin.py +++ b/plugins/User/plugin.py @@ -46,7 +46,7 @@ _ = PluginInternationalization('User') class User(callbacks.Plugin): def _checkNotChannel(self, irc, msg, password=' '): if password and irc.isChannel(msg.args[0]): - raise callbacks.Error, conf.supybot.replies.requiresPrivacy() + raise callbacks.Error(conf.supybot.replies.requiresPrivacy()) @internationalizeDocstring def list(self, irc, msg, args, optlist, glob): @@ -281,7 +281,7 @@ class User(callbacks.Plugin): command. """ def getHostmasks(user): - hostmasks = map(repr, user.hostmasks) + hostmasks = list(map(repr, user.hostmasks)) if hostmasks: hostmasks.sort() return format('%L', hostmasks) @@ -350,11 +350,11 @@ class User(callbacks.Plugin): Raise=True) try: user.addHostmask(hostmask) - except ValueError, e: + except ValueError as e: irc.error(str(e), Raise=True) try: ircdb.users.setUser(user) - except ValueError, e: + except ValueError as e: irc.error(str(e), Raise=True) except ircdb.DuplicateHostmask: irc.error(_('That hostmask is already registered.'), @@ -416,7 +416,7 @@ class User(callbacks.Plugin): def _expire_tokens(self): now = time.time() - self._tokens = dict(filter(lambda (x,y): y[1]>now, + self._tokens = dict(filter(lambda x_y: x_y[1][1]>now, self._tokens.items())) @internationalizeDocstring @@ -511,7 +511,7 @@ class User(callbacks.Plugin): prefix, expiry = self._tokens.pop(token) found = False for (id, user) in ircdb.users.items(): - if keyid in map(lambda x:x[-len(keyid):], user.gpgkeys): + if keyid in [x[-len(keyid):] for x in user.gpgkeys]: user.addAuth(msg.prefix) ircdb.users.setUser(user, flush=False) irc.reply(_('You are now authenticated as %s.') % diff --git a/plugins/Utilities/plugin.py b/plugins/Utilities/plugin.py index 8d0452603..ee3807821 100644 --- a/plugins/Utilities/plugin.py +++ b/plugins/Utilities/plugin.py @@ -75,7 +75,7 @@ class Utilities(callbacks.Plugin): nested commands to run, but only the output of the last one to be returned. """ - args = filter(None, args) + args = list(filter(None, args)) if args: irc.reply(args[-1]) else: @@ -113,7 +113,7 @@ class Utilities(callbacks.Plugin): try: samp = random.sample(things, num) irc.reply(' '.join(samp)) - except ValueError, e: + except ValueError as e: irc.error('%s' % (e,)) sample = wrap(sample, ['positiveInt', many('anything')]) @@ -135,7 +135,7 @@ class Utilities(callbacks.Plugin): args = [token and token or '""' for token in rest] text = ' '.join(args) commands = command.split() - commands = map(callbacks.canonicalName, commands) + commands = list(map(callbacks.canonicalName, commands)) tokens = callbacks.tokenize(text) allTokens = commands + tokens self.Proxy(irc, msg, allTokens) diff --git a/plugins/Web/plugin.py b/plugins/Web/plugin.py index a90b5d1bf..20bb233b8 100644 --- a/plugins/Web/plugin.py +++ b/plugins/Web/plugin.py @@ -93,7 +93,7 @@ def fetch_sandbox(f): try: replies = commands.process(process, self, irc, *args, timeout=5, heap_size=1024*1024, - pn=self.name(), cn=f.func_name) + pn=self.name(), cn=f.__name__) except commands.ProcessTimeoutError: raise utils.web.Error(_('Page is too big.')) else: @@ -135,7 +135,7 @@ class Web(callbacks.PluginRegexp): fd = utils.web.getUrlFd(url) text = fd.read(size) fd.close() - except socket.timeout, e: + except socket.timeout as e: self.log.info('Couldn\'t snarf title of %u: %s.', url, e) if self.registryValue('snarferReportIOExceptions', channel): irc.reply(url+" : "+utils.web.TIMED_OUT, prefixNick=False) diff --git a/plugins/Web/test.py b/plugins/Web/test.py index d60ba9d5f..ba39e3e83 100644 --- a/plugins/Web/test.py +++ b/plugins/Web/test.py @@ -65,9 +65,9 @@ class WebTestCase(ChannelPluginTestCase): # part of it. self.assertRegexp('title http://www.n-e-r-d.com/', 'N.*E.*R.*D') # Checks that the parser doesn't hang on invalid tags - print - print "If we have not fixed a bug with the parser, the following", - print "test will hang the test-suite." + print() + print("If we have not fixed a bug with the parser, the following") + print("test will hang the test-suite.") self.assertNotError( 'title http://www.youtube.com/watch?v=x4BtiqPN4u8') diff --git a/plugins/__init__.py b/plugins/__init__.py index cdda215dc..57edd67a1 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -83,7 +83,7 @@ def DB(filename, types): return types[type](fn, *args, **kwargs) except KeyError: continue - raise NoSuitableDatabase, types.keys() + raise NoSuitableDatabase(types.keys()) return MakeDB def makeChannelFilename(filename, channel=None, dirname=None): @@ -191,15 +191,18 @@ class ChannelUserDictionary(collections.MutableMapping): def __init__(self): self.channels = ircutils.IrcDict() - def __getitem__(self, (channel, id)): + def __getitem__(self, key): + (channel, id) = key return self.channels[channel][id] - def __setitem__(self, (channel, id), v): + def __setitem__(self, key, v): + (channel, id) = key if channel not in self.channels: self.channels[channel] = self.IdDict() self.channels[channel][id] = v - def __delitem__(self, (channel, id)): + def __delitem__(self, key): + (channel, id) = key del self.channels[channel][id] def __iter__(self): @@ -233,7 +236,7 @@ class ChannelUserDB(ChannelUserDictionary): self.filename = filename try: fd = open(self.filename) - except EnvironmentError, e: + except EnvironmentError as e: log.warning('Couldn\'t open %s: %s.', self.filename, e) return reader = csv.reader(fd) @@ -251,11 +254,11 @@ class ChannelUserDB(ChannelUserDictionary): pass v = self.deserialize(channel, id, t) self[channel, id] = v - except Exception, e: + except Exception as e: log.warning('Invalid line #%s in %s.', lineno, self.__class__.__name__) log.debug('Exception: %s', utils.exnToString(e)) - except Exception, e: # This catches exceptions from csv.reader. + except Exception as e: # This catches exceptions from csv.reader. log.warning('Invalid line #%s in %s.', lineno, self.__class__.__name__) log.debug('Exception: %s', utils.exnToString(e)) @@ -503,7 +506,7 @@ class PeriodicFileDownloader(object): periodicFiles = None def __init__(self): if self.periodicFiles is None: - raise ValueError, 'You must provide files to download' + raise ValueError('You must provide files to download') self.lastDownloaded = {} self.downloadedCounter = {} for filename in self.periodicFiles: @@ -525,10 +528,10 @@ class PeriodicFileDownloader(object): try: try: infd = utils.web.getUrlFd(url) - except IOError, e: + except IOError as e: self.log.warning('Error downloading %s: %s', url, e) return - except utils.web.Error, e: + except utils.web.Error as e: self.log.warning('Error downloading %s: %s', url, e) return confDir = conf.supybot.directories.data() diff --git a/setup.py b/setup.py index e75e71143..1cf932e5b 100644 --- a/setup.py +++ b/setup.py @@ -148,10 +148,17 @@ try: def log_debug(self, msg, *args): log.debug(msg, *args) - fixer_names = get_fixers_from_package('lib2to3.fixes') - fixer_names.remove('lib2to3.fixes.fix_import') - fixer_names += get_fixers_from_package('2to3') - r = DistutilsRefactoringTool(fixer_names, options=options) + fixer_names = ['fix_basestring', + 'fix_dict', + 'fix_imports', + 'fix_long', + 'fix_metaclass', 'fix_methodattrs', + 'fix_numliterals', + 'fix_types', + 'fix_unicode', 'fix_urllib', 'fix_xrange'] + fixers = list(map(lambda x:'lib2to3.fixes.'+x, fixer_names)) + fixers += get_fixers_from_package('2to3') + r = DistutilsRefactoringTool(fixers, options=options) r.refactor(files, write=True) except ImportError: # 2.x diff --git a/src/callbacks.py b/src/callbacks.py index 074211a73..adf288a14 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -91,7 +91,7 @@ def _addressed(nick, msg, prefixChars=None, nicks=None, return payload[1:].strip() if nicks is None: nicks = get(conf.supybot.reply.whenAddressedBy.nicks) - nicks = map(ircutils.toLower, nicks) + nicks = list(map(ircutils.toLower, nicks)) else: nicks = list(nicks) # Just in case. nicks.insert(0, ircutils.toLower(nick)) @@ -315,11 +315,11 @@ class Tokenizer(object): while True: token = lexer.get_token() if not token: - raise SyntaxError, _('Missing "%s". You may want to ' + raise SyntaxError(_('Missing "%s". You may want to ' 'quote your arguments with double ' 'quotes in order to prevent extra ' 'brackets from being evaluated ' - 'as nested commands.') % self.right + 'as nested commands.') % self.right) elif token == self.right: return ret elif token == self.left: @@ -345,26 +345,26 @@ class Tokenizer(object): # for strings like 'foo | bar', where a pipe stands alone as a # token, but shouldn't be treated specially. if not args: - raise SyntaxError, _('"|" with nothing preceding. I ' + raise SyntaxError(_('"|" with nothing preceding. I ' 'obviously can\'t do a pipe with ' - 'nothing before the |.') + 'nothing before the |.')) ends.append(args) args = [] elif token == self.left: args.append(self._insideBrackets(lexer)) elif token == self.right: - raise SyntaxError, _('Spurious "%s". You may want to ' + raise SyntaxError(_('Spurious "%s". You may want to ' 'quote your arguments with double ' 'quotes in order to prevent extra ' 'brackets from being evaluated ' - 'as nested commands.') % self.right + 'as nested commands.') % self.right) else: args.append(self._handleToken(token)) if ends: if not args: - raise SyntaxError, _('"|" with nothing following. I ' + raise SyntaxError(_('"|" with nothing following. I ' 'obviously can\'t do a pipe with ' - 'nothing after the |.') + 'nothing after the |.')) args.append(ends.pop()) while ends: args[-1].append(ends.pop()) @@ -384,8 +384,8 @@ def tokenize(s, channel=None): try: ret = Tokenizer(brackets=brackets,pipe=pipe,quotes=quotes).tokenize(s) return ret - except ValueError, e: - raise SyntaxError, str(e) + except ValueError as e: + raise SyntaxError(str(e)) def formatCommand(command): return ' '.join(command) @@ -399,7 +399,7 @@ def checkCommandCapability(msg, cb, commandName): if ircdb.checkCapability(msg.prefix, capability): log.info('Preventing %s from calling %s because of %s.', msg.prefix, pluginCommand, capability) - raise RuntimeError, capability + raise RuntimeError(capability) try: antiPlugin = ircdb.makeAntiCapability(plugin) antiCommand = ircdb.makeAntiCapability(commandName) @@ -424,7 +424,7 @@ def checkCommandCapability(msg, cb, commandName): return not (default or \ any(lambda x: ircdb.checkCapability(msg.prefix, x), checkAtEnd)) - except RuntimeError, e: + except RuntimeError as e: s = ircdb.unAntiCapability(str(e)) return s @@ -497,7 +497,7 @@ class RichReplyMethods(object): def _error(self, s, Raise=False, **kwargs): if Raise: - raise Error, s + raise Error(s) else: return self.error(s, **kwargs) @@ -598,7 +598,7 @@ class ReplyIrcProxy(RichReplyMethods): def error(self, s, msg=None, **kwargs): if 'Raise' in kwargs and kwargs['Raise']: if s: - raise Error, s + raise Error(s) else: raise ArgumentError if msg is None: @@ -717,9 +717,9 @@ class NestedCommandsIrcProxy(ReplyIrcProxy): log.debug('Calling %s.invalidCommand.', cb.name()) try: cb.invalidCommand(self, self.msg, self.args) - except Error, e: + except Error as e: self.error(str(e)) - except Exception, e: + except Exception as e: log.exception('Uncaught exception in %s.invalidCommand.', cb.name()) log.debug('Finished calling %s.invalidCommand.', cb.name()) @@ -738,7 +738,7 @@ class NestedCommandsIrcProxy(ReplyIrcProxy): """Returns a two-tuple of (command, plugins) that has the command (a list of strings) and the plugins for which it was a command.""" assert isinstance(args, list) - args = map(canonicalName, args) + args = list(map(canonicalName, args)) cbs = [] maxL = [] for cb in self.irc.callbacks: @@ -783,7 +783,7 @@ class NestedCommandsIrcProxy(ReplyIrcProxy): # 3. Whether an importantPlugin is one of the responses. important = defaultPlugins.importantPlugins() - important = map(canonicalName, important) + important = list(map(canonicalName, important)) importants = [] for cb in cbs: if cb.canonicalName() in important: @@ -992,7 +992,7 @@ class NestedCommandsIrcProxy(ReplyIrcProxy): self.repliedTo = True if Raise: if s: - raise Error, s + raise Error(s) else: raise ArgumentError if s: @@ -1170,7 +1170,7 @@ class Commands(BasePlugin): if hasattr(self, name): method = getattr(self, name) if inspect.ismethod(method): - code = method.im_func.func_code + code = method.im_func.__code__ return inspect.getargs(code)[0] == self.commandArgs else: return False @@ -1188,7 +1188,7 @@ class Commands(BasePlugin): return self.getCommand(command) == command def getCommand(self, args, stripOwnName=True): - assert args == map(canonicalName, args) + assert args == list(map(canonicalName, args)) first = args[0] for cb in self.cbs: if first == cb.canonicalName(): @@ -1206,7 +1206,7 @@ class Commands(BasePlugin): """Gets the given command from this plugin.""" #print '*** %s.getCommandMethod(%r)' % (self.name(), command) assert not isinstance(command, basestring) - assert command == map(canonicalName, command) + assert command == list(map(canonicalName, command)) assert self.getCommand(command) == command for cb in self.cbs: if command[0] == cb.canonicalName(): @@ -1217,7 +1217,7 @@ class Commands(BasePlugin): else: method = getattr(self, command[0]) if inspect.ismethod(method): - code = method.im_func.func_code + code = method.im_func.__code__ if inspect.getargs(code)[0] == self.commandArgs: return method else: @@ -1269,7 +1269,7 @@ class Commands(BasePlugin): self.callingCommand = None except SilentError: pass - except (getopt.GetoptError, ArgumentError), e: + except (getopt.GetoptError, ArgumentError) as e: self.log.debug('Got %s, giving argument error.', utils.exnToString(e)) help = self.getCommandHelp(command) @@ -1277,10 +1277,10 @@ class Commands(BasePlugin): irc.error(_('Invalid arguments for %s.') % method.__name__) else: irc.reply(help) - except (SyntaxError, Error), e: + except (SyntaxError, Error) as e: self.log.debug('Error return: %s', utils.exnToString(e)) irc.error(str(e)) - except Exception, e: + except Exception as e: self.log.exception('Uncaught exception in %s.', command) if conf.supybot.reply.error.detailed(): irc.error(utils.exnToString(e)) @@ -1444,9 +1444,9 @@ class PluginRegexp(Plugin): method = getattr(self, name) try: method(irc, msg, m) - except Error, e: + except Error as e: irc.error(str(e)) - except Exception, e: + except Exception as e: self.log.exception('Uncaught exception in _callRegexp:') def invalidCommand(self, irc, msg, tokens): diff --git a/src/cdb.py b/src/cdb.py index 150860239..b10b3ca56 100644 --- a/src/cdb.py +++ b/src/cdb.py @@ -80,7 +80,7 @@ def open_db(filename, mode='r', **kwargs): maker.finish() return ReaderWriter(filename, **kwargs) else: - raise ValueError, 'Invalid flag: %s' % mode + raise ValueError('Invalid flag: %s' % mode) def shelf(filename, *args, **kwargs): """Opens a new shelf database object.""" @@ -118,7 +118,7 @@ def make(dbFilename, readFilename=None): else: readfd = open(readFilename, 'rb') maker = Maker(dbFilename) - while 1: + while True: (initchar, key, value) = _readKeyValue(readfd) if initchar is None: break @@ -257,7 +257,7 @@ class Reader(utils.IterableMap): try: return self.default except AttributeError: - raise KeyError, key + raise KeyError(key) def findall(self, key): ret = [] @@ -318,7 +318,7 @@ class ReaderWriter(utils.IterableMap): adds = {} try: fd = open(self.journalName, 'r') - while 1: + while True: (initchar, key, value) = _readKeyValue(fd) if initchar is None: break @@ -377,7 +377,7 @@ class ReaderWriter(utils.IterableMap): def __getitem__(self, key): if key in self.removals: - raise KeyError, key + raise KeyError(key) else: try: return self.adds[key] @@ -386,7 +386,7 @@ class ReaderWriter(utils.IterableMap): def __delitem__(self, key): if key in self.removals: - raise KeyError, key + raise KeyError(key) else: if key in self.adds and key in self.cdb: self._journalRemoveKey(key) @@ -398,7 +398,7 @@ class ReaderWriter(utils.IterableMap): elif key in self.cdb: self._journalRemoveKey(key) else: - raise KeyError, key + raise KeyError(key) self.mods += 1 self._flushIfOverLimit() diff --git a/src/commands.py b/src/commands.py index 29c605239..6611b0435 100644 --- a/src/commands.py +++ b/src/commands.py @@ -67,7 +67,7 @@ def thread(f): t.start() else: f(self, irc, msg, args, *L, **kwargs) - return utils.python.changeFunctionName(newf, f.func_name, f.__doc__) + return utils.python.changeFunctionName(newf, f.__name__, f.__doc__) class ProcessTimeoutError(Exception): """Gets raised when a process is killed due to timeout.""" @@ -121,7 +121,7 @@ def process(f, *args, **kwargs): p.join(timeout) if p.is_alive(): p.terminate() - raise ProcessTimeoutError, "%s aborted due to timeout." % (p.name,) + raise ProcessTimeoutError("%s aborted due to timeout." % (p.name,)) try: v = q.get(block=False) except Queue.Empty: @@ -160,7 +160,7 @@ class UrlSnarfThread(world.SupyThread): def run(self): try: super(UrlSnarfThread, self).run() - except utils.web.Error, e: + except utils.web.Error as e: log.debug('Exception in urlSnarfer: %s', utils.exnToString(e)) class SnarfQueue(ircutils.FloodQueue): @@ -219,7 +219,7 @@ def urlSnarfer(f): L = list(L) t = UrlSnarfThread(target=doSnarf, url=url) t.start() - newf = utils.python.changeFunctionName(newf, f.func_name, f.__doc__) + newf = utils.python.changeFunctionName(newf, f.__name__, f.__doc__) return newf @@ -301,7 +301,7 @@ def getId(irc, msg, args, state, kind=None): try: args[0] = args[0].lstrip('#') getInt(irc, msg, args, state, type=type) - except Exception, e: + except Exception as e: args[0] = original raise @@ -798,8 +798,8 @@ class UnknownConverter(KeyError): def getConverter(name): try: return wrappers[name] - except KeyError, e: - raise UnknownConverter, str(e) + except KeyError as e: + raise UnknownConverter(str(e)) def callConverter(name, irc, msg, args, state, *L): getConverter(name)(irc, msg, args, state, *L) @@ -852,7 +852,7 @@ class rest(context): args[:] = [' '.join(args)] try: super(rest, self).__call__(irc, msg, args, state) - except Exception, e: + except Exception as e: args[:] = original else: raise IndexError @@ -878,7 +878,7 @@ class optional(additional): def __call__(self, irc, msg, args, state): try: super(optional, self).__call__(irc, msg, args, state) - except (callbacks.ArgumentError, callbacks.Error), e: + except (callbacks.ArgumentError, callbacks.Error) as e: log.debug('Got %s, returning default.', utils.exnToString(e)) state.errored = False setDefault(state, self.default) @@ -896,7 +896,7 @@ class any(context): self.__parent.__call__(irc, msg, args, st) except IndexError: pass - except (callbacks.ArgumentError, callbacks.Error), e: + except (callbacks.ArgumentError, callbacks.Error) as e: if not self.continueOnError: raise else: @@ -917,7 +917,7 @@ class first(context): self.default = kw.pop('default') assert not kw, 'Bad kwargs for first.__init__' self.spec = specs # for __repr__ - self.specs = map(contextify, specs) + self.specs = list(map(contextify, specs)) def __call__(self, irc, msg, args, state): errored = False @@ -925,7 +925,7 @@ class first(context): try: spec(irc, msg, args, state) return - except Exception, e: + except Exception as e: e2 = e # 'e' is local. errored = state.errored state.errored = False @@ -956,7 +956,7 @@ class commalist(context): if part: # trailing commas super(commalist, self).__call__(irc, msg, [part], st) state.args.append(st.args) - except Exception, e: + except Exception as e: args[:] = original raise @@ -1024,7 +1024,7 @@ class State(object): self.errored = True return getattr(dynamic.irc, attr) else: - raise AttributeError, attr + raise AttributeError(attr) def essence(self): st = State(self.types) @@ -1068,7 +1068,7 @@ class Spec(object): return state def _wrap(f, specList=[], name=None, checkDoc=True, **kw): - name = name or f.func_name + name = name or f.__name__ assert (not checkDoc) or (hasattr(f, '__doc__') and f.__doc__), \ 'Command %r has no docstring.' % name spec = Spec(specList, **kw) @@ -1083,7 +1083,7 @@ def _wrap(f, specList=[], name=None, checkDoc=True, **kw): except TypeError: self.log.error('Spec: %s', specList) self.log.error('Received args: %s', args) - code = f.func_code + code = f.__code__ funcArgs = inspect.getargs(code)[0][len(self.commandArgs):] self.log.error('Extra args: %s', funcArgs) self.log.debug('Make sure you did not wrap a wrapped ' diff --git a/src/conf.py b/src/conf.py index 9b3b0441f..5e1214295 100644 --- a/src/conf.py +++ b/src/conf.py @@ -839,7 +839,7 @@ class Databases(registry.SpaceSeparatedListOfStrings): def __call__(self): v = super(Databases, self).__call__() if not v: - v = ['anydbm', 'cdb', 'flat', 'pickle'] + v = ['anydbm', 'dbm', 'cdb', 'flat', 'pickle'] if 'sqlite' in sys.modules: v.insert(0, 'sqlite') if 'sqlite3' in sys.modules: diff --git a/src/dbi.py b/src/dbi.py index fbeeeea30..ab3999e48 100644 --- a/src/dbi.py +++ b/src/dbi.py @@ -117,7 +117,7 @@ class DirMapping(MappingInterface): try: fd = open(self._makeFilename(id)) return fd.read() - except EnvironmentError, e: + except EnvironmentError as e: exn = NoRecordError(id) exn.realException = e raise exn @@ -141,8 +141,8 @@ class DirMapping(MappingInterface): def remove(self, id): try: os.remove(self._makeFilename(id)) - except EnvironmentError, e: - raise NoRecordError, id + except EnvironmentError as e: + raise NoRecordError(id) class FlatfileMapping(MappingInterface): def __init__(self, filename, maxSize=10**6): @@ -154,8 +154,8 @@ class FlatfileMapping(MappingInterface): try: self.currentId = int(strId) except ValueError: - raise Error, 'Invalid file for FlatfileMapping: %s' % filename - except EnvironmentError, e: + raise Error('Invalid file for FlatfileMapping: %s' % filename) + except EnvironmentError as e: # File couldn't be opened. self.maxSize = int(math.log10(maxSize)) self.currentId = 0 @@ -209,7 +209,7 @@ class FlatfileMapping(MappingInterface): (lineId, s) = self._splitLine(line) if lineId == strId: return s - raise NoRecordError, id + raise NoRecordError(id) finally: fd.close() @@ -295,7 +295,7 @@ class CdbMapping(MappingInterface): try: return self.db[str(id)] except KeyError: - raise NoRecordError, id + raise NoRecordError(id) # XXX Same as above. def set(self, id, s): diff --git a/src/drivers/Socket.py b/src/drivers/Socket.py index 7045df269..cab96264a 100644 --- a/src/drivers/Socket.py +++ b/src/drivers/Socket.py @@ -82,7 +82,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): self.writeCheckTime = None self.nextReconnectTime = None self.resetDelay() - if self.networkGroup.get('ssl').value and not globals().has_key('ssl'): + if self.networkGroup.get('ssl').value and 'ssl' not in globals(): drivers.log.error('The Socket driver can not connect to SSL ' 'servers for your Python version. Try the ' 'Twisted driver instead, or install a Python' @@ -131,7 +131,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): while msgs[-1] is not None: msgs.append(self.irc.takeMsg()) del msgs[-1] - self.outbuffer += ''.join(imap(str, msgs)) + self.outbuffer += ''.join(map(str, msgs)) if self.outbuffer: try: if sys.version_info[0] < 3: @@ -140,7 +140,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): sent = self.conn.send(self.outbuffer.encode()) self.outbuffer = self.outbuffer[sent:] self.eagains = 0 - except socket.error, e: + except socket.error as e: self._handleSocketError(e) if self.zombie and not self.outbuffer: self._reallyDie() @@ -233,13 +233,13 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): self.irc.feedMsg(msg) except socket.timeout: pass - except SSLError, e: + except SSLError as e: if e.args[0] == 'The read operation timed out': pass else: self._handleSocketError(e) return - except socket.error, e: + except socket.error as e: self._handleSocketError(e) return if self.irc and not self.irc.zombie: @@ -295,7 +295,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): self.conn = utils.net.getSocket(address, socks_proxy) vhost = conf.supybot.protocols.irc.vhost() self.conn.bind((vhost, 0)) - except socket.error, e: + except socket.error as e: drivers.log.connectError(self.currentServer, e) self.scheduleReconnect() return @@ -304,7 +304,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): self.conn.settimeout(max(10, conf.supybot.drivers.poll()*10)) try: if getattr(conf.supybot.networks, self.irc.network).ssl(): - assert globals().has_key('ssl') + assert 'ssl' in globals() certfile = getattr(conf.supybot.networks, self.irc.network) \ .certfile() if not certfile: @@ -321,7 +321,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): setTimeout() self.connected = True self.resetDelay() - except socket.error, e: + except socket.error as e: if e.args[0] == 115: now = time.time() when = now + 60 diff --git a/src/dynamicScope.py b/src/dynamicScope.py index e1fd97fd2..322cf7e57 100644 --- a/src/dynamicScope.py +++ b/src/dynamicScope.py @@ -36,7 +36,7 @@ class DynamicScope(object): if name in f.f_locals: return f.f_locals f = f.f_back - raise NameError, name + raise NameError(name) def __getattr__(self, name): try: diff --git a/src/i18n.py b/src/i18n.py index 6085fd3fd..281661cfb 100644 --- a/src/i18n.py +++ b/src/i18n.py @@ -183,7 +183,7 @@ def parse(translationFile): i18nSupybot = None def PluginInternationalization(name='supybot'): # This is a proxy that prevents having several objects for the same plugin - if i18nClasses.has_key(name): + if name in i18nClasses: return i18nClasses[name] else: return _PluginInternationalization(name) @@ -282,8 +282,10 @@ class _PluginInternationalization: load its functions.""" if self.name != 'supybot': return + path = self._getL10nCodePath() try: - execfile(self._getL10nCodePath()) + with open(path) as fd: + exec(compile(fd.read(), path, 'exec')) except IOError: # File doesn't exist pass @@ -308,7 +310,7 @@ class _PluginInternationalization: if self.name != 'supybot': return if hasattr(self, '_l10nFunctions') and \ - self._l10nFunctions.has_key(name): + name in self._l10nFunctions: return self._l10nFunctions[name] def internationalizeFunction(self, name): @@ -357,7 +359,7 @@ def internationalizeDocstring(obj): Only useful for commands (commands' docstring is displayed on IRC)""" if obj.__doc__ == None: return obj - if sys.modules[obj.__module__].__dict__.has_key('_'): + if '_' in sys.modules[obj.__module__].__dict__: internationalizedCommands.update({hash(obj): obj}) try: obj.__doc__=sys.modules[obj.__module__]._.__call__(obj.__doc__) diff --git a/src/ircdb.py b/src/ircdb.py index 73dfb0288..f4f2eb2e8 100644 --- a/src/ircdb.py +++ b/src/ircdb.py @@ -80,7 +80,7 @@ def unAntiCapability(capability): """Takes an anticapability and returns the non-anti form.""" assert isCapability(capability), 'got %s' % capability if not isAntiCapability(capability): - raise ValueError, '%s is not an anti capability' % capability + raise ValueError('%s is not an anti capability' % capability) if isChannelCapability(capability): (channel, capability) = fromChannelCapability(capability) return ','.join((channel, capability[1:])) @@ -150,7 +150,7 @@ class CapabilitySet(set): def __repr__(self): return '%s([%s])' % (self.__class__.__name__, - ', '.join(imap(repr, self))) + ', '.join(map(repr, self))) antiOwner = makeAntiCapability('owner') class UserCapabilitySet(CapabilitySet): @@ -290,8 +290,7 @@ class IrcUser(object): """Adds a hostmask to the user's hostmasks.""" assert ircutils.isUserHostmask(hostmask), 'got %s' % hostmask if len(unWildcardHostmask(hostmask)) < 3: - raise ValueError, \ - 'Hostmask must contain at least 3 non-wildcard characters.' + raise ValueError('Hostmask must contain at least 3 non-wildcard characters.') self.hostmasks.add(hostmask) def removeHostmask(self, hostmask): @@ -334,10 +333,10 @@ class IrcUser(object): knownHostmasks.add(mask) return True return False - uniqued = filter(uniqueHostmask, reversed(self.auth)) + uniqued = list(filter(uniqueHostmask, reversed(self.auth))) self.auth = list(reversed(uniqued)) else: - raise ValueError, 'secure flag set, unmatched hostmask' + raise ValueError('secure flag set, unmatched hostmask') def clearAuth(self): """Unsets a user's authenticated hostmask.""" @@ -492,7 +491,7 @@ class IrcChannel(object): class Creator(object): def badCommand(self, command, rest, lineno): - raise ValueError, 'Invalid command on line %s: %s' % (lineno, command) + raise ValueError('Invalid command on line %s: %s' % (lineno, command)) class IrcUserCreator(Creator): u = None @@ -503,12 +502,12 @@ class IrcUserCreator(Creator): def user(self, rest, lineno): if self.u.id is not None: - raise ValueError, 'Unexpected user command on line %s.' % lineno + raise ValueError('Unexpected user command on line %s.' % lineno) self.u.id = int(rest) def _checkId(self): if self.u.id is None: - raise ValueError, 'Unexpected user description without user.' + raise ValueError('Unexpected user description without user.') def name(self, rest, lineno): self._checkId() @@ -571,12 +570,12 @@ class IrcChannelCreator(Creator): def channel(self, rest, lineno): if self.name is not None: - raise ValueError, 'Unexpected channel command on line %s' % lineno + raise ValueError('Unexpected channel command on line %s' % lineno) IrcChannelCreator.name = rest def _checkId(self): if self.name is None: - raise ValueError, 'Unexpected channel description without channel.' + raise ValueError('Unexpected channel description without channel.') def lobotomized(self, rest, lineno): self._checkId() @@ -629,10 +628,10 @@ class UsersDictionary(utils.IterableMap): reader.readFile(filename) self.noFlush = False self.flush() - except EnvironmentError, e: + except EnvironmentError as e: log.error('Invalid user dictionary file, resetting to empty.') log.error('Exact error: %s', utils.exnToString(e)) - except Exception, e: + except Exception as e: log.exception('Exact error:') finally: self.noFlush = False @@ -646,7 +645,7 @@ class UsersDictionary(utils.IterableMap): if self.filename is not None: try: self.open(self.filename) - except EnvironmentError, e: + except EnvironmentError as e: log.warning('UsersDictionary.reload failed: %s', e) else: log.error('UsersDictionary.reload called with no filename.') @@ -697,14 +696,14 @@ class UsersDictionary(utils.IterableMap): self._hostmaskCache[id] = set([s]) return id elif len(ids) == 0: - raise KeyError, s + raise KeyError(s) else: log.error('Multiple matches found in user database. ' 'Removing the offending hostmasks.') for (id, hostmask) in ids.iteritems(): log.error('Removing %q from user %s.', hostmask, id) self.users[id].removeHostmask(hostmask) - raise DuplicateHostmask, 'Ids %r matched.' % ids + raise DuplicateHostmask('Ids %r matched.' % ids) else: # Not a hostmask, must be a name. s = s.lower() try: @@ -716,7 +715,7 @@ class UsersDictionary(utils.IterableMap): self._nameCache[id] = s return id else: - raise KeyError, s + raise KeyError(s) def getUser(self, id): """Returns a user given its id, name, or hostmask.""" @@ -775,7 +774,7 @@ class UsersDictionary(utils.IterableMap): self.nextId = max(self.nextId, user.id) try: if self.getUserId(user.name) != user.id: - raise DuplicateHostmask, hostmask + raise DuplicateHostmask(hostmask) except KeyError: pass for hostmask in user.hostmasks: @@ -788,10 +787,10 @@ class UsersDictionary(utils.IterableMap): # raise an exception. So instead, we'll raise an # exception, but be nice and give the offending hostmask # back at the same time. - raise DuplicateHostmask, hostmask + raise DuplicateHostmask(hostmask) for otherHostmask in u.hostmasks: if ircutils.hostmaskPatternEqual(hostmask, otherHostmask): - raise DuplicateHostmask, hostmask + raise DuplicateHostmask(hostmask) self.invalidateCache(user.id) self.users[user.id] = user if flush: @@ -835,10 +834,10 @@ class ChannelsDictionary(utils.IterableMap): reader.readFile(filename) self.noFlush = False self.flush() - except EnvironmentError, e: + except EnvironmentError as e: log.error('Invalid channel database, resetting to empty.') log.error('Exact error: %s', utils.exnToString(e)) - except Exception, e: + except Exception as e: log.error('Invalid channel database, resetting to empty.') log.exception('Exact error:') finally: @@ -871,7 +870,7 @@ class ChannelsDictionary(utils.IterableMap): self.channels.clear() try: self.open(self.filename) - except EnvironmentError, e: + except EnvironmentError as e: log.warning('ChannelsDictionary.reload failed: %s', e) else: log.warning('ChannelsDictionary.reload without self.filename.') @@ -914,7 +913,7 @@ class IgnoresDB(object): else: expiration = 0 self.add(hostmask, expiration) - except Exception, e: + except Exception as e: log.error('Invalid line in ignores database: %q', line) fd.close() @@ -942,7 +941,7 @@ class IgnoresDB(object): self.hostmasks.clear() try: self.open(self.filename) - except EnvironmentError, e: + except EnvironmentError as e: log.warning('IgnoresDB.reload failed: %s', e) # Let's be somewhat transactional. self.hostmasks.update(oldhostmasks) @@ -972,7 +971,7 @@ try: userFile = os.path.join(confDir, conf.supybot.databases.users.filename()) users = UsersDictionary() users.open(userFile) -except EnvironmentError, e: +except EnvironmentError as e: log.warning('Couldn\'t open user database: %s', e) try: @@ -980,7 +979,7 @@ try: conf.supybot.databases.channels.filename()) channels = ChannelsDictionary() channels.open(channelFile) -except EnvironmentError, e: +except EnvironmentError as e: log.warning('Couldn\'t open channel database: %s', e) try: @@ -988,7 +987,7 @@ try: conf.supybot.databases.ignores.filename()) ignores = IgnoresDB() ignores.open(ignoreFile) -except EnvironmentError, e: +except EnvironmentError as e: log.warning('Couldn\'t open ignore database: %s', e) @@ -1084,7 +1083,7 @@ def checkCapability(hostmask, capability, users=users, channels=channels, # Raised when no hostmasks match. return _checkCapabilityForUnknownUser(capability, users=users, channels=channels) - except ValueError, e: + except ValueError as e: # Raised when multiple hostmasks match. log.warning('%s: %s', hostmask, e) return _checkCapabilityForUnknownUser(capability, users=users, @@ -1144,9 +1143,9 @@ class DefaultCapabilities(registry.SpaceSeparatedListOfStrings): def setValue(self, v, allowDefaultOwner=conf.allowDefaultOwner): registry.SpaceSeparatedListOfStrings.setValue(self, v) if '-owner' not in self.value and not allowDefaultOwner: - print '*** You must run supybot with the --allow-default-owner' - print '*** option in order to allow a default capability of owner.' - print '*** Don\'t do that, it\'s dumb.' + print('*** You must run supybot with the --allow-default-owner') + print('*** option in order to allow a default capability of owner.') + print('*** Don\'t do that, it\'s dumb.') self.value.add('-owner') conf.registerGlobalValue(conf.supybot, 'capabilities', diff --git a/src/irclib.py b/src/irclib.py index d640ffc36..4874e5189 100644 --- a/src/irclib.py +++ b/src/irclib.py @@ -205,8 +205,9 @@ class IrcMsgQueue(object): msg in self.lowpriority or \ msg in self.highpriority - def __nonzero__(self): + def __bool__(self): return bool(self.highpriority or self.normal or self.lowpriority) + __nonzero__ = __bool__ def __len__(self): return len(self.highpriority)+len(self.lowpriority)+len(self.normal) @@ -434,9 +435,9 @@ class IrcState(IrcCommandDispatcher): assert left[0] == '(', 'Odd PREFIX in 005: %s' % s left = left[1:] assert len(left) == len(right), 'Odd PREFIX in 005: %s' % s - return dict(zip(left, right)) + return dict(list(zip(left, right))) else: - return dict(zip('ovh', s)) + return dict(list(zip('ovh', s))) _005converters['prefix'] = _prefixParser del _prefixParser def _maxlistParser(s): @@ -447,7 +448,7 @@ class IrcState(IrcCommandDispatcher): (mode, limit) = pair.split(':', 1) modes += mode limits += (int(limit),) * len(mode) - return dict(zip(modes, limits)) + return dict(list(zip(modes, limits))) _005converters['maxlist'] = _maxlistParser del _maxlistParser def _maxbansParser(s): @@ -460,7 +461,7 @@ class IrcState(IrcCommandDispatcher): (mode, limit) = pair.split(':', 1) modes += mode limits += (int(limit),) * len(mode) - d = dict(zip(modes, limits)) + d = dict(list(zip(modes, limits))) assert 'b' in d return d['b'] else: @@ -474,7 +475,7 @@ class IrcState(IrcCommandDispatcher): converter = self._005converters.get(name, lambda x: x) try: self.supported[name] = converter(value) - except Exception, e: + except Exception as e: log.exception('Uncaught exception in 005 converter:') log.error('Name: %s, Converter: %s', name, converter) else: diff --git a/src/ircmsgs.py b/src/ircmsgs.py index 700b81576..325802f4a 100644 --- a/src/ircmsgs.py +++ b/src/ircmsgs.py @@ -85,7 +85,7 @@ class IrcMsg(object): def __init__(self, s='', command='', args=(), prefix='', msg=None): assert not (msg and s), 'IrcMsg.__init__ cannot accept both s and msg' if not s and not command and not msg: - raise MalformedIrcMsg, 'IRC messages require a command.' + raise MalformedIrcMsg('IRC messages require a command.') self._str = None self._repr = None self._hash = None @@ -109,7 +109,7 @@ class IrcMsg(object): self.args = s.split() self.command = self.args.pop(0) except (IndexError, ValueError): - raise MalformedIrcMsg, repr(originalString) + raise MalformedIrcMsg(repr(originalString)) else: if msg is not None: if prefix: diff --git a/src/ircutils.py b/src/ircutils.py index 428db6269..9c293e4dc 100644 --- a/src/ircutils.py +++ b/src/ircutils.py @@ -36,6 +36,7 @@ work in an IRC-case-insensitive fashion), and numerous other things. """ from __future__ import division +from __future__ import print_function import re import sys @@ -47,11 +48,12 @@ import functools from cStringIO import StringIO as sio from . import utils -from itertools import imap +from . import minisix + def debug(s, *args): """Prints a debug string. Most likely replaced by our logging debug.""" - print '***', s % args + print('***', s % args) userHostmaskRe = re.compile(r'^\S+!\S+@\S+$') def isUserHostmask(s): @@ -87,17 +89,17 @@ def splitHostmask(hostmask): assert isUserHostmask(hostmask) nick, rest = hostmask.split('!', 1) user, host = rest.split('@', 1) - return (intern(nick), intern(user), intern(host)) + return (minisix.intern(nick), minisix.intern(user), minisix.intern(host)) def joinHostmask(nick, ident, host): """nick, user, host => hostmask Joins the nick, ident, host into a user hostmask.""" assert nick and ident and host - return intern('%s!%s@%s' % (nick, ident, host)) + return minisix.intern('%s!%s@%s' % (nick, ident, host)) -_rfc1459trans = utils.str.MultipleReplacer(dict(zip( +_rfc1459trans = utils.str.MultipleReplacer(dict(list(zip( string.ascii_uppercase + r'\[]~', - string.ascii_lowercase + r'|{}^'))) + string.ascii_lowercase + r'|{}^')))) def toLower(s, casemapping=None): """s => s Returns the string s lowered according to IRC case rules.""" @@ -106,7 +108,7 @@ def toLower(s, casemapping=None): elif casemapping == 'ascii': # freenode return s.lower() else: - raise ValueError, 'Invalid casemapping: %r' % casemapping + raise ValueError('Invalid casemapping: %r' % casemapping) def strEqual(nick1, nick2): """s1, s2 => bool @@ -160,7 +162,7 @@ def areReceivers(s, strictRfc=True, nicklen=None, chantypes='#&+!', nick = functools.partial(isNick, strictRfc=strictRfc, nicklen=nicklen) chan = functools.partial(isChannel, chantypes=chantypes, channellen=channellen) - return all(map(lambda x:nick(x) or chan(x), s.split(','))) + return all([nick(x) or chan(x) for x in s.split(',')]) _patternCache = utils.structures.CacheDict(1000) def _hostmaskPatternEqual(pattern, hostmask): @@ -523,7 +525,7 @@ def unDccIP(i): L.append(i % 256) i //= 256 L.reverse() - return '.'.join(imap(str, L)) + return '.'.join(map(str, L)) class IrcString(str): """This class does case-insensitive comparison and hashing of nicks.""" diff --git a/src/log.py b/src/log.py index c5cfdbbe3..b5425e4e9 100644 --- a/src/log.py +++ b/src/log.py @@ -52,7 +52,8 @@ class Formatter(logging.Formatter): def formatTime(self, record, datefmt=None): return timestamp(record.created) - def formatException(self, (E, e, tb)): + def formatException(self, exc_info): + (E, e, tb) = exc_info for exn in deadlyExceptions: if issubclass(e.__class__, exn): raise @@ -95,9 +96,9 @@ class StdoutStreamHandler(logging.StreamHandler): # We check for ERROR there because otherwise, tracebacks (which are # already wrapped by Python itself) wrap oddly. if not isinstance(record.levelname, basestring): - print record - print record.levelname - print utils.stackTrace() + print(record) + print(record.levelname) + print(utils.stackTrace()) prefixLen = len(record.levelname) + 1 # ' ' s = textwrap.fill(s, width=78, subsequent_indent=' '*prefixLen) s.rstrip('\r\n') @@ -107,13 +108,13 @@ class StdoutStreamHandler(logging.StreamHandler): if conf.supybot.log.stdout() and not conf.daemonized: try: logging.StreamHandler.emit(self, record) - except ValueError, e: # Raised if sys.stdout is closed. + except ValueError as e: # Raised if sys.stdout is closed. self.disable() error('Error logging to stdout. Removing stdout handler.') exception('Uncaught exception in StdoutStreamHandler:') def disable(self): - self.setLevel(sys.maxint) # Just in case. + self.setLevel(sys.maxsize) # Just in case. _logger.removeHandler(self) logging._acquireLock() try: @@ -142,7 +143,8 @@ class ColorizedFormatter(Formatter): # This was necessary because these variables aren't defined until later. # The staticmethod is necessary because they get treated like methods. _fmtConf = staticmethod(lambda : conf.supybot.log.stdout.format()) - def formatException(self, (E, e, tb)): + def formatException(self, exc_info): + (E, e, tb) = exc_info if conf.supybot.log.stdout.colorized(): return ''.join([ansi.RED, Formatter.formatException(self, (E, e, tb)), @@ -184,13 +186,12 @@ if not os.path.exists(pluginLogDir): try: messagesLogFilename = os.path.join(_logDir, 'messages.log') _handler = BetterFileHandler(messagesLogFilename) -except EnvironmentError, e: - raise SystemExit, \ - 'Error opening messages logfile (%s). ' \ +except EnvironmentError as e: + raise SystemExit('Error opening messages logfile (%s). ' \ 'Generally, this is because you are running Supybot in a directory ' \ 'you don\'t have permissions to add files in, or you\'re running ' \ 'Supybot as a different user than you normal do. The original ' \ - 'error was: %s' % (messagesLogFilename, utils.gen.exnToString(e)) + 'error was: %s' % (messagesLogFilename, utils.gen.exnToString(e))) # These are public. formatter = Formatter('NEVER SEEN; IF YOU SEE THIS, FILE A BUG!') @@ -345,20 +346,20 @@ def firewall(f, errorHandler=None): logging_function = self.log.exception else: logging_function = exception - logging_function('%s in %s.%s:', s, self.__class__.__name__, f.func_name) + logging_function('%s in %s.%s:', s, self.__class__.__name__, f.__name__) def m(self, *args, **kwargs): try: return f(self, *args, **kwargs) - except Exception, e: + except Exception as e: if testing: raise logException(self) if errorHandler is not None: try: return errorHandler(self, *args, **kwargs) - except Exception, e: + except Exception as e: logException(self, 'Uncaught exception in errorHandler') - m = utils.python.changeFunctionName(m, f.func_name, f.__doc__) + m = utils.python.changeFunctionName(m, f.__name__, f.__doc__) return m class MetaFirewall(type): diff --git a/src/minisix.py b/src/minisix.py new file mode 100644 index 000000000..eed817d34 --- /dev/null +++ b/src/minisix.py @@ -0,0 +1,40 @@ +### +# Copyright (c) 2014, Valentin Lorentz +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +"""Restricted equivalent to six.""" + +import sys + +if sys.version_info[0] >= 3: + intern = sys.intern +else: + if isinstance(__builtins__, dict): + intern = __builtins__['intern'] + else: + intern = __builtins__.intern diff --git a/src/plugin.py b/src/plugin.py index 324a38792..448a017e6 100644 --- a/src/plugin.py +++ b/src/plugin.py @@ -54,12 +54,12 @@ def loadPluginModule(name, ignoreDeprecation=False): log.warning('Invalid plugin directory: %s; removing.', dir) conf.supybot.directories.plugins().remove(dir) if name not in files: - matched_names = filter(lambda x: re.search(r'(?i)^%s$' % (name,), x), - files) + search = lambda x: re.search(r'(?i)^%s$' % (name,), x) + matched_names = list(filter(search, files)) if len(matched_names) == 1: name = matched_names[0] else: - raise ImportError, name + raise ImportError(name) moduleInfo = imp.find_module(name, pluginDirs) try: module = imp.load_module(name, *moduleInfo) @@ -74,8 +74,8 @@ def loadPluginModule(name, ignoreDeprecation=False): if ignoreDeprecation: log.warning('Deprecated plugin loaded: %s', name) else: - raise Deprecated, format('Attempted to load deprecated plugin %s', - name) + raise Deprecated(format('Attempted to load deprecated plugin %s', + name)) if module.__name__ in sys.modules: sys.modules[module.__name__] = module linecache.checkcache() @@ -85,11 +85,10 @@ def loadPluginClass(irc, module, register=None): """Loads the plugin Class from the given module into the given Irc.""" try: cb = module.Class(irc) - except TypeError, e: + except TypeError as e: s = str(e) if '2 given' in s and '__init__' in s: - raise callbacks.Error, \ - 'In our switch from CVS to Darcs (after 0.80.1), we ' \ + raise callbacks.Error('In our switch from CVS to Darcs (after 0.80.1), we ' \ 'changed the __init__ for callbacks.Privmsg* to also ' \ 'accept an irc argument. This plugin (%s) is overriding ' \ 'its __init__ method and needs to update its prototype ' \ @@ -98,17 +97,16 @@ def loadPluginClass(irc, module, register=None): 'parent\'s __init__. Another possible cause: the code in ' \ 'your __init__ raised a TypeError when calling a function ' \ 'or creating an object, which doesn\'t take 2 arguments.' %\ - module.__name__ + module.__name__) else: raise - except AttributeError, e: + except AttributeError as e: if 'Class' in str(e): - raise callbacks.Error, \ - 'This plugin module doesn\'t have a "Class" ' \ + raise callbacks.Error('This plugin module doesn\'t have a "Class" ' \ 'attribute to specify which plugin should be ' \ 'instantiated. If you didn\'t write this ' \ 'plugin, but received it with Supybot, file ' \ - 'a bug with us about this error.' + 'a bug with us about this error.') else: raise cb.classModule = module @@ -129,7 +127,7 @@ def loadPluginClass(irc, module, register=None): renameCommand(cb, command, newName) else: conf.supybot.commands.renames.unregister(plugin) - except registry.NonExistentRegistryEntry, e: + except registry.NonExistentRegistryEntry as e: pass # The plugin isn't there. irc.addCallback(cb) return cb diff --git a/src/questions.py b/src/questions.py index 998a9b3e0..61abb19a8 100644 --- a/src/questions.py +++ b/src/questions.py @@ -29,7 +29,7 @@ """Handles interactive questions; useful for wizards and whatnot.""" - +from __future__ import print_function import sys import textwrap @@ -44,8 +44,8 @@ useBold = False def output(s, unformatted=True, fd=sys.stdout): if unformatted: s = textwrap.fill(utils.str.normalizeWhitespace(s), width=65) - print >>fd, s - print >>fd + print(s, file=fd) + print('', file=fd) def expect(prompt, possibilities, recursed=False, default=None, acceptEmpty=False, fd=sys.stdout): @@ -75,10 +75,13 @@ def expect(prompt, possibilities, recursed=False, default=None, prompt = prompt.strip() + ' ' if useBold: prompt += ansi.RESET - print >>fd, ansi.BOLD, - s = raw_input(prompt) + print(ansi.BOLD, end=' ', file=fd) + if sys.version_info[0] >= 3: + s = input(prompt) + else: + s = raw_input(prompt) s = s.strip() - print >>fd + print(file=fd) if possibilities: if s in possibilities: return s @@ -140,7 +143,7 @@ def getpass(prompt=None, secondPrompt=None): output(_('Passwords don\'t match.')) else: break - print + print('') return password diff --git a/src/registry.py b/src/registry.py index 1bce02c13..ef67c4264 100644 --- a/src/registry.py +++ b/src/registry.py @@ -42,11 +42,11 @@ _ = i18n.PluginInternationalization() def error(s): """Replace me with something better from another module!""" - print '***', s + print('***', s) def exception(s): """Ditto!""" - print '***', s, 'A bad exception.' + print('***', s, 'A bad exception.') class RegistryException(Exception): pass @@ -103,7 +103,7 @@ def open_registry(filename, clear=False): value = decoder(value)[0] acc = '' except ValueError: - raise InvalidRegistryFile, 'Error unpacking line %r' % acc + raise InvalidRegistryFile('Error unpacking line %r' % acc) _cache[key] = value _lastModified = time.time() _fd.close() @@ -127,12 +127,12 @@ def close(registry, filename, private=True): lines.append('#\n') try: x = value.__class__(value._default, value._help) - except Exception, e: + except Exception as e: exception('Exception instantiating default for %s:' % value._name) try: lines.append('# Default value: %s\n' % x) - except Exception, e: + except Exception as e: exception('Exception printing default value of %s:' % value._name) lines.append('###\n') @@ -144,7 +144,7 @@ def close(registry, filename, private=True): else: s = 'CENSORED' fd.write('%s: %s\n' % (name, s)) - except Exception, e: + except Exception as e: exception('Exception printing value:') fd.close() @@ -169,7 +169,7 @@ def unescape(name): _splitRe = re.compile(r'(?= 1: - print "shlex: pushing token " + `tok` + print("shlex: pushing token " + repr(tok)) self.pushback = [tok] + self.pushback def push_source(self, newstream, newfile=None): @@ -48,9 +48,9 @@ class shlex: self.lineno = 1 if self.debug: if newfile is not None: - print 'shlex: pushing to file %s' % (self.infile,) + print('shlex: pushing to file %s' % (self.infile,)) else: - print 'shlex: pushing to stream %s' % (self.instream,) + print('shlex: pushing to stream %s' % (self.instream,)) def pop_source(self): "Pop the input source stack." @@ -58,8 +58,8 @@ class shlex: (self.infile, self.instream, self.lineno) = self.filestack[0] self.filestack = self.filestack[1:] if self.debug: - print 'shlex: popping to %s, line %d' \ - % (self.instream, self.lineno) + print('shlex: popping to %s, line %d' \ + % (self.instream, self.lineno)) self.state = ' ' def get_token(self): @@ -68,7 +68,7 @@ class shlex: tok = self.pushback[0] self.pushback = self.pushback[1:] if self.debug >= 1: - print "shlex: popping token " + `tok` + print("shlex: popping token " + repr(tok)) return tok # No pushback. Get a token. raw = self.read_token() @@ -89,20 +89,20 @@ class shlex: # Neither inclusion nor EOF if self.debug >= 1: if raw: - print "shlex: token=" + `raw` + print("shlex: token=" + repr(raw)) else: - print "shlex: token=EOF" + print("shlex: token=EOF") return raw def read_token(self): "Read a token from the input stream (no pushback or inclusions)" - while 1: + while True: nextchar = self.instream.read(1) if nextchar == '\n': self.lineno = self.lineno + 1 if self.debug >= 3: - print "shlex: in state", repr(self.state), \ - "I see character:", repr(nextchar) + print("shlex: in state", repr(self.state), \ + "I see character:", repr(nextchar)) if self.state is None: self.token = '' # past end of file break @@ -112,7 +112,7 @@ class shlex: break elif nextchar in self.whitespace: if self.debug >= 2: - print "shlex: I see whitespace in whitespace state" + print("shlex: I see whitespace in whitespace state") if self.token: break # emit current token else: @@ -147,16 +147,16 @@ class shlex: self.backslash = False elif not nextchar: # end of file if self.debug >= 2: - print "shlex: I see EOF in quotes state" + print("shlex: I see EOF in quotes state") # XXX what error should be raised here? - raise ValueError, "No closing quotation" + raise ValueError("No closing quotation") elif self.state == 'a': if not nextchar: self.state = None # end of file break elif nextchar in self.whitespace: if self.debug >= 2: - print "shlex: I see whitespace in word state" + print("shlex: I see whitespace in word state") self.state = ' ' if self.token: break # emit current token @@ -170,7 +170,7 @@ class shlex: else: self.pushback = [nextchar] + self.pushback if self.debug >= 2: - print "shlex: I see punctuation in word state" + print("shlex: I see punctuation in word state") self.state = ' ' if self.token: break # emit current token @@ -180,9 +180,9 @@ class shlex: self.token = '' if self.debug > 1: if result: - print "shlex: raw token=" + `result` + print("shlex: raw token=" + repr(result)) else: - print "shlex: raw token=EOF" + print("shlex: raw token=EOF") return result def sourcehook(self, newfile): @@ -190,7 +190,7 @@ class shlex: if newfile[0] == '"': newfile = newfile[1:-1] # This implements cpp-like semantics for relative-path inclusion. - if type(self.infile) == type("") and not os.path.isabs(newfile): + if isinstance(self.infile, basestring) and not os.path.isabs(newfile): newfile = os.path.join(os.path.dirname(self.infile), newfile) return (newfile, open(newfile, "r")) @@ -210,9 +210,9 @@ if __name__ == '__main__': file = sys.argv[1] with open(file) as fd: lexer = shlex(fd, file) - while 1: + while True: tt = lexer.get_token() if tt: - print "Token: " + repr(tt) + print("Token: " + repr(tt)) else: break diff --git a/src/test.py b/src/test.py index 57f7ed25b..f1ee7c7e4 100644 --- a/src/test.py +++ b/src/test.py @@ -81,7 +81,7 @@ class TestPlugin(callbacks.Plugin): irc.reply(repr(eval(' '.join(args)))) except callbacks.ArgumentError: raise - except Exception, e: + except Exception as e: irc.reply(utils.exnToString(e)) # Since we know we don't now need the Irc object, we just give None. This # might break if callbacks.Privmsg ever *requires* the Irc object. @@ -147,8 +147,8 @@ class PluginTestCase(SupyTestCase): for cb in self.irc.callbacks: cbModule = sys.modules[cb.__class__.__module__] if hasattr(cbModule, 'deprecated') and cbModule.deprecated: - print - print 'Ignored, %s is deprecated.' % cb.name() + print('') + print('Ignored, %s is deprecated.' % cb.name()) run = False if run: originalRunTest() @@ -187,7 +187,7 @@ class PluginTestCase(SupyTestCase): ircdb.ignores.reload() ircdb.channels.reload() if self.plugins is None: - raise ValueError, 'PluginTestCase must have a "plugins" attribute.' + raise ValueError('PluginTestCase must have a "plugins" attribute.') self.nick = nick self.prefix = ircutils.joinHostmask(nick, 'user', 'host.domain.tld') self.irc = getTestIrc() @@ -238,7 +238,7 @@ class PluginTestCase(SupyTestCase): if timeout is None: timeout = self.timeout if self.myVerbose: - print # Extra newline, so it's pretty. + print('') # Extra newline, so it's pretty. prefixChars = conf.supybot.reply.whenAddressedBy.chars() if not usePrefixChar and query[0] in prefixChars: query = query[1:] @@ -246,7 +246,7 @@ class PluginTestCase(SupyTestCase): query = query.encode('utf8') # unicode->str msg = ircmsgs.privmsg(to, query, prefix=frm) if self.myVerbose: - print 'Feeding: %r' % msg + print('Feeding: %r' % msg) self.irc.feedMsg(msg) fed = time.time() response = self.irc.takeMsg() @@ -255,7 +255,7 @@ class PluginTestCase(SupyTestCase): drivers.run() response = self.irc.takeMsg() if self.myVerbose: - print 'Response: %r' % response + print('Response: %r' % response) return response def getMsg(self, query, **kwargs): @@ -276,7 +276,7 @@ class PluginTestCase(SupyTestCase): def assertError(self, query, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) if lastGetHelp not in m.args[1]: self.failUnless(m.args[1].startswith('Error:'), '%r did not error: %s' % (query, m.args[1])) @@ -288,7 +288,7 @@ class PluginTestCase(SupyTestCase): def assertNotError(self, query, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) self.failIf(m.args[1].startswith('Error:'), '%r errored: %s' % (query, m.args[1])) self.failIf(lastGetHelp in m.args[1], @@ -301,7 +301,7 @@ class PluginTestCase(SupyTestCase): def assertHelp(self, query, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) msg = m.args[1] if 'more message' in msg: msg = msg[0:-27] # Strip (XXX more messages) @@ -321,7 +321,7 @@ class PluginTestCase(SupyTestCase): def assertResponse(self, query, expectedResponse, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) self.assertEqual(m.args[1], expectedResponse, '%r != %r' % (expectedResponse, m.args[1])) return m @@ -333,7 +333,7 @@ class PluginTestCase(SupyTestCase): def assertRegexp(self, query, regexp, flags=re.I, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) self.failUnless(re.search(regexp, m.args[1], flags), '%r does not match %r' % (m.args[1], regexp)) return m @@ -345,7 +345,7 @@ class PluginTestCase(SupyTestCase): def assertNotRegexp(self, query, regexp, flags=re.I, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) self.failUnless(re.search(regexp, m.args[1], flags) is None, '%r matched %r' % (m.args[1], regexp)) return m @@ -357,7 +357,7 @@ class PluginTestCase(SupyTestCase): def assertAction(self, query, expectedResponse=None, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) self.failUnless(ircmsgs.isAction(m), '%r is not an action.' % m) if expectedResponse is not None: s = ircmsgs.unAction(m) @@ -372,7 +372,7 @@ class PluginTestCase(SupyTestCase): def assertActionRegexp(self, query, regexp, flags=re.I, **kwargs): m = self._feedMsg(query, **kwargs) if m is None: - raise TimeoutError, query + raise TimeoutError(query) self.failUnless(ircmsgs.isAction(m)) s = ircmsgs.unAction(m) self.failUnless(re.search(regexp, s, flags), @@ -433,7 +433,7 @@ class ChannelPluginTestCase(PluginTestCase): if timeout is None: timeout = self.timeout if self.myVerbose: - print # Newline, just like PluginTestCase. + print('') # Newline, just like PluginTestCase. prefixChars = conf.supybot.reply.whenAddressedBy.chars() if query[0] not in prefixChars and usePrefixChar: query = prefixChars[0] + query @@ -441,7 +441,7 @@ class ChannelPluginTestCase(PluginTestCase): query = query.encode('utf8') # unicode->str msg = ircmsgs.privmsg(to, query, prefix=frm) if self.myVerbose: - print 'Feeding: %r' % msg + print('Feeding: %r' % msg) self.irc.feedMsg(msg) fed = time.time() response = self.irc.takeMsg() @@ -466,7 +466,7 @@ class ChannelPluginTestCase(PluginTestCase): else: ret = None if self.myVerbose: - print 'Returning: %r' % ret + print('Returning: %r' % ret) return ret def feedMsg(self, query, to=None, frm=None, private=False): @@ -537,7 +537,7 @@ def open_http(url, data=None): host = realhost #print "proxy via http:", host, selector - if not host: raise IOError, ('http error', 'no host given') + if not host: raise IOError('http error', 'no host given') if proxy_passwd: import base64 diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 4e26f8d60..6d1de1002 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -44,7 +44,7 @@ def join(L): def split(s): fd = StringIO.StringIO(s) reader = csv.reader(fd) - return reader.next() + return next(reader) csv.join = join csv.split = split diff --git a/src/utils/file.py b/src/utils/file.py index 16981db5a..b2a698033 100644 --- a/src/utils/file.py +++ b/src/utils/file.py @@ -50,7 +50,7 @@ def open_mkdir(filename, mode='wb', *args, **kwargs): baz in it. """ if mode not in ('w', 'wb'): - raise ValueError, 'utils.file.open expects to write.' + raise ValueError('utils.file.open expects to write.') (dirname, basename) = os.path.split(filename) os.makedirs(dirname) return open(filename, mode, *args, **kwargs) @@ -105,7 +105,7 @@ def nonCommentLines(fd): yield line def nonEmptyLines(fd): - return ifilter(str.strip, fd) + return filter(str.strip, fd) def nonCommentNonEmptyLines(fd): return nonEmptyLines(nonCommentLines(fd)) @@ -137,7 +137,7 @@ class AtomicFile(object): if allowEmptyOverwrite is None: allowEmptyOverwrite = force(self.default.allowEmptyOverwrite) if mode not in ('w', 'wb'): - raise ValueError, format('Invalid mode: %q', mode) + raise ValueError(format('Invalid mode: %q', mode)) self.rolledback = False self.allowEmptyOverwrite = allowEmptyOverwrite self.makeBackupIfSmaller = makeBackupIfSmaller @@ -219,7 +219,7 @@ class AtomicFile(object): shutil.move(self.tempFilename, self.filename) else: - raise ValueError, 'AtomicFile.close called after rollback.' + raise ValueError('AtomicFile.close called after rollback.') def __del__(self): # We rollback because if we're deleted without being explicitly closed, diff --git a/src/utils/gen.py b/src/utils/gen.py index 42df662ea..7b0a7956e 100644 --- a/src/utils/gen.py +++ b/src/utils/gen.py @@ -28,6 +28,8 @@ # POSSIBILITY OF SUCH DAMAGE. ### +from __future__ import print_function + import os import sys import ast @@ -36,7 +38,7 @@ import types import textwrap import traceback import collections -from itertools import imap + from . import crypt from .str import format @@ -115,7 +117,7 @@ def timeElapsed(elapsed, short=False, leadingZeroes=False, years=True, leadingZeroes = True Format(_('second'), secs) if not ret: - raise ValueError, 'Time difference not great enough to be noted.' + raise ValueError('Time difference not great enough to be noted.') result = '' if short: result = ' '.join(ret) @@ -158,14 +160,14 @@ def safeEval(s, namespace={'True': True, 'False': False, 'None': None}): without unsafely using eval().""" try: node = ast.parse(s) - except SyntaxError, e: - raise ValueError, 'Invalid string: %s.' % e + except SyntaxError as e: + raise ValueError('Invalid string: %s.' % e) nodes = ast.parse(s).body if not nodes: if node.__class__ is ast.Module: return node.doc else: - raise ValueError, format('Unsafe string: %q', s) + raise ValueError(format('Unsafe string: %q', s)) node = nodes[0] def checkNode(node): if node.__class__ is ast.Expr: @@ -190,7 +192,7 @@ def safeEval(s, namespace={'True': True, 'False': False, 'None': None}): if checkNode(node): return eval(s, namespace, namespace) else: - raise ValueError, format('Unsafe string: %q', s) + raise ValueError(format('Unsafe string: %q', s)) def exnToString(e): """Turns a simple exception instance into a string (better than str(e))""" @@ -239,10 +241,11 @@ class IterableMap(object): ret += 1 return ret - def __nonzero__(self): + def __bool__(self): for _ in self.iteritems(): return True return False + __nonzero__ = __bool__ class InsensitivePreservingDict(collections.MutableMapping): @@ -299,7 +302,7 @@ class InsensitivePreservingDict(collections.MutableMapping): class NormalizingSet(set): def __init__(self, iterable=()): - iterable = imap(self.normalize, iterable) + iterable = list(map(self.normalize, iterable)) super(NormalizingSet, self).__init__(iterable) def normalize(self, x): @@ -344,7 +347,7 @@ def callTracer(fd=None, basename=True): filename = code.co_filename if basename: filename = os.path.basename(filename) - print >>fd, '%s: %s(%s)' % (filename, funcname, lineno) + print('%s: %s(%s)' % (filename, funcname, lineno), file=fd) return tracer # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/src/utils/iter.py b/src/utils/iter.py index f4039341e..8e84d8915 100644 --- a/src/utils/iter.py +++ b/src/utils/iter.py @@ -36,8 +36,9 @@ from itertools import * # For old plugins ifilter = filter -def ifilterfalse(p, L): - return ifilter(lambda x:not p(x), L) +def filterfalse(p, L): + return filter(lambda x:not p(x), L) +ifilterfalse = filterfalse imap = map def len(iterable): @@ -48,7 +49,7 @@ def len(iterable): return i def trueCycle(iterable): - while 1: + while True: yielded = False for x in iterable: yield x @@ -70,14 +71,14 @@ def partition(p, iterable): def any(p, iterable): """Returns true if any element in iterable satisfies predicate p.""" - for elt in ifilter(p, iterable): + for elt in filter(p, iterable): return True else: return False def all(p, iterable): """Returns true if all elements in iterable satisfy predicate p.""" - for elt in ifilterfalse(p, iterable): + for elt in filterfalse(p, iterable): return False else: return True @@ -141,7 +142,7 @@ def startswith(long_, short): shortI = iter(short) try: while True: - if shortI.next() != longI.next(): + if next(shortI) != next(longI): return False except StopIteration: return True @@ -151,10 +152,10 @@ def limited(iterable, limit): iterable = iter(iterable) try: while i: - yield iterable.next() + yield next(iterable) i -= 1 except StopIteration: - raise ValueError, 'Expected %s elements in iterable (%r), got %s.' % \ - (limit, iterable, limit-i) + raise ValueError('Expected %s elements in iterable (%r), got %s.' % \ + (limit, iterable, limit-i)) # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/src/utils/net.py b/src/utils/net.py index f65ead27a..cb8b522a3 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -67,7 +67,7 @@ def getSocket(host, socks_proxy=None): elif isIPV6(host): return socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: - raise socket.error, 'Something wonky happened.' + raise socket.error('Something wonky happened.') def isIP(s): """Returns whether or not a given string is an IP address. diff --git a/src/utils/python.py b/src/utils/python.py index b9d6c1886..acd2cba7d 100644 --- a/src/utils/python.py +++ b/src/utils/python.py @@ -53,13 +53,18 @@ def universalImport(*names): ret = getattr(ret, parts[0]) del parts[0] return ret - raise ImportError, ','.join(names) + raise ImportError(','.join(names)) def changeFunctionName(f, name, doc=None): if doc is None: doc = f.__doc__ - newf = types.FunctionType(f.func_code, f.func_globals, name, - f.func_defaults, f.func_closure) + if hasattr(f, '__closure__'): + closure = f.__closure__ + else: + # Pypy + closure = f.func_closure + newf = types.FunctionType(f.__code__, f.__globals__, name, + f.__defaults__, closure) newf.__doc__ = doc return newf @@ -86,7 +91,7 @@ class Synchronized(type): f(self, *args, **kwargs) finally: lock.release() - return changeFunctionName(g, f.func_name, f.__doc__) + return changeFunctionName(g, f.__name__, f.__doc__) for attr in sync: if attr in dict: dict[attr] = synchronized(dict[attr]) diff --git a/src/utils/seq.py b/src/utils/seq.py index 67b0272be..0fa37e492 100644 --- a/src/utils/seq.py +++ b/src/utils/seq.py @@ -33,7 +33,7 @@ def window(L, size): Returns a sliding 'window' through the list L of size size.""" assert not isinstance(L, int), 'Argument order swapped: window(L, size)' if size < 1: - raise ValueError, 'size <= 0 disallowed.' + raise ValueError('size <= 0 disallowed.') for i in xrange(len(L) - (size-1)): yield L[i:i+size] diff --git a/src/utils/str.py b/src/utils/str.py index 0e9c18947..61387c970 100644 --- a/src/utils/str.py +++ b/src/utils/str.py @@ -114,8 +114,8 @@ class MultipleRemover: def __call__(self, s): return self._matcher.sub(lambda m: '', s) -_soundextrans = MultipleReplacer(dict(zip(string.ascii_uppercase, - '01230120022455012623010202'))) +_soundextrans = MultipleReplacer(dict(list(zip(string.ascii_uppercase, + '01230120022455012623010202')))) def soundex(s, length=4): """Returns the soundex hash of a given string. @@ -124,7 +124,7 @@ def soundex(s, length=4): s = s.upper() # Make everything uppercase. s = ''.join([x for x in s if x in string.ascii_uppercase]) if not s: - raise ValueError, 'Invalid string for soundex: %s' + raise ValueError('Invalid string for soundex: %s') firstChar = s[0] # Save the first character. s = _soundextrans(s) # Convert to soundex numbers. s = s.lstrip(s[0]) # Remove all repeated first characters. @@ -155,7 +155,7 @@ _openers = '{[(<' _closers = '}])>' def _getSep(s, allowBraces=False): if len(s) < 2: - raise ValueError, 'string given to _getSep is too short: %r' % s + raise ValueError('string given to _getSep is too short: %r' % s) if allowBraces: braces = _closers else: @@ -165,9 +165,8 @@ def _getSep(s, allowBraces=False): else: separator = s[0] if separator.isalnum() or separator in braces: - raise ValueError, \ - 'Invalid separator: separator must not be alphanumeric or in ' \ - '"%s"' % braces + raise ValueError('Invalid separator: separator must not be alphanumeric or in ' \ + '"%s"' % braces) return separator def perlReToPythonRe(s): @@ -183,7 +182,7 @@ def perlReToPythonRe(s): try: (regexp, flags) = matcher.match(s).groups() except AttributeError: # Unpack list of wrong size. - raise ValueError, 'Must be of the form m/.../ or /.../' + raise ValueError('Must be of the form m/.../ or /.../') regexp = regexp.replace('\\'+opener, opener) if opener != closer: regexp = regexp.replace('\\'+closer, closer) @@ -192,11 +191,11 @@ def perlReToPythonRe(s): for c in flags.upper(): flag |= getattr(re, c) except AttributeError: - raise ValueError, 'Invalid flag: %s' % c + raise ValueError('Invalid flag: %s' % c) try: return re.compile(regexp, flag) - except re.error, e: - raise ValueError, str(e) + except re.error as e: + raise ValueError(str(e)) def perlReToReplacer(s): """Converts a string representation of a Perl regular expression (i.e., @@ -210,7 +209,7 @@ def perlReToReplacer(s): try: (regexp, replace, flags) = matcher.match(s).groups() except AttributeError: # Unpack list of wrong size. - raise ValueError, 'Must be of the form s/.../.../' + raise ValueError('Must be of the form s/.../.../') regexp = regexp.replace('\x08', r'\b') replace = replace.replace('\\'+sep, sep) for i in xrange(10): @@ -218,7 +217,7 @@ def perlReToReplacer(s): g = False if 'g' in flags: g = True - flags = filter('g'.__ne__, flags) + flags = list(filter('g'.__ne__, flags)) if isinstance(flags, list): flags = ''.join(flags) r = perlReToPythonRe(sep.join(('', regexp, flags))) @@ -414,7 +413,7 @@ def toBool(s): elif s in ('false', 'off', 'disable', 'disabled', '0'): return False else: - raise ValueError, 'Invalid string for toBool: %s' % quoted(s) + raise ValueError('Invalid string for toBool: %s' % quoted(s)) # When used with Supybot, this is overriden when supybot.conf is loaded def timestamp(t): @@ -476,14 +475,12 @@ def format(s, *args, **kwargs): return commaAndify(t) elif isinstance(t, tuple) and len(t) == 2: if not isinstance(t[0], list): - raise ValueError, \ - 'Invalid list for %%L in format: %s' % t + raise ValueError('Invalid list for %%L in format: %s' % t) if not isinstance(t[1], basestring): - raise ValueError, \ - 'Invalid string for %%L in format: %s' % t + raise ValueError('Invalid string for %%L in format: %s' % t) return commaAndify(t[0], And=t[1]) else: - raise ValueError, 'Invalid value for %%L in format: %s' % t + raise ValueError('Invalid value for %%L in format: %s' % t) elif char == 'p': return pluralize(args.pop()) elif char == 'q': @@ -493,17 +490,17 @@ def format(s, *args, **kwargs): elif char == 'n': t = args.pop() if not isinstance(t, (tuple, list)): - raise ValueError, 'Invalid value for %%n in format: %s' % t + raise ValueError('Invalid value for %%n in format: %s' % t) if len(t) == 2: return nItems(*t) elif len(t) == 3: return nItems(t[0], t[2], between=t[1]) else: - raise ValueError, 'Invalid value for %%n in format: %s' % t + raise ValueError('Invalid value for %%n in format: %s' % t) elif char == 'S': t = args.pop() if not isinstance(t, (int, long)): - raise ValueError, 'Invalid value for %%S in format: %s' % t + raise ValueError('Invalid value for %%S in format: %s' % t) for suffix in ['B','KB','MB','GB','TB']: if t < 1024: return "%i%s" % (t, suffix) @@ -527,10 +524,10 @@ def format(s, *args, **kwargs): elif char == '%': return '%' else: - raise ValueError, 'Invalid char in sub (in format).' + raise ValueError('Invalid char in sub (in format).') try: return _formatRe.sub(sub, s) except IndexError: - raise ValueError, 'Extra format chars in format spec: %r' % s + raise ValueError('Extra format chars in format spec: %r' % s) # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/src/utils/structures.py b/src/utils/structures.py index 3b2910397..31e8f561f 100644 --- a/src/utils/structures.py +++ b/src/utils/structures.py @@ -34,14 +34,14 @@ Data structures for Python. import time import types import collections -from itertools import imap + class RingBuffer(object): """Class to represent a fixed-size ring buffer.""" __slots__ = ('L', 'i', 'full', 'maxSize') def __init__(self, maxSize, seq=()): if maxSize <= 0: - raise ValueError, 'maxSize must be > 0.' + raise ValueError('maxSize must be > 0.') self.maxSize = maxSize self.reset() for elt in seq: @@ -70,14 +70,15 @@ class RingBuffer(object): self.maxSize == other.maxSize and len(self) == len(other): iterator = iter(other) for elt in self: - otherelt = iterator.next() + otherelt = next(iterator) if not elt == otherelt: return False return True return False - def __nonzero__(self): + def __bool__(self): return len(self) > 0 + __nonzero__ = __bool__ def __contains__(self, elt): return elt in self.L @@ -100,7 +101,7 @@ class RingBuffer(object): def __getitem__(self, idx): if self.full: oidx = idx - if type(oidx) == types.SliceType: + if isinstance(oidx, types.SliceType): L = [] for i in xrange(*slice.indices(oidx, len(self))): L.append(self[i]) @@ -108,11 +109,11 @@ class RingBuffer(object): else: (m, idx) = divmod(oidx, len(self.L)) if m and m != -1: - raise IndexError, oidx + raise IndexError(oidx) idx = (idx + self.i) % len(self.L) return self.L[idx] else: - if type(idx) == types.SliceType: + if isinstance(idx, types.SliceType): L = [] for i in xrange(*slice.indices(idx, len(self))): L.append(self[i]) @@ -123,24 +124,24 @@ class RingBuffer(object): def __setitem__(self, idx, elt): if self.full: oidx = idx - if type(oidx) == types.SliceType: + if isinstance(oidx, types.SliceType): range_ = xrange(*slice.indices(oidx, len(self))) if len(range_) != len(elt): - raise ValueError, 'seq must be the same length as slice.' + raise ValueError('seq must be the same length as slice.') else: for (i, x) in zip(range_, elt): self[i] = x else: (m, idx) = divmod(oidx, len(self.L)) if m and m != -1: - raise IndexError, oidx + raise IndexError(oidx) idx = (idx + self.i) % len(self.L) self.L[idx] = elt else: - if type(idx) == types.SliceType: + if isinstance(idx, types.SliceType): range_ = xrange(*slice.indices(idx, len(self))) if len(range_) != len(elt): - raise ValueError, 'seq must be the same length as slice.' + raise ValueError('seq must be the same length as slice.') else: for (i, x) in zip(range_, elt): self[i] = x @@ -153,7 +154,8 @@ class RingBuffer(object): def __getstate__(self): return (self.maxSize, self.full, self.i, self.L) - def __setstate__(self, (maxSize, full, i, L)): + def __setstate__(self, state): + (maxSize, full, i, L) = state self.maxSize = maxSize self.full = full self.i = i @@ -196,8 +198,9 @@ class queue(object): def __len__(self): return len(self.front) + len(self.back) - def __nonzero__(self): + def __bool__(self): return bool(self.back or self.front) + __nonzero__ = __bool__ def __contains__(self, elt): return elt in self.front or elt in self.back @@ -212,7 +215,7 @@ class queue(object): if len(self) == len(other): otheriter = iter(other) for elt in self: - otherelt = otheriter.next() + otherelt = next(otheriter) if not (elt == otherelt): return False return True @@ -220,12 +223,12 @@ class queue(object): return False def __repr__(self): - return 'queue([%s])' % ', '.join(imap(repr, self)) + return 'queue([%s])' % ', '.join(map(repr, self)) def __getitem__(self, oidx): if len(self) == 0: - raise IndexError, 'queue index out of range' - if type(oidx) == types.SliceType: + raise IndexError('queue index out of range') + if isinstance(oidx, types.SliceType): L = [] for i in xrange(*slice.indices(oidx, len(self))): L.append(self[i]) @@ -233,7 +236,7 @@ class queue(object): else: (m, idx) = divmod(oidx, len(self)) if m and m != -1: - raise IndexError, oidx + raise IndexError(oidx) if len(self.front) > idx: return self.front[-(idx+1)] else: @@ -241,36 +244,36 @@ class queue(object): def __setitem__(self, oidx, value): if len(self) == 0: - raise IndexError, 'queue index out of range' - if type(oidx) == types.SliceType: + raise IndexError('queue index out of range') + if isinstance(oidx, types.SliceType): range_ = xrange(*slice.indices(oidx, len(self))) if len(range_) != len(value): - raise ValueError, 'seq must be the same length as slice.' + raise ValueError('seq must be the same length as slice.') else: for i in range_: (m, idx) = divmod(oidx, len(self)) if m and m != -1: - raise IndexError, oidx + raise IndexError(oidx) for (i, x) in zip(range_, value): self[i] = x else: (m, idx) = divmod(oidx, len(self)) if m and m != -1: - raise IndexError, oidx + raise IndexError(oidx) if len(self.front) > idx: self.front[-(idx+1)] = value else: self.back[idx-len(self.front)] = value def __delitem__(self, oidx): - if type(oidx) == types.SliceType: + if isinstance(oidx, types.SliceType): range_ = xrange(*slice.indices(oidx, len(self))) for i in range_: del self[i] else: (m, idx) = divmod(oidx, len(self)) if m and m != -1: - raise IndexError, oidx + raise IndexError(oidx) if len(self.front) > idx: del self.front[-(idx+1)] else: @@ -279,7 +282,8 @@ class queue(object): def __getstate__(self): return (list(self),) - def __setstate__(self, (L,)): + def __setstate__(self, state): + (L,) = state L.reverse() self.front = L self.back = [] @@ -296,7 +300,7 @@ class smallqueue(list): return self[0] def __repr__(self): - return 'smallqueue([%s])' % ', '.join(imap(repr, self)) + return 'smallqueue([%s])' % ', '.join(map(repr, self)) def reset(self): self[:] = [] @@ -363,7 +367,8 @@ class MaxLengthQueue(queue): def __getstate__(self): return (self.length, queue.__getstate__(self)) - def __setstate__(self, (length, q)): + def __setstate__(self, state): + (length, q) = state self.length = length queue.__setstate__(self, q) diff --git a/src/utils/transaction.py b/src/utils/transaction.py index b91f14783..8a4e09d6b 100644 --- a/src/utils/transaction.py +++ b/src/utils/transaction.py @@ -107,7 +107,7 @@ class Transaction(TransactionMixin): raise FailedAcquisition(self.txnDir) try: os.rename(self.txnDir, self.dir) - except EnvironmentError, e: + except EnvironmentError as e: raise FailedAcquisition(self.txnDir, e) os.mkdir(self.dirize(self.ORIGINALS)) os.mkdir(self.dirize(self.REPLACEMENTS)) diff --git a/src/utils/web.py b/src/utils/web.py index f439d1925..dec904de0 100644 --- a/src/utils/web.py +++ b/src/utils/web.py @@ -125,19 +125,19 @@ def getUrlFd(url, headers=None, data=None, timeout=None): request.set_proxy(httpProxy, 'http') fd = urllib2.urlopen(request, timeout=timeout) return fd - except socket.timeout, e: - raise Error, TIMED_OUT - except sockerrors, e: - raise Error, strError(e) - except httplib.InvalidURL, e: - raise Error, 'Invalid URL: %s' % e - except urllib2.HTTPError, e: - raise Error, strError(e) - except urllib2.URLError, e: - raise Error, strError(e.reason) + except socket.timeout as e: + raise Error(TIMED_OUT) + except sockerrors as e: + raise Error(strError(e)) + except httplib.InvalidURL as e: + raise Error('Invalid URL: %s' % e) + except urllib2.HTTPError as e: + raise Error(strError(e)) + except urllib2.URLError as e: + raise Error(strError(e.reason)) # Raised when urllib doesn't recognize the url type - except ValueError, e: - raise Error, strError(e) + except ValueError as e: + raise Error(strError(e)) def getUrl(url, size=None, headers=None, data=None): """getUrl(url, size=None, headers=None, data=None) @@ -151,8 +151,8 @@ def getUrl(url, size=None, headers=None, data=None): text = fd.read() else: text = fd.read(size) - except socket.timeout, e: - raise Error, TIMED_OUT + except socket.timeout as e: + raise Error(TIMED_OUT) fd.close() return text diff --git a/src/world.py b/src/world.py index 3a6d53bd8..a59a59973 100644 --- a/src/world.py +++ b/src/world.py @@ -118,7 +118,7 @@ def flush(): for (i, f) in enumerate(flushers): try: f() - except Exception, e: + except Exception as e: log.exception('Uncaught exception in flusher #%s (%s):', i, f) def debugFlush(s=''): diff --git a/test/test_ircmsgs.py b/test/test_ircmsgs.py index 9a6a51be4..24960f500 100644 --- a/test/test_ircmsgs.py +++ b/test/test_ircmsgs.py @@ -138,7 +138,7 @@ class FunctionsTestCase(SupyTestCase): ':ACTION beats ang senseless with a 50lb Unix manual (#2)', ':supybot!~supybot@underthemain.net PRIVMSG #sourcereview ' ':ACTION resizes angryman\'s terminal to 40x24 (#16)'] - msgs = map(ircmsgs.IrcMsg, L) + msgs = list(map(ircmsgs.IrcMsg, L)) for msg in msgs: self.failUnless(ircmsgs.isAction(msg)) diff --git a/test/test_utils.py b/test/test_utils.py index 1919c1e09..bffb0d0b0 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -479,7 +479,7 @@ class IterTest(SupyTestCase): self.assertEqual(lflatten(range(10)), list(range(10))) twoRanges = list(range(10))*2 twoRanges.sort() - self.assertEqual(lflatten(zip(range(10), range(10))), twoRanges) + self.assertEqual(lflatten(list(zip(range(10), range(10)))), twoRanges) self.assertEqual(lflatten([1, [2, 3], 4]), [1, 2, 3, 4]) self.assertEqual(lflatten([[[[[[[[[[]]]]]]]]]]), []) self.assertEqual(lflatten([1, [2, [3, 4], 5], 6]), [1, 2, 3, 4, 5, 6])