From 3a48cf204be3083c200b785d661c74bdcc2dff43 Mon Sep 17 00:00:00 2001 From: karxi Date: Tue, 29 Nov 2016 15:20:41 -0500 Subject: [PATCH] General cleanup. Stopped using older 'except Error, var' syntax. --- TODO.mkdn | 28 ++++++++++++ convo.py | 2 +- easyInstaller | 2 +- libs/feedparser.py | 10 ++-- oyoyo/client.py | 4 +- oyoyo/cmdhandler.py | 6 +-- parsetools.py | 17 +++++-- pesterchum.py | 22 +++++---- pnc/lexercon.py | 6 +++ pnc/unicolor.py | 108 ++++++++++++++++++++++---------------------- profile.py | 102 +++++++++++++++++------------------------ quirks.py | 2 +- updatecheck.py | 2 +- 13 files changed, 168 insertions(+), 143 deletions(-) diff --git a/TODO.mkdn b/TODO.mkdn index c35128d..687d5b8 100644 --- a/TODO.mkdn +++ b/TODO.mkdn @@ -39,6 +39,32 @@ Features * Overhaul debugging * Make a console to display debug info without requiring us to run from console * Debug generic.py's CaseInsensitiveDict/replace it with mine +* Overhaul messaging so Chan/Nick/Memo Servs all use the same code (and lexer) +* Implement MemoServ support +* Add support for displaying more verbose information (e.g. Cease messages which tell you more than the abbreviation of who left) +* Make Pesterchum recognize conventional /mes so they aren't invisible +* Fix NickServ auto-login things +* Fix memo autojoin +* Tell user when NickServ handles are going to expire +* Tell user when old handles have D/C'd? Offer autoghost support?! + +* Add more comprehensive status support - IDLE, DND, INVISIBLE for now - or at least add similar functionality. +* SEPARATE FUNCTIONALITY from CONNECTED STATE!! This is a huge problem! Being shunted off our nick closes windows and breaks things! Just D/C and reconnect? + * It'd probably be best to give an option to either CHANGE NICKS or DISCONNECT upon nick collision...? But, then how would we GHOST? + * Maybe GHOSTing should use auto-identify to ensure- no, that doesn't work, because we can't ident into a specified nick without being ON it. Need GD's help to fix.... + +* Separate Pesterchum system handling from window handling. Dicts should be stored and maintained via dicts - even a refined version of what I used for textsub. + * Doing it this way means I can fix the case in/sensitivity issue, too. + +* Finish creating the sound wrapper. Just make it check what the type of sound needed is upon creation, and instantiate a private class based off of that. + * There is basically no good way to do this without moving to Qt5. I might try that myself later, but that's a long-term goal. +* Toggle individual tab flash / alert sounds (from the same right-click memo that lets us toggle OOC) +* Make it possible to test quirk things and such without connecting? This'd be hard to separate out, but useful. + +Debugging +---- +* Make small, simplistic windows that allow the viewing of internal variables pertaining to things like set quirks, users present, etc. +* Make a window that can be used to interface with the script directly - a simple Python console. Bugs ---- @@ -58,6 +84,8 @@ Bugs * +c is not properly recognized on join, nor does it stop someone from reenabling their quirk (let ops and above ignore it) * Chumlist handles groups pretty badly (no using the same name as a handle, for example? Needs an errormessage at least) * PESTERCHUM: messages are sent to things like NickServ +* Log folder/file names are not case-sensitive, so they break on non-Windows systems +* Capitalized /me's don't render (should forcibly lowercase them) Windows Bugs ------------ diff --git a/convo.py b/convo.py index ebc947e..ace98f7 100644 --- a/convo.py +++ b/convo.py @@ -462,7 +462,7 @@ class PesterText(QtGui.QTextEdit): else: self.sending.sendinglabel.setText("F41L3D: %s %s" % (response.status, response.reason)) hconn.close() - except Exception, e: + except Exception as e: self.sending.sendinglabel.setText("F41L3D: %s" % (e)) del self.sending diff --git a/easyInstaller b/easyInstaller index 2592a92..b5798fa 100755 --- a/easyInstaller +++ b/easyInstaller @@ -224,7 +224,7 @@ try: print "Invalid input, try again" except KeyboardInterrupt: print "" -except Exception, e: +except Exception as e: error = -1 finally: if error == -1: diff --git a/libs/feedparser.py b/libs/feedparser.py index bb802df..91bec85 100755 --- a/libs/feedparser.py +++ b/libs/feedparser.py @@ -2234,7 +2234,7 @@ def _parse_date(dateString): raise ValueError map(int, date9tuple) return date9tuple - except Exception, e: + except Exception as e: if _debug: sys.stderr.write('%s raised %s\n' % (handler.__name__, repr(e))) pass return None @@ -2458,7 +2458,7 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer try: f = _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, handlers) data = f.read() - except Exception, e: + except Exception as e: result['bozo'] = 1 result['bozo_exception'] = e data = '' @@ -2469,7 +2469,7 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer if gzip and f.headers.get('content-encoding', '') == 'gzip': try: data = gzip.GzipFile(fileobj=_StringIO(data)).read() - except Exception, e: + except Exception as e: # Some feeds claim to be gzipped but they're not, so # we get garbage. Ideally, we should re-request the # feed without the 'Accept-encoding: gzip' header, @@ -2480,7 +2480,7 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer elif zlib and f.headers.get('content-encoding', '') == 'deflate': try: data = zlib.decompress(data, -zlib.MAX_WBITS) - except Exception, e: + except Exception as e: result['bozo'] = 1 result['bozo_exception'] = e data = '' @@ -2609,7 +2609,7 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer saxparser._ns_stack.append({'http://www.w3.org/XML/1998/namespace':'xml'}) try: saxparser.parse(source) - except Exception, e: + except Exception as e: if _debug: import traceback traceback.print_stack() diff --git a/oyoyo/client.py b/oyoyo/client.py index 32342a3..41f0ae1 100644 --- a/oyoyo/client.py +++ b/oyoyo/client.py @@ -204,7 +204,7 @@ class IRCClient: logging.info('error: closing socket') self.socket.close() raise se - except Exception, e: + except Exception as e: logging.debug("other exception: %s" % e) raise e else: @@ -270,7 +270,7 @@ class IRCApp: try: clientdesc.con.next() - except Exception, e: + except Exception as e: logging.error('client error %s' % e) logging.error(traceback.format_exc()) if clientdesc.autoreconnect: diff --git a/oyoyo/cmdhandler.py b/oyoyo/cmdhandler.py index 48505f7..d77b8ee 100644 --- a/oyoyo/cmdhandler.py +++ b/oyoyo/cmdhandler.py @@ -104,7 +104,7 @@ class CommandHandler(object): try: f(*args) - except Exception, e: + except Exception as e: logging.error('command raised %s' % e) logging.error(traceback.format_exc()) raise CommandError(command) @@ -150,7 +150,7 @@ class DefaultBotCommandHandler(CommandHandler): else: try: f = self.get(arg) - except CommandError, e: + except CommandError as e: helpers.msg(self.client, dest, str(e)) return @@ -197,7 +197,7 @@ class BotCommandHandler(DefaultCommandHandler): try: self.command_handler.run(command, prefix, dest, *arg) - except CommandError, e: + except CommandError as e: helpers.msg(self.client, dest, str(e)) return True diff --git a/parsetools.py b/parsetools.py index 916a935..6e925e5 100644 --- a/parsetools.py +++ b/parsetools.py @@ -220,7 +220,8 @@ kxpclexer = lexercon.Pesterchum() def kxlexMsg(string): # Do a bit of sanitization. msg = unicode(string) - # TODO: Let people paste line-by-line normally. + # TODO: Let people paste line-by-line normally. Maybe have a mass-paste + # right-click option? msg = msg.replace('\n', ' ').replace('\r', ' ') # Something the original doesn't seem to have accounted for. # Replace tabs with 4 spaces. @@ -340,12 +341,22 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False): Keep in mind that there's a little bit of magic involved in this at the moment; some unsafe assumptions are made.""" + + # NOTE: Keep in mind that lexercon CTag objects convert to "r,g,b" format. + # This means that they're usually going to be fairly long. + # Support for changing this will probably be added later, but it won't work + # properly with Chumdroid...I'll probably have to leave it as an actual + # config option that's applied to the parser. + # Procedure: Lex. Convert for lengths as we go, keep starting tag # length as we go too. Split whenever we hit the limit, add the tags to # the start of the next line (or just keep a running line length # total), and continue. # N.B.: Keep the end tag length too. (+4 for each.) # Copy the list so we can't break anything. + # TODO: There's presently an issue where certain combinations of color + # codes end up being added as a separate, empty line. This is a bug, of + # course, and should be looked into. lexed = list(lexed) working = [] output = [] @@ -479,7 +490,7 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False): if text_preproc: # If we got here, it means we overflowed due to text - which # means we also split and added it to working. There's no - # reason to continue and add it twice. + # reason to go on and add it twice. # This could be handled with an elif chain, but eh. continue # If we got here, it means we haven't done anything with 'msg' yet, @@ -640,7 +651,7 @@ def kxhandleInput(ctx, text=None, flavor=None): # files for the original sentMessage variants. if flavor is None: - return ValueError("A flavor is needed to determine suitable logic!") + raise ValueError("A flavor is needed to determine suitable logic!") if text is None: # Fetch the raw text from the input box. diff --git a/pesterchum.py b/pesterchum.py index b15ff5d..0b5e28d 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -15,19 +15,21 @@ reqmissing = [] optmissing = [] try: from PyQt4 import QtGui, QtCore -except ImportError, e: +except ImportError as e: module = str(e) if module.startswith("No module named ") or \ module.startswith("cannot import name "): reqmissing.append(module[module.rfind(" ")+1:]) else: print e + del module try: import pygame -except ImportError, e: +except ImportError as e: pygame = None module = str(e) if module[:16] == "No module named ": optmissing.append(module[16:]) else: print e + del module if reqmissing: print "ERROR: The following modules are required for Pesterchum to run and are missing on your system:" for m in reqmissing: print "* "+m @@ -1022,10 +1024,10 @@ class PesterWindow(MovingWindow): try: themeChecker(self.theme) - except ThemeException, (inst): - print "Caught: "+inst.parameter + except ThemeException as inst: + print "Caught: " + inst.parameter themeWarning = QtGui.QMessageBox(self) - themeWarning.setText("Theme Error: %s" % (inst)) + themeWarning.setText("Theme Error: %s" % inst) themeWarning.exec_() self.theme = pesterTheme("pesterchum") @@ -1679,15 +1681,15 @@ class PesterWindow(MovingWindow): else: sound.setVolume(vol) except Exception as err: - print "Couldn't set volumme: {}".format(err) + print "Couldn't set volume: {}".format(err) def changeTheme(self, theme): # check theme try: themeChecker(theme) - except ThemeException, (inst): + except ThemeException as inst: themeWarning = QtGui.QMessageBox(self) - themeWarning.setText("Theme Error: %s" % (inst)) + themeWarning.setText("Theme Error: %s" % inst) themeWarning.exec_() theme = pesterTheme("pesterchum") return @@ -2521,7 +2523,7 @@ class PesterWindow(MovingWindow): newmodes = self.optionmenu.modechange.text() if newmodes: self.setChannelMode.emit(self.profile().handle, newmodes, "") - except Exception, e: + except Exception as e: logging.error(e) finally: self.optionmenu = None @@ -2560,7 +2562,7 @@ class PesterWindow(MovingWindow): if override or themename != self.theme.name: try: self.changeTheme(pesterTheme(themename)) - except ValueError, e: + except ValueError as e: themeWarning = QtGui.QMessageBox(self) themeWarning.setText("Theme Error: %s" % (e)) themeWarning.exec_() diff --git a/pnc/lexercon.py b/pnc/lexercon.py index 809499a..5f2df31 100644 --- a/pnc/lexercon.py +++ b/pnc/lexercon.py @@ -252,6 +252,12 @@ class Pesterchum(Lexer): _ctag_end = re.compile(r"", flags=re.I) _mecmdre = re.compile(r"^(/me|PESTERCHUM:ME)(\S*)") + # TODO: At some point, this needs to have support for setting up + # optimization controls - so ctags will be rendered down into things like + # "" instead of "". + # I'd make this the default, but I'd like to retain *some* compatibility + # with Chumdroid's faulty implementation...or at least have the option to. + def lex(self, string): lexlist = [ ##(mecmd, self._mecmdre), diff --git a/pnc/unicolor.py b/pnc/unicolor.py index da29939..fdfb3e8 100644 --- a/pnc/unicolor.py +++ b/pnc/unicolor.py @@ -37,27 +37,6 @@ class Color(object): # TODO: color_for_name() # TODO: Split __init__, partly using __new__, so the former just has to do # conversions - ##def __new__(cls, *args, **kwargs): - ## nargs = len(args) - ## if nargs > 0: arg = args[0] - ## if (nargs == 1 - ## and isinstance(arg, basestr) and not arg.startswith('#') - ## ): - ## # Try to look up the color name - ## name = arg.lower() - ## try: - ## color = _svg_colors[name] - ## except LookupError: - ## # We don't have a color with that name - ## raise ValueError("No color with name '%s' found" % name) - ## else: - ## # Hand over a copy of the color we found - ## return cls(color) - ## else: - ## return super(Color, cls).__new__(cls) - ## inst = super(Color, cls).__new__(cls) - ## inst.ccode = '' - ## nargs = len(args) def __init__(self, *args, **kwargs): self.ccode = '' self.closest_name = self.name = None @@ -284,37 +263,47 @@ class Color(object): def hexstr_to_rgb(cls, hexstr): hexstr = cls.sanitize_hex(hexstr) hexstr = hexstr.lstrip('#') - # This is ugly, but the purpose is simple and it's accomplished in a - # single line...it just runs through the string, picking two characters - # at a time and converting them from hex values to ints. - result = tuple(int(hexstr[i:i+2], 16) for i in range(len(hexstr))[::2]) + if len(hexstr) == 3: + # NOTE: This will presently never happen, due to the way + # sanitize_hex works. + # We have something like '#FEF', which means '#FFEEFF'. Expand it + # first. + # Multiplying each element by 17 expands it. Dividing it does the + # opposite. + result = tuple( (int(h, 16) * 17) for h in hexstr ) + else: + # This is ugly, but the purpose is simple and it's accomplished in + # a single line...it just runs through the string, picking two + # characters at a time and converting them from hex values to ints. + result = tuple( + int(hexstr[i:i+2], 16) for i in range(0, len(hexstr), 2) + ) return result - ##working = collections.deque(hexstr) - ##result = [] - ### The alternative to doing it this way would be to use an int-driven - ### 'for' loop, or similar which might be preferable - ##while working: - ## # Fetch the next two args and convert them to an int - ## i = int(working.popleft() + working.popleft(), 16) - ## result.append(i) @staticmethod - def rgb_to_hexstr(red, green, blue): + def rgb_to_hexstr(red, green, blue, compress=False): rgb = [red, green, blue] rgb = map(abs, rgb) - # Preemptively add the '#' to our result - result = ['#'] + result = [] for c in rgb: - ### Convert to hex, stripping the leading "0x" that Python adds - ##c = hex(c).lstrip("0x", 1) - ### Add a '0' in front if it's just a single digit - ##c = ('0' + c)[-2:] c = "%02X" % c # Append to our result result.append(c) + if compress: + # Try to compress this down from six characters to three. + # Basically the same thing as reduce_hexstr. Might make it use that + # later. + for h in result: + if h[0] != h[1]: + # We can't compress this; alas. + # Break out so we don't go to the 'else' segment. + break + else: + # All of our codes were doubles; compress them all down. + result = [h[0] for h in result] # Join and return the result - return ''.join(result) + return '#' + ''.join(result) # These next two are from http://www.easyrgb.com/index.php?X=MATH @staticmethod @@ -355,37 +344,46 @@ class Color(object): @staticmethod def reduce_hexstr(hexstr): + """Attempt to reduce a six-character hexadecimal color code down to a + four-character one.""" orig = hexstr hexstr = hexstr.lstrip('#') - lhexstr = hexstr.lower() strlen = len(hexstr) - working = ['#'] - for i in range(strlen)[::2]: - if lhexstr[i] == lhexstr[i+1]: - # The two characters fetched are the same, so we can reduce - working.append(hexstr[i]) - else: - # The two characters differ, so we can't actually reduce this - # string at all; just return the original + h = hexstr.upper() + for i in range(0, strlen, 2): + if h[i] != h[i+1]: + # We found a match that wouldn't work; give back the old value. return orig - # If we got here, we successfully reduced - return ''.join(working) + else: + # All of these can be reduced; do so and return. + return '#' + hexstr[::2] @staticmethod def sanitize_hex(hexstr): + orig = hexstr hexstr = hexstr.upper() # We don't need the leading hash mark for now hexstr = hexstr.lstrip('#') strlen = len(hexstr) if strlen == 6: - return '#' + hexstr + # We just need to test this for validity. Fall through to the end. + pass elif strlen == 3: # We have a short (CSS style) code; duplicate all of the characters hexstr = [c + c for c in hexstr] hexstr = ''.join(hexstr) - return '#' + hexstr - # Should probably error out, but that can wait until later + else: + raise ValueError( + "Invalid hexadecimal value provided: %s" % orig + ) + try: + # Make sure it works/is readable (no invalid characters). + int(hexstr, 16) + except ValueError: + raise ValueError( + "Invalid hexadecimal value provided: %s" % orig + ) return '#' + hexstr def to_cielab_tuple(self): diff --git a/profile.py b/profile.py index 029f9f5..db0d98a 100644 --- a/profile.py +++ b/profile.py @@ -97,9 +97,8 @@ class userConfig(object): self.NEWCONVO = 8 self.INITIALS = 16 self.filename = _datadir+"pesterchum.js" - fp = open(self.filename) - self.config = json.load(fp) - fp.close() + with open(self.filename) as fp: + self.config = json.load(fp) if self.config.has_key("defaultprofile"): self.userprofile = userProfile(self.config["defaultprofile"]) else: @@ -110,28 +109,21 @@ class userConfig(object): if not os.path.exists(self.logpath): os.makedirs(self.logpath) try: - fp = open("%s/groups.js" % (self.logpath), 'r') - self.groups = json.load(fp) - fp.close() - except IOError: + with open("%s/groups.js" % (self.logpath), 'r') as fp: + self.groups = json.load(fp) + except (IOError, ValueError): self.groups = {} - fp = open("%s/groups.js" % (self.logpath), 'w') - json.dump(self.groups, fp) - fp.close() - except ValueError: - self.groups = {} - fp = open("%s/groups.js" % (self.logpath), 'w') - json.dump(self.groups, fp) - fp.close() + with open("%s/groups.js" % (self.logpath), 'w') as fp: + json.dump(self.groups, fp) def chums(self): if not self.config.has_key('chums'): self.set("chums", []) return self.config.get('chums', []) def setChums(self, newchums): - fp = open(self.filename) # what if we have two clients open?? - newconfig = json.load(fp) - fp.close() + with open(self.filename) as fp: + # what if we have two clients open?? + newconfig = json.load(fp) oldchums = newconfig['chums'] # Time to merge these two! :OOO for c in list(set(oldchums) - set(newchums)): @@ -225,9 +217,9 @@ class userConfig(object): return self.config.get('ghostchum', False) def addChum(self, chum): if chum.handle not in self.chums(): - fp = open(self.filename) # what if we have two clients open?? - newconfig = json.load(fp) - fp.close() + with open(self.filename) as fp: + # what if we have two clients open?? + newconfig = json.load(fp) newchums = newconfig['chums'] + [chum.handle] self.set("chums", newchums) def removeChum(self, chum): @@ -285,11 +277,10 @@ class userConfig(object): self.groups['groups'] = groups try: jsonoutput = json.dumps(self.groups) - except ValueError, e: + except ValueError as e: raise e - fp = open("%s/groups.js" % (self.logpath), 'w') - fp.write(jsonoutput) - fp.close() + with open("%s/groups.js" % (self.logpath), 'w') as fp: + fp.write(jsonoutput) def server(self): if hasattr(self.parent, 'serverOverride'): @@ -319,11 +310,10 @@ class userConfig(object): self.config[item] = setting try: jsonoutput = json.dumps(self.config) - except ValueError, e: + except ValueError as e: raise e - fp = open(self.filename, 'w') - fp.write(jsonoutput) - fp.close() + with open(self.filename, 'w') as fp: + fp.write(jsonoutput) def availableThemes(self): themes = [] # Load user themes. @@ -372,12 +362,11 @@ class userProfile(object): self.mentions = [] self.autojoins = [] else: - fp = open("%s/%s.js" % (self.profiledir, user)) - self.userprofile = json.load(fp) - fp.close() + with open("%s/%s.js" % (self.profiledir, user)) as fp: + self.userprofile = json.load(fp) try: self.theme = pesterTheme(self.userprofile["theme"]) - except ValueError, e: + except ValueError: self.theme = pesterTheme("pesterchum") self.lastmood = self.userprofile.get('lastmood', self.theme["main/defaultmood"]) self.chat = PesterProfile(self.userprofile["handle"], @@ -402,7 +391,7 @@ class userProfile(object): try: with open(_datadir+"passwd.js") as fp: self.passwd = json.load(fp) - except Exception, e: + except: self.passwd = {} self.autoidentify = False self.nickservpass = "" @@ -479,11 +468,10 @@ class userProfile(object): return try: jsonoutput = json.dumps(self.userprofile) - except ValueError, e: + except ValueError as e: raise e - fp = open("%s/%s.js" % (self.profiledir, handle), 'w') - fp.write(jsonoutput) - fp.close() + with open("%s/%s.js" % (self.profiledir, handle), 'w') as fp: + fp.write(jsonoutput) def saveNickServPass(self): # remove profiles with no passwords for h,t in self.passwd.items(): @@ -491,7 +479,7 @@ class userProfile(object): del self.passwd[h] try: jsonoutput = json.dumps(self.passwd, indent=4) - except ValueError, e: + except ValueError as e: raise e with open(_datadir+"passwd.js", 'w') as fp: fp.write(jsonoutput) @@ -511,19 +499,13 @@ class PesterProfileDB(dict): if not os.path.exists(self.logpath): os.makedirs(self.logpath) try: - fp = open("%s/chums.js" % (self.logpath), 'r') - chumdict = json.load(fp) - fp.close() - except IOError: + with open("%s/chums.js" % (self.logpath), 'r') as fp: + chumdict = json.load(fp) + except (IOError, ValueError): + # karxi: This code feels awfully familiar.... chumdict = {} - fp = open("%s/chums.js" % (self.logpath), 'w') - json.dump(chumdict, fp) - fp.close() - except ValueError: - chumdict = {} - fp = open("%s/chums.js" % (self.logpath), 'w') - json.dump(chumdict, fp) - fp.close() + with open("%s/chums.js" % (self.logpath), 'w') as fp: + json.dump(chumdict, fp) u = [] for (handle, c) in chumdict.iteritems(): @@ -542,11 +524,10 @@ class PesterProfileDB(dict): def save(self): try: - fp = open("%s/chums.js" % (self.logpath), 'w') - chumdict = dict([p.plaindict() for p in self.itervalues()]) - json.dump(chumdict, fp) - fp.close() - except Exception, e: + with open("%s/chums.js" % (self.logpath), 'w') as fp: + chumdict = dict([p.plaindict() for p in self.itervalues()]) + json.dump(chumdict, fp) + except Exception as e: raise e def getColor(self, handle, default=None): if not self.has_key(handle): @@ -598,9 +579,8 @@ class pesterTheme(dict): self.name = name try: - fp = open(self.path+"/style.js") - theme = json.load(fp, object_hook=self.pathHook) - fp.close() + with open(self.path+"/style.js") as fp: + theme = json.load(fp, object_hook=self.pathHook) except IOError: theme = json.loads("{}") self.update(theme) @@ -612,7 +592,7 @@ class pesterTheme(dict): keys = key.split("/") try: v = dict.__getitem__(self, keys.pop(0)) - except KeyError, e: + except KeyError as e: if hasattr(self, 'inheritedTheme'): return self.inheritedTheme[key] if hasattr(self, 'defaultTheme'): @@ -622,7 +602,7 @@ class pesterTheme(dict): for k in keys: try: v = v[k] - except KeyError, e: + except KeyError as e: if hasattr(self, 'inheritedTheme'): return self.inheritedTheme[key] if hasattr(self, 'defaultTheme'): diff --git a/quirks.py b/quirks.py index e07b14b..48e3b85 100644 --- a/quirks.py +++ b/quirks.py @@ -64,7 +64,7 @@ class ScriptQuirks(object): module = self.loadModule(name, filename) if module is None: continue - except Exception, e: + except Exception as e: print "Error loading %s: %s (in quirks.py)" % (os.path.basename(name), e) msgbox = QtGui.QMessageBox() msgbox.setWindowTitle("Error!") diff --git a/updatecheck.py b/updatecheck.py index ef88e25..00d5ec9 100644 --- a/updatecheck.py +++ b/updatecheck.py @@ -36,7 +36,7 @@ class MSPAChecker(QtGui.QWidget): raise if os.path.exists("status_old.pkl"): os.remove("status_old.pkl") - except Exception, e: + except Exception as e: print e msg = QtGui.QMessageBox(self) msg.setText("Problems writing save file.")