diff --git a/contrib/check-code.py b/contrib/check-code.py
--- a/contrib/check-code.py
+++ b/contrib/check-code.py
@@ -455,7 +455,7 @@ def checkfile(f, logfunc=_defaultlogger.
 
     try:
         fp = open(f)
-    except IOError, e:
+    except IOError as e:
         print "Skipping %s, %s" % (f, str(e).split(':', 1)[0])
         return result
     pre = post = fp.read()
diff --git a/contrib/import-checker.py b/contrib/import-checker.py
--- a/contrib/import-checker.py
+++ b/contrib/import-checker.py
@@ -328,7 +328,7 @@ def find_cycles(imports):
     for mod in sorted(imports.iterkeys()):
         try:
             checkmod(mod, imports)
-        except CircularImport, e:
+        except CircularImport as e:
             cycle = e.args[0]
             cycles.add(" -> ".join(rotatecycle(cycle)))
     return cycles
diff --git a/contrib/revsetbenchmarks.py b/contrib/revsetbenchmarks.py
--- a/contrib/revsetbenchmarks.py
+++ b/contrib/revsetbenchmarks.py
@@ -33,7 +33,7 @@ def update(rev):
     """update the repo to a revision"""
     try:
         check_call(['hg', 'update', '--quiet', '--check', str(rev)])
-    except CalledProcessError, exc:
+    except CalledProcessError as exc:
         print >> sys.stderr, 'update to revision %s failed, aborting' % rev
         sys.exit(exc.returncode)
 
@@ -56,7 +56,7 @@ def perf(revset, target=None):
     try:
         output = hg(['perfrevset', revset], repo=target)
         return parseoutput(output)
-    except CalledProcessError, exc:
+    except CalledProcessError as exc:
         print >> sys.stderr, 'abort: cannot run revset benchmark: %s' % exc.cmd
         if exc.output is None:
             print >> sys.stderr, '(no ouput)'
@@ -201,7 +201,7 @@ def getrevs(spec):
     """get the list of rev matched by a revset"""
     try:
         out = check_output(['hg', 'log', '--template={rev}\n', '--rev', spec])
-    except CalledProcessError, exc:
+    except CalledProcessError as exc:
         print >> sys.stderr, "abort, can't get revision from %s" % spec
         sys.exit(exc.returncode)
     return [r for r in out.split() if r]
diff --git a/contrib/synthrepo.py b/contrib/synthrepo.py
--- a/contrib/synthrepo.py
+++ b/contrib/synthrepo.py
@@ -253,7 +253,7 @@ def synthesize(ui, repo, descpath, **opt
     '''
     try:
         fp = hg.openpath(ui, descpath)
-    except Exception, err:
+    except Exception as err:
         raise util.Abort('%s: %s' % (descpath, err[0].strerror))
     desc = json.load(fp)
     fp.close()
@@ -285,7 +285,7 @@ def synthesize(ui, repo, descpath, **opt
     dictfile = opts.get('dict') or '/usr/share/dict/words'
     try:
         fp = open(dictfile, 'rU')
-    except IOError, err:
+    except IOError as err:
         raise util.Abort('%s: %s' % (dictfile, err.strerror))
     words = fp.read().splitlines()
     fp.close()
diff --git a/hgext/blackbox.py b/hgext/blackbox.py
--- a/hgext/blackbox.py
+++ b/hgext/blackbox.py
@@ -52,14 +52,14 @@ def wrapui(ui):
             def rotate(oldpath, newpath):
                 try:
                     os.unlink(newpath)
-                except OSError, err:
+                except OSError as err:
                     if err.errno != errno.ENOENT:
                         self.debug("warning: cannot remove '%s': %s\n" %
                                    (newpath, err.strerror))
                 try:
                     if newpath:
                         os.rename(oldpath, newpath)
-                except OSError, err:
+                except OSError as err:
                     if err.errno != errno.ENOENT:
                         self.debug("warning: cannot rename '%s' to '%s': %s\n" %
                                    (newpath, oldpath, err.strerror))
@@ -92,7 +92,7 @@ def wrapui(ui):
             elif util.safehasattr(self, '_bbopener'):
                 try:
                     self._blackbox = self._openlogfile()
-                except (IOError, OSError), err:
+                except (IOError, OSError) as err:
                     self.debug('warning: cannot write to blackbox.log: %s\n' %
                                err.strerror)
                     del self._bbopener
@@ -110,7 +110,7 @@ def wrapui(ui):
                 formattedmsg = msg[0] % msg[1:]
                 try:
                     blackbox.write('%s %s> %s' % (date, user, formattedmsg))
-                except IOError, err:
+                except IOError as err:
                     self.debug('warning: cannot write to blackbox.log: %s\n' %
                                err.strerror)
                 lastblackbox = blackbox
diff --git a/hgext/bugzilla.py b/hgext/bugzilla.py
--- a/hgext/bugzilla.py
+++ b/hgext/bugzilla.py
@@ -357,7 +357,7 @@ class bzmysql(bzaccess):
         try:
             import MySQLdb as mysql
             bzmysql._MySQLdb = mysql
-        except ImportError, err:
+        except ImportError as err:
             raise util.Abort(_('python mysql support not available: %s') % err)
 
         bzaccess.__init__(self, ui)
@@ -910,5 +910,5 @@ def hook(ui, repo, hooktype, node=None, 
             for bug in bugs:
                 bz.update(bug, bugs[bug], ctx)
             bz.notify(bugs, util.email(ctx.user()))
-    except Exception, e:
+    except Exception as e:
         raise util.Abort(_('Bugzilla error: %s') % e)
diff --git a/hgext/censor.py b/hgext/censor.py
--- a/hgext/censor.py
+++ b/hgext/censor.py
@@ -147,7 +147,7 @@ def censor(ui, repo, path, rev='', tombs
             # Immediate children of censored node must be re-added as fulltext.
             try:
                 revdata = flog.revision(srev)
-            except error.CensoredNodeError, e:
+            except error.CensoredNodeError as e:
                 revdata = e.tombstone
             dlen = rewrite(srev, offset, revdata)
         else:
diff --git a/hgext/churn.py b/hgext/churn.py
--- a/hgext/churn.py
+++ b/hgext/churn.py
@@ -26,7 +26,7 @@ def maketemplater(ui, repo, tmpl):
     try:
         t = cmdutil.changeset_templater(ui, repo, False, None, tmpl,
                                         None, False)
-    except SyntaxError, inst:
+    except SyntaxError as inst:
         raise util.Abort(inst.args[0])
     return t
 
diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -194,7 +194,7 @@ def _terminfosetup(ui, mode):
 
     try:
         curses.setupterm()
-    except curses.error, e:
+    except curses.error as e:
         _terminfo_params = {}
         return
 
diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -427,7 +427,7 @@ class mapfile(dict):
             return
         try:
             fp = open(self.path, 'r')
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
             return
@@ -451,7 +451,7 @@ class mapfile(dict):
         if self.fp is None:
             try:
                 self.fp = open(self.path, 'a')
-            except IOError, err:
+            except IOError as err:
                 raise util.Abort(_('could not open map file %r: %s') %
                                  (self.path, err.strerror))
         self.fp.write('%s %s\n' % (key, value))
diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py
+++ b/hgext/convert/convcmd.py
@@ -54,7 +54,7 @@ def convertsource(ui, path, type, rev):
         try:
             if not type or name == type:
                 return source(ui, path, rev), sortmode
-        except (NoRepo, MissingTool), inst:
+        except (NoRepo, MissingTool) as inst:
             exceptions.append(inst)
     if not ui.quiet:
         for inst in exceptions:
@@ -68,9 +68,9 @@ def convertsink(ui, path, type):
         try:
             if not type or name == type:
                 return sink(ui, path)
-        except NoRepo, inst:
+        except NoRepo as inst:
             ui.note(_("convert: %s\n") % inst)
-        except MissingTool, inst:
+        except MissingTool as inst:
             raise util.Abort('%s\n' % inst)
     raise util.Abort(_('%s: unknown repository type') % path)
 
diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py
--- a/hgext/convert/cvs.py
+++ b/hgext/convert/cvs.py
@@ -136,7 +136,7 @@ class convert_cvs(converter_source):
                                 passw = part2
                                 break
                         pf.close()
-                    except IOError, inst:
+                    except IOError as inst:
                         if inst.errno != errno.ENOENT:
                             if not getattr(inst, 'filename', None):
                                 inst.filename = cvspass
diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py
--- a/hgext/convert/cvsps.py
+++ b/hgext/convert/cvsps.py
@@ -179,7 +179,7 @@ def createlog(ui, directory=None, root="
                     break
 
             ui.note(_('cache has %d log entries\n') % len(oldlog))
-        except Exception, e:
+        except Exception as e:
             ui.note(_('error reading cache: %r\n') % e)
 
         if oldlog:
@@ -824,7 +824,7 @@ def debugcvsps(ui, *args, **opts):
                 log += createlog(ui, d, root=opts["root"], cache=cache)
         else:
             log = createlog(ui, root=opts["root"], cache=cache)
-    except logerror, e:
+    except logerror as e:
         ui.write("%r\n"%e)
         return
 
diff --git a/hgext/convert/darcs.py b/hgext/convert/darcs.py
--- a/hgext/convert/darcs.py
+++ b/hgext/convert/darcs.py
@@ -197,7 +197,7 @@ class darcs_source(converter_source, com
         try:
             data = util.readfile(path)
             mode = os.lstat(path).st_mode
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno == errno.ENOENT:
                 return None, None
             raise
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -42,7 +42,7 @@ class mercurial_sink(converter_sink):
                 if not self.repo.local():
                     raise NoRepo(_('%s is not a local Mercurial repository')
                                  % path)
-            except error.RepoError, err:
+            except error.RepoError as err:
                 ui.traceback()
                 raise NoRepo(err.args[0])
         else:
@@ -487,7 +487,7 @@ class mercurial_source(converter_source)
                 copies[name] = copysource
             except TypeError:
                 pass
-            except error.LookupError, e:
+            except error.LookupError as e:
                 if not self.ignoreerrors:
                     raise
                 self.ignored.add(name)
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -126,7 +126,7 @@ def get_log_child(fp, url, paths, start,
     except IOError:
         # Caller may interrupt the iteration
         pickle.dump(None, fp, protocol)
-    except Exception, inst:
+    except Exception as inst:
         pickle.dump(str(inst), fp, protocol)
     else:
         pickle.dump(None, fp, protocol)
@@ -216,7 +216,7 @@ def httpcheck(ui, path, proto):
         opener = urllib2.build_opener()
         rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path))
         data = rsp.read()
-    except urllib2.HTTPError, inst:
+    except urllib2.HTTPError as inst:
         if inst.code != 404:
             # Except for 404 we cannot know for sure this is not an svn repo
             ui.warn(_('svn: cannot probe remote repository, assume it could '
@@ -944,7 +944,8 @@ class svn_source(converter_source):
                             firstcset.parents.append(latest)
                 except SvnPathNotFound:
                     pass
-        except SubversionException, (inst, num):
+        except SubversionException as xxx_todo_changeme:
+            (inst, num) = xxx_todo_changeme.args
             if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
                 raise util.Abort(_('svn: branch has no revision %s')
                                  % to_revnum)
@@ -970,7 +971,7 @@ class svn_source(converter_source):
                 info = info[-1]
             mode = ("svn:executable" in info) and 'x' or ''
             mode = ("svn:special" in info) and 'l' or mode
-        except SubversionException, e:
+        except SubversionException as e:
             notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
                 svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
             if e.apr_err in notfound: # File not found
diff --git a/hgext/convert/transport.py b/hgext/convert/transport.py
--- a/hgext/convert/transport.py
+++ b/hgext/convert/transport.py
@@ -87,7 +87,8 @@ class SvnRaTransport(object):
                 self.ra = svn.client.open_ra_session(
                     self.svn_url,
                     self.client, self.pool)
-            except SubversionException, (inst, num):
+            except SubversionException as xxx_todo_changeme:
+                (inst, num) = xxx_todo_changeme.args
                 if num in (svn.core.SVN_ERR_RA_ILLEGAL_URL,
                            svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED,
                            svn.core.SVN_ERR_BAD_URL):
diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -218,7 +218,7 @@ def parseeol(ui, repo, nodes):
                 return eolfile(ui, repo.root, data)
             except (IOError, LookupError):
                 pass
-    except error.ParseError, inst:
+    except error.ParseError as inst:
         ui.warn(_("warning: ignoring .hgeol file due to parse error "
                   "at %s: %s\n") % (inst.args[1], inst.args[0]))
     return None
diff --git a/hgext/gpg.py b/hgext/gpg.py
--- a/hgext/gpg.py
+++ b/hgext/gpg.py
@@ -283,7 +283,7 @@ def sign(ui, repo, *revs, **opts):
         editor = cmdutil.getcommiteditor(editform='gpg.sign', **opts)
         repo.commit(message, opts['user'], opts['date'], match=msigs,
                     editor=editor)
-    except ValueError, inst:
+    except ValueError as inst:
         raise util.Abort(str(inst))
 
 def shortkey(ui, key):
diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -222,7 +222,7 @@ class histeditstate(object):
         """Load histedit state from disk and set fields appropriately."""
         try:
             fp = self.repo.vfs('histedit-state', 'r')
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
             raise util.Abort(_('no histedit in progress'))
diff --git a/hgext/largefiles/basestore.py b/hgext/largefiles/basestore.py
--- a/hgext/largefiles/basestore.py
+++ b/hgext/largefiles/basestore.py
@@ -96,7 +96,7 @@ class basestore(object):
 
         try:
             gothash = self._getfile(tmpfile, filename, hash)
-        except StoreError, err:
+        except StoreError as err:
             self.ui.warn(err.longmessage())
             gothash = ""
         tmpfile.close()
diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py
--- a/hgext/largefiles/lfcommands.py
+++ b/hgext/largefiles/lfcommands.py
@@ -391,7 +391,7 @@ def cachelfiles(ui, repo, node, filelist
     for lfile in lfiles:
         try:
             expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
-        except IOError, err:
+        except IOError as err:
             if err.errno == errno.ENOENT:
                 continue # node must be None and standin wasn't found in wctx
             raise
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -580,7 +580,7 @@ def overridecopy(orig, ui, repo, pats, o
     installnormalfilesmatchfn(repo[None].manifest())
     try:
         result = orig(ui, repo, pats, opts, rename)
-    except util.Abort, e:
+    except util.Abort as e:
         if str(e) != _('no files to copy'):
             raise e
         else:
@@ -682,7 +682,7 @@ def overridecopy(orig, ui, repo, pats, o
 
                 lfdirstate.add(destlfile)
         lfdirstate.write()
-    except util.Abort, e:
+    except util.Abort as e:
         if str(e) != _('no files to copy'):
             raise e
         else:
diff --git a/hgext/largefiles/proto.py b/hgext/largefiles/proto.py
--- a/hgext/largefiles/proto.py
+++ b/hgext/largefiles/proto.py
@@ -37,7 +37,7 @@ def putlfile(repo, proto, sha):
             raise IOError(0, _('largefile contents do not match hash'))
         tmpfp.close()
         lfutil.linktousercache(repo, sha)
-    except IOError, e:
+    except IOError as e:
         repo.ui.warn(_('largefiles: failed to put %s into store: %s\n') %
                      (sha, e.strerror))
         return wireproto.pushres(1)
diff --git a/hgext/largefiles/remotestore.py b/hgext/largefiles/remotestore.py
--- a/hgext/largefiles/remotestore.py
+++ b/hgext/largefiles/remotestore.py
@@ -38,7 +38,7 @@ class remotestore(basestore.basestore):
         try:
             fd = lfutil.httpsendfile(self.ui, filename)
             return self._put(hash, fd)
-        except IOError, e:
+        except IOError as e:
             raise util.Abort(
                 _('remotestore: could not open file %s: %s')
                 % (filename, str(e)))
@@ -49,17 +49,17 @@ class remotestore(basestore.basestore):
     def _getfile(self, tmpfile, filename, hash):
         try:
             chunks = self._get(hash)
-        except urllib2.HTTPError, e:
+        except urllib2.HTTPError as e:
             # 401s get converted to util.Aborts; everything else is fine being
             # turned into a StoreError
             raise basestore.StoreError(filename, hash, self.url, str(e))
-        except urllib2.URLError, e:
+        except urllib2.URLError as e:
             # This usually indicates a connection problem, so don't
             # keep trying with the other files... they will probably
             # all fail too.
             raise util.Abort('%s: %s' %
                              (util.hidepassword(self.url), e.reason))
-        except IOError, e:
+        except IOError as e:
             raise basestore.StoreError(filename, hash, self.url, str(e))
 
         return lfutil.copyandhash(chunks, tmpfile)
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -448,7 +448,7 @@ class queue(object):
         try:
             lines = self.opener.read(self.statuspath).splitlines()
             return list(parselines(lines))
-        except IOError, e:
+        except IOError as e:
             if e.errno == errno.ENOENT:
                 return []
             raise
@@ -457,7 +457,7 @@ class queue(object):
     def fullseries(self):
         try:
             return self.opener.read(self.seriespath).splitlines()
-        except IOError, e:
+        except IOError as e:
             if e.errno == errno.ENOENT:
                 return []
             raise
@@ -574,7 +574,7 @@ class queue(object):
             self.activeguards = []
             try:
                 guards = self.opener.read(self.guardspath).split()
-            except IOError, err:
+            except IOError as err:
                 if err.errno != errno.ENOENT:
                     raise
                 guards = []
@@ -675,7 +675,7 @@ class queue(object):
             return
         try:
             os.unlink(undo)
-        except OSError, inst:
+        except OSError as inst:
             self.ui.warn(_('error removing undo: %s\n') % str(inst))
 
     def backup(self, repo, files, copy=False):
@@ -804,7 +804,7 @@ class queue(object):
             fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1,
                                   files=files, eolmode=None)
             return (True, list(files), fuzz)
-        except Exception, inst:
+        except Exception as inst:
             self.ui.note(str(inst) + '\n')
             if not self.ui.verbose:
                 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
@@ -959,7 +959,7 @@ class queue(object):
             for p in patches:
                 try:
                     os.unlink(self.join(p))
-                except OSError, inst:
+                except OSError as inst:
                     if inst.errno != errno.ENOENT:
                         raise
 
@@ -1159,7 +1159,7 @@ class queue(object):
             try:
                 # if patch file write fails, abort early
                 p = self.opener(patchfn, "w")
-            except IOError, e:
+            except IOError as e:
                 raise util.Abort(_('cannot write patch "%s": %s')
                                  % (patchfn, e.strerror))
             try:
@@ -1816,7 +1816,7 @@ class queue(object):
             raise util.Abort(_("patch queue directory already exists"))
         try:
             os.mkdir(self.path)
-        except OSError, inst:
+        except OSError as inst:
             if inst.errno != errno.EEXIST or not create:
                 raise
         if create:
diff --git a/hgext/notify.py b/hgext/notify.py
--- a/hgext/notify.py
+++ b/hgext/notify.py
@@ -276,7 +276,7 @@ class notifier(object):
         p = email.Parser.Parser()
         try:
             msg = p.parsestr(data)
-        except email.Errors.MessageParseError, inst:
+        except email.Errors.MessageParseError as inst:
             raise util.Abort(inst)
 
         # store sender and subject
diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -628,7 +628,7 @@ def patchbomb(ui, repo, *revs, **opts):
             try:
                 generator.flatten(m, 0)
                 fp.write('\n')
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno != errno.EPIPE:
                     raise
             if fp is not ui:
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -838,7 +838,7 @@ def restorestatus(repo):
         _setrebasesetvisibility(repo, state.keys())
         return (originalwd, target, state, skipped,
                 collapse, keep, keepbranches, external, activebookmark)
-    except IOError, err:
+    except IOError as err:
         if err.errno != errno.ENOENT:
             raise
         raise util.Abort(_('no rebase in progress'))
diff --git a/hgext/relink.py b/hgext/relink.py
--- a/hgext/relink.py
+++ b/hgext/relink.py
@@ -178,7 +178,7 @@ def do_relink(src, dst, files, ui):
             ui.progress(_('relinking'), pos, f, _('files'), total)
             relinked += 1
             savedbytes += sz
-        except OSError, inst:
+        except OSError as inst:
             ui.warn('%s: %s\n' % (tgt, str(inst)))
 
     ui.progress(_('relinking'), None)
diff --git a/hgext/share.py b/hgext/share.py
--- a/hgext/share.py
+++ b/hgext/share.py
@@ -84,7 +84,7 @@ def _hassharedbookmarks(repo):
     """Returns whether this repo has shared bookmarks"""
     try:
         shared = repo.vfs.read('shared').splitlines()
-    except IOError, inst:
+    except IOError as inst:
         if inst.errno != errno.ENOENT:
             raise
         return False
diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -69,7 +69,7 @@ class shelvedfile(object):
     def opener(self, mode='rb'):
         try:
             return self.vfs(self.fname, mode)
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
             raise util.Abort(_("shelved change '%s' not found") % self.name)
@@ -294,7 +294,7 @@ def deletecmd(ui, repo, pats):
         for name in pats:
             for suffix in 'hg patch'.split():
                 shelvedfile(repo, name, suffix).unlink()
-    except OSError, err:
+    except OSError as err:
         if err.errno != errno.ENOENT:
             raise
         raise util.Abort(_("shelved change '%s' not found") % name)
@@ -305,7 +305,7 @@ def listshelves(repo):
     """return all shelves in repo as list of (time, filename)"""
     try:
         names = repo.vfs.readdir('shelved')
-    except OSError, err:
+    except OSError as err:
         if err.errno != errno.ENOENT:
             raise
         return []
@@ -532,7 +532,7 @@ def unshelve(ui, repo, *shelved, **opts)
 
         try:
             state = shelvedstate.load(repo)
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
             raise util.Abort(_('no unshelve operation underway'))
diff --git a/hgext/transplant.py b/hgext/transplant.py
--- a/hgext/transplant.py
+++ b/hgext/transplant.py
@@ -272,7 +272,7 @@ class transplanter(object):
                 files = set()
                 patch.patch(self.ui, repo, patchfile, files=files, eolmode=None)
                 files = list(files)
-            except Exception, inst:
+            except Exception as inst:
                 seriespath = os.path.join(self.path, 'series')
                 if os.path.exists(seriespath):
                     os.unlink(seriespath)
diff --git a/i18n/polib.py b/i18n/polib.py
--- a/i18n/polib.py
+++ b/i18n/polib.py
@@ -1276,7 +1276,7 @@ class _POFileParser(object):
             (action, state) = self.transitions[(symbol, self.current_state)]
             if action():
                 self.current_state = state
-        except Exception, exc:
+        except Exception as exc:
             raise IOError('Syntax error in po file (line %s)' % linenum)
 
     # state handlers
diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -45,7 +45,7 @@ class bmstore(dict):
                     self[refspec] = repo.changelog.lookup(sha)
                 except LookupError:
                     pass
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
 
@@ -54,7 +54,7 @@ class bmstore(dict):
         if 'HG_PENDING' in os.environ:
             try:
                 bkfile = repo.vfs('bookmarks.pending')
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno != errno.ENOENT:
                     raise
         if bkfile is None:
@@ -116,7 +116,7 @@ def readactive(repo):
     mark = None
     try:
         file = repo.vfs('bookmarks.current')
-    except IOError, inst:
+    except IOError as inst:
         if inst.errno != errno.ENOENT:
             raise
         return None
@@ -159,7 +159,7 @@ def deactivate(repo):
     try:
         repo.vfs.unlink('bookmarks.current')
         repo._activebookmark = None
-    except OSError, inst:
+    except OSError as inst:
         if inst.errno != errno.ENOENT:
             raise
     finally:
diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -55,7 +55,7 @@ def read(repo):
                 partial._closednodes.add(node)
     except KeyboardInterrupt:
         raise
-    except Exception, inst:
+    except Exception as inst:
         if repo.ui.debugflag:
             msg = 'invalid branchheads cache'
             if repo.filtername is not None:
@@ -203,7 +203,7 @@ class branchcache(dict):
             repo.ui.log('branchcache',
                         'wrote %s branch cache with %d labels and %d nodes\n',
                         repo.filtername, len(self), nodecount)
-        except (IOError, OSError, util.Abort), inst:
+        except (IOError, OSError, util.Abort) as inst:
             repo.ui.debug("couldn't write branch cache: %s\n" % inst)
             # Abort may be raise by read only opener
             pass
@@ -315,7 +315,7 @@ class revbranchcache(object):
             bndata = repo.vfs.read(_rbcnames)
             self._rbcsnameslen = len(bndata) # for verification before writing
             self._names = [encoding.tolocal(bn) for bn in bndata.split('\0')]
-        except (IOError, OSError), inst:
+        except (IOError, OSError) as inst:
             if readonly:
                 # don't try to use cache - fall back to the slow path
                 self.branchinfo = self._branchinfo
@@ -324,7 +324,7 @@ class revbranchcache(object):
             try:
                 data = repo.vfs.read(_rbcrevs)
                 self._rbcrevs.fromstring(data)
-            except (IOError, OSError), inst:
+            except (IOError, OSError) as inst:
                 repo.ui.debug("couldn't read revision branch cache: %s\n" %
                               inst)
         # remember number of good records on disk
@@ -418,7 +418,7 @@ class revbranchcache(object):
                                   for b in self._names[self._rbcnamescount:]))
                 self._rbcsnameslen = f.tell()
                 f.close()
-            except (IOError, OSError, util.Abort), inst:
+            except (IOError, OSError, util.Abort) as inst:
                 repo.ui.debug("couldn't write revision branch cache names: "
                               "%s\n" % inst)
                 return
@@ -436,7 +436,7 @@ class revbranchcache(object):
                 end = revs * _rbcrecsize
                 f.write(self._rbcrevs[start:end])
                 f.close()
-            except (IOError, OSError, util.Abort), inst:
+            except (IOError, OSError, util.Abort) as inst:
                 repo.ui.debug("couldn't write revision branch cache: %s\n" %
                               inst)
                 return
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -336,7 +336,7 @@ def processbundle(repo, unbundler, trans
     try:
         for nbpart, part in iterparts:
             _processpart(op, part)
-    except BaseException, exc:
+    except BaseException as exc:
         for nbpart, part in iterparts:
             # consume the bundle content
             part.seek(0, 2)
@@ -380,7 +380,7 @@ def _processpart(op, part):
                 raise error.UnsupportedPartError(parttype=part.type,
                                                params=unknownparams)
             status = 'supported'
-        except error.UnsupportedPartError, exc:
+        except error.UnsupportedPartError as exc:
             if part.mandatory: # mandatory parts
                 raise
             indebug(op.ui, 'ignoring unsupported advisory part %s' % exc)
@@ -585,7 +585,7 @@ class unpackermixin(object):
         if self._seekable:
             try:
                 return self._fp.tell()
-            except IOError, e:
+            except IOError as e:
                 if e.errno == errno.ESPIPE:
                     self._seekable = False
                 else:
@@ -841,7 +841,7 @@ class bundlepart(object):
                 outdebug(ui, 'payload chunk size: %i' % len(chunk))
                 yield _pack(_fpayloadsize, len(chunk))
                 yield chunk
-        except BaseException, exc:
+        except BaseException as exc:
             # backup exception data for later
             ui.debug('bundle2-input-stream-interrupt: encoding exception %s'
                      % exc)
@@ -1248,7 +1248,7 @@ def handleremotechangegroup(op, inpart):
         part.addparam('return', '%i' % ret, mandatory=False)
     try:
         real_part.validate()
-    except util.Abort, e:
+    except util.Abort as e:
         raise util.Abort(_('bundle at %s is corrupted:\n%s') %
             (util.hidepassword(raw_url), str(e)))
     assert not inpart.read()
diff --git a/mercurial/byterange.py b/mercurial/byterange.py
--- a/mercurial/byterange.py
+++ b/mercurial/byterange.py
@@ -264,7 +264,7 @@ class FTPRangeHandler(urllib2.FTPHandler
 
         try:
             host = socket.gethostbyname(host)
-        except socket.error, msg:
+        except socket.error as msg:
             raise urllib2.URLError(msg)
         path, attrs = splitattr(req.get_selector())
         dirs = path.split('/')
@@ -322,7 +322,7 @@ class FTPRangeHandler(urllib2.FTPHandler
                 headers += "Content-Length: %d\n" % retrlen
             headers = email.message_from_string(headers)
             return addinfourl(fp, headers, req.get_full_url())
-        except ftplib.all_errors, msg:
+        except ftplib.all_errors as msg:
             raise IOError('ftp error', msg)
 
     def connect_ftp(self, user, passwd, host, port, dirs):
@@ -352,7 +352,7 @@ class ftpwrapper(urllib.ftpwrapper):
             # Use nlst to see if the file exists at all
             try:
                 self.ftp.nlst(file)
-            except ftplib.error_perm, reason:
+            except ftplib.error_perm as reason:
                 raise IOError('ftp error', reason)
             # Restore the transfer mode!
             self.ftp.voidcmd(cmd)
@@ -360,7 +360,7 @@ class ftpwrapper(urllib.ftpwrapper):
             try:
                 cmd = 'RETR ' + file
                 conn = self.ftp.ntransfercmd(cmd, rest)
-            except ftplib.error_perm, reason:
+            except ftplib.error_perm as reason:
                 if str(reason).startswith('501'):
                     # workaround for REST not supported error
                     fp, retrlen = self.retrfile(file, type)
diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -491,7 +491,7 @@ class cg1packer(object):
         if revlog.iscensored(base) or revlog.iscensored(rev):
             try:
                 delta = revlog.revision(node)
-            except error.CensoredNodeError, e:
+            except error.CensoredNodeError as e:
                 delta = e.tombstone
             if base == nullrev:
                 prefix = mdiff.trivialdiffheader(len(delta))
@@ -665,7 +665,7 @@ def addchangegroupfiles(repo, source, re
         try:
             if not fl.addgroup(source, revmap, trp):
                 raise util.Abort(_("received file revlog group is empty"))
-        except error.CensoredBaseError, e:
+        except error.CensoredBaseError as e:
             raise util.Abort(_("received delta base is censored: %s") % e)
         revisions += len(fl) - o
         files += 1
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -119,7 +119,7 @@ def dorecord(ui, repo, commitfunc, cmdsu
         # 1. filter patch, so we have intending-to apply subset of it
         try:
             chunks = filterfn(ui, originalchunks)
-        except patch.PatchError, err:
+        except patch.PatchError as err:
             raise util.Abort(_('error parsing patch: %s') % err)
 
         # We need to keep a backup of files that have been newly added and
@@ -153,7 +153,7 @@ def dorecord(ui, repo, commitfunc, cmdsu
             backupdir = repo.join('record-backups')
             try:
                 os.mkdir(backupdir)
-            except OSError, err:
+            except OSError as err:
                 if err.errno != errno.EEXIST:
                     raise
         try:
@@ -189,7 +189,7 @@ def dorecord(ui, repo, commitfunc, cmdsu
                     ui.debug('applying patch\n')
                     ui.debug(fp.getvalue())
                     patch.internalpatch(ui, repo, fp, 1, eolmode=None)
-                except patch.PatchError, err:
+                except patch.PatchError as err:
                     raise util.Abort(str(err))
             del fp
 
@@ -309,7 +309,7 @@ def logmessage(ui, opts):
                 message = ui.fin.read()
             else:
                 message = '\n'.join(util.readfile(logfile).splitlines())
-        except IOError, inst:
+        except IOError as inst:
             raise util.Abort(_("can't read commit message '%s': %s") %
                              (logfile, inst.strerror))
     return message
@@ -418,7 +418,7 @@ def makefilename(repo, pat, node, desc=N
             newname.append(c)
             i += 1
         return ''.join(newname)
-    except KeyError, inst:
+    except KeyError as inst:
         raise util.Abort(_("invalid format spec '%%%s' in output filename") %
                          inst.args[0])
 
@@ -605,7 +605,7 @@ def copy(ui, repo, pats, opts, rename=Fa
                 else:
                     util.copyfile(src, target)
                 srcexists = True
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno == errno.ENOENT:
                     ui.warn(_('%s: deleted in working directory\n') % relsrc)
                     srcexists = False
@@ -773,7 +773,7 @@ def service(opts, parentfn=None, initfn=
         finally:
             try:
                 os.unlink(lockpath)
-            except OSError, e:
+            except OSError as e:
                 if e.errno != errno.ENOENT:
                     raise
         if parentfn:
@@ -898,7 +898,7 @@ def tryimportone(ui, repo, hunk, parents
             try:
                 patch.patch(ui, repo, tmpname, strip=strip, prefix=prefix,
                             files=files, eolmode=None, similarity=sim / 100.0)
-            except patch.PatchError, e:
+            except patch.PatchError as e:
                 if not partial:
                     raise util.Abort(str(e))
                 if partial:
@@ -942,7 +942,7 @@ def tryimportone(ui, repo, hunk, parents
                 try:
                     patch.patchrepo(ui, repo, p1, store, tmpname, strip, prefix,
                                     files, eolmode=None)
-                except patch.PatchError, e:
+                except patch.PatchError as e:
                     raise util.Abort(str(e))
                 if opts.get('exact'):
                     editor = None
@@ -1459,10 +1459,10 @@ class changeset_templater(changeset_prin
                     self.footer = templater.stringify(self.t(types['footer'],
                                                       **props))
 
-        except KeyError, inst:
+        except KeyError as inst:
             msg = _("%s: no key named '%s'")
             raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
-        except SyntaxError, inst:
+        except SyntaxError as inst:
             raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
 
 def gettemplate(ui, tmpl, style):
@@ -1523,7 +1523,7 @@ def show_changeset(ui, repo, opts, buffe
     try:
         t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
                                 buffered)
-    except SyntaxError, inst:
+    except SyntaxError as inst:
         raise util.Abort(inst.args[0])
     return t
 
@@ -2682,7 +2682,7 @@ def buildcommittemplate(repo, ctx, subs,
 
     try:
         t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
-    except SyntaxError, inst:
+    except SyntaxError as inst:
         raise util.Abort(inst.args[0])
 
     for k, v in repo.ui.configitems('committemplate'):
@@ -3115,7 +3115,7 @@ def _performrevert(repo, parents, ctx, a
             if reversehunks:
                 chunks = patch.reversehunks(chunks)
 
-        except patch.PatchError, err:
+        except patch.PatchError as err:
             raise util.Abort(_('error parsing patch: %s') % err)
 
         newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
@@ -3128,7 +3128,7 @@ def _performrevert(repo, parents, ctx, a
         if dopatch:
             try:
                 patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
-            except patch.PatchError, err:
+            except patch.PatchError as err:
                 raise util.Abort(str(err))
         del fp
     else:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2340,7 +2340,7 @@ def debuginstall(ui):
     ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
     try:
         encoding.fromlocal("test")
-    except util.Abort, inst:
+    except util.Abort as inst:
         ui.write(" %s\n" % inst)
         ui.write(_(" (check that your locale is properly set)\n"))
         problems += 1
@@ -2358,7 +2358,7 @@ def debuginstall(ui):
     try:
         import bdiff, mpatch, base85, osutil
         dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
-    except Exception, inst:
+    except Exception as inst:
         ui.write(" %s\n" % inst)
         ui.write(_(" One or more extensions could not be found"))
         ui.write(_(" (check that you compiled the extensions)\n"))
@@ -2374,7 +2374,7 @@ def debuginstall(ui):
             # template found, check if it is working
             try:
                 templater.templater(m)
-            except Exception, inst:
+            except Exception as inst:
                 ui.write(" %s\n" % inst)
                 p = None
         else:
@@ -2406,7 +2406,7 @@ def debuginstall(ui):
     ui.status(_("checking username...\n"))
     try:
         ui.username()
-    except util.Abort, e:
+    except util.Abort as e:
         ui.write(" %s\n" % e)
         ui.write(_(" (specify a username in your configuration file)\n"))
         problems += 1
@@ -2517,7 +2517,7 @@ def debuglocks(ui, repo, **opts):
                                  % (user, pid, host)
                 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
                 return 1
-            except OSError, e:
+            except OSError as e:
                 if e.errno != errno.ENOENT:
                     raise
 
@@ -2581,7 +2581,7 @@ def debugobsolete(ui, repo, precursor=No
                                      parents=parents, date=date,
                                      metadata=metadata)
                 tr.close()
-            except ValueError, exc:
+            except ValueError as exc:
                 raise util.Abort(_('bad obsmarker input: %s') % exc)
             finally:
                 tr.release()
@@ -3470,7 +3470,7 @@ def graft(ui, repo, *revs, **opts):
         try:
             nodes = repo.vfs.read('graftstate').splitlines()
             revs = [repo[node].rev() for node in nodes]
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
             raise util.Abort(_("no graft state found, can't continue"))
@@ -3664,7 +3664,7 @@ def grep(ui, repo, pattern, *pats, **opt
         reflags |= re.I
     try:
         regexp = util.re.compile(pattern, reflags)
-    except re.error, inst:
+    except re.error as inst:
         ui.warn(_("grep: invalid match pattern: %s\n") % inst)
         return 1
     sep, eol = ':', '\n'
@@ -5083,7 +5083,7 @@ def postincoming(ui, repo, modheads, opt
         checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
         try:
             ret = hg.update(repo, checkout)
-        except util.Abort, inst:
+        except util.Abort as inst:
             ui.warn(_("not updating: %s\n") % str(inst))
             if inst.hint:
                 ui.warn(_("(%s)\n") % inst.hint)
diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -300,9 +300,9 @@ class _requesthandler(SocketServer.Strea
                 sv.serve()
             # handle exceptions that may be raised by command server. most of
             # known exceptions are caught by dispatch.
-            except util.Abort, inst:
+            except util.Abort as inst:
                 ui.warn(_('abort: %s\n') % inst)
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno != errno.EPIPE:
                     raise
             except KeyboardInterrupt:
diff --git a/mercurial/config.py b/mercurial/config.py
--- a/mercurial/config.py
+++ b/mercurial/config.py
@@ -122,7 +122,7 @@ class config(object):
                     try:
                         include(inc, remap=remap, sections=sections)
                         break
-                    except IOError, inst:
+                    except IOError as inst:
                         if inst.errno != errno.ENOENT:
                             raise error.ParseError(_("cannot include %s (%s)")
                                                    % (inc, inst.strerror),
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1438,7 +1438,7 @@ class workingctx(committablectx):
     def copy(self, source, dest):
         try:
             st = self._repo.wvfs.lstat(dest)
-        except OSError, err:
+        except OSError as err:
             if err.errno != errno.ENOENT:
                 raise
             self._repo.ui.warn(_("%s does not exist!\n") % dest)
@@ -1684,7 +1684,7 @@ class workingfilectx(committablefilectx)
         t, tz = self._changectx.date()
         try:
             return (int(self._repo.wvfs.lstat(self._path).st_mtime), tz)
-        except OSError, err:
+        except OSError as err:
             if err.errno != errno.ENOENT:
                 raise
             return (t, tz)
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -115,7 +115,7 @@ class dirstate(object):
     def _branch(self):
         try:
             return self._opener.read("branch").strip() or "default"
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
             return "default"
@@ -131,7 +131,7 @@ class dirstate(object):
                 return st[:20], st[20:40]
             elif l > 0 and l < 40:
                 raise util.Abort(_('working directory state appears damaged!'))
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
         return [nullid, nullid]
@@ -331,7 +331,7 @@ class dirstate(object):
                 st = fp.read()
             finally:
                 fp.close()
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
             return
@@ -717,7 +717,7 @@ class dirstate(object):
                     badfn(ff, badtype(kind))
                     if nf in dmap:
                         results[nf] = None
-            except OSError, inst: # nf not found on disk - it is dirstate only
+            except OSError as inst: # nf not found on disk - it is dirstate only
                 if nf in dmap: # does it exactly match a missing file?
                     results[nf] = None
                 else: # does it match a missing directory?
@@ -802,7 +802,7 @@ class dirstate(object):
                     skip = '.hg'
                 try:
                     entries = listdir(join(nd), stat=True, skip=skip)
-                except OSError, inst:
+                except OSError as inst:
                     if inst.errno in (errno.EACCES, errno.ENOENT):
                         match.bad(self.pathto(nd), inst.strerror)
                         continue
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -76,12 +76,12 @@ def dispatch(req):
             req.ui.fout = req.fout
         if req.ferr:
             req.ui.ferr = req.ferr
-    except util.Abort, inst:
+    except util.Abort as inst:
         ferr.write(_("abort: %s\n") % inst)
         if inst.hint:
             ferr.write(_("(%s)\n") % inst.hint)
         return -1
-    except error.ParseError, inst:
+    except error.ParseError as inst:
         _formatparse(ferr.write, inst)
         return -1
 
@@ -172,29 +172,29 @@ def _runcatch(req):
 
     # Global exception handling, alphabetically
     # Mercurial-specific first, followed by built-in and library exceptions
-    except error.AmbiguousCommand, inst:
+    except error.AmbiguousCommand as inst:
         ui.warn(_("hg: command '%s' is ambiguous:\n    %s\n") %
                 (inst.args[0], " ".join(inst.args[1])))
-    except error.ParseError, inst:
+    except error.ParseError as inst:
         _formatparse(ui.warn, inst)
         return -1
-    except error.LockHeld, inst:
+    except error.LockHeld as inst:
         if inst.errno == errno.ETIMEDOUT:
             reason = _('timed out waiting for lock held by %s') % inst.locker
         else:
             reason = _('lock held by %s') % inst.locker
         ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
-    except error.LockUnavailable, inst:
+    except error.LockUnavailable as inst:
         ui.warn(_("abort: could not lock %s: %s\n") %
                (inst.desc or inst.filename, inst.strerror))
-    except error.CommandError, inst:
+    except error.CommandError as inst:
         if inst.args[0]:
             ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
             commands.help_(ui, inst.args[0], full=False, command=True)
         else:
             ui.warn(_("hg: %s\n") % inst.args[1])
             commands.help_(ui, 'shortlist')
-    except error.OutOfBandError, inst:
+    except error.OutOfBandError as inst:
         if inst.args:
             msg = _("abort: remote error:\n")
         else:
@@ -204,11 +204,11 @@ def _runcatch(req):
             ui.warn(''.join(inst.args))
         if inst.hint:
             ui.warn('(%s)\n' % inst.hint)
-    except error.RepoError, inst:
+    except error.RepoError as inst:
         ui.warn(_("abort: %s!\n") % inst)
         if inst.hint:
             ui.warn(_("(%s)\n") % inst.hint)
-    except error.ResponseError, inst:
+    except error.ResponseError as inst:
         ui.warn(_("abort: %s") % inst.args[0])
         if not isinstance(inst.args[1], basestring):
             ui.warn(" %r\n" % (inst.args[1],))
@@ -216,13 +216,13 @@ def _runcatch(req):
             ui.warn(_(" empty string\n"))
         else:
             ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
-    except error.CensoredNodeError, inst:
+    except error.CensoredNodeError as inst:
         ui.warn(_("abort: file censored %s!\n") % inst)
-    except error.RevlogError, inst:
+    except error.RevlogError as inst:
         ui.warn(_("abort: %s!\n") % inst)
     except error.SignalInterrupt:
         ui.warn(_("killed!\n"))
-    except error.UnknownCommand, inst:
+    except error.UnknownCommand as inst:
         ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
         try:
             # check if the command is in a disabled extension
@@ -238,21 +238,21 @@ def _runcatch(req):
                     suggested = True
             if not suggested:
                 commands.help_(ui, 'shortlist')
-    except error.InterventionRequired, inst:
+    except error.InterventionRequired as inst:
         ui.warn("%s\n" % inst)
         return 1
-    except util.Abort, inst:
+    except util.Abort as inst:
         ui.warn(_("abort: %s\n") % inst)
         if inst.hint:
             ui.warn(_("(%s)\n") % inst.hint)
-    except ImportError, inst:
+    except ImportError as inst:
         ui.warn(_("abort: %s!\n") % inst)
         m = str(inst).split()[-1]
         if m in "mpatch bdiff".split():
             ui.warn(_("(did you forget to compile extensions?)\n"))
         elif m in "zlib".split():
             ui.warn(_("(is your Python install correct?)\n"))
-    except IOError, inst:
+    except IOError as inst:
         if util.safehasattr(inst, "code"):
             ui.warn(_("abort: %s\n") % inst)
         elif util.safehasattr(inst, "reason"):
@@ -276,7 +276,7 @@ def _runcatch(req):
                 ui.warn(_("abort: %s\n") % inst.strerror)
         else:
             raise
-    except OSError, inst:
+    except OSError as inst:
         if getattr(inst, "filename", None) is not None:
             ui.warn(_("abort: %s: '%s'\n") % (inst.strerror, inst.filename))
         else:
@@ -284,7 +284,7 @@ def _runcatch(req):
     except KeyboardInterrupt:
         try:
             ui.warn(_("interrupted!\n"))
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno == errno.EPIPE:
                 if ui.debugflag:
                     ui.warn(_("\nbroken pipe\n"))
@@ -292,11 +292,11 @@ def _runcatch(req):
                 raise
     except MemoryError:
         ui.warn(_("abort: out of memory\n"))
-    except SystemExit, inst:
+    except SystemExit as inst:
         # Commands shouldn't sys.exit directly, but give a return code.
         # Just in case catch this and and pass exit code to caller.
         return inst.code
-    except socket.error, inst:
+    except socket.error as inst:
         ui.warn(_("abort: %s\n") % inst.args[-1])
     except: # re-raises
         myver = util.version()
@@ -452,7 +452,7 @@ class cmdalias(object):
 
         try:
             args = shlex.split(self.definition)
-        except ValueError, inst:
+        except ValueError as inst:
             self.badalias = (_("error in definition for alias '%s': %s")
                              % (self.name, inst))
             return
@@ -543,7 +543,7 @@ def _parse(ui, args):
 
     try:
         args = fancyopts.fancyopts(args, commands.globalopts, options)
-    except fancyopts.getopt.GetoptError, inst:
+    except fancyopts.getopt.GetoptError as inst:
         raise error.CommandError(None, inst)
 
     if args:
@@ -566,7 +566,7 @@ def _parse(ui, args):
 
     try:
         args = fancyopts.fancyopts(args, c, cmdoptions, True)
-    except fancyopts.getopt.GetoptError, inst:
+    except fancyopts.getopt.GetoptError as inst:
         raise error.CommandError(cmd, inst)
 
     # separate global options back out
@@ -665,7 +665,7 @@ def _getlocal(ui, rpath):
     """
     try:
         wd = os.getcwd()
-    except OSError, e:
+    except OSError as e:
         raise util.Abort(_("error getting current working directory: %s") %
                          e.strerror)
     path = cmdutil.findrepo(wd) or ""
diff --git a/mercurial/encoding.py b/mercurial/encoding.py
--- a/mercurial/encoding.py
+++ b/mercurial/encoding.py
@@ -138,7 +138,7 @@ def tolocal(s):
             except UnicodeDecodeError:
                 u = s.decode("utf-8", "replace") # last ditch
                 return u.encode(encoding, "replace") # can't round-trip
-    except LookupError, k:
+    except LookupError as k:
         raise error.Abort(k, hint="please check your locale settings")
 
 def fromlocal(s):
@@ -158,10 +158,10 @@ def fromlocal(s):
 
     try:
         return s.decode(encoding, encodingmode).encode("utf-8")
-    except UnicodeDecodeError, inst:
+    except UnicodeDecodeError as inst:
         sub = s[max(0, inst.start - 10):inst.start + 10]
         raise error.Abort("decoding near '%s': %s!" % (sub, inst))
-    except LookupError, k:
+    except LookupError as k:
         raise error.Abort(k, hint="please check your locale settings")
 
 # How to treat ambiguous-width characters. Set to 'wide' to treat as wide.
@@ -330,7 +330,7 @@ def lower(s):
         return lu.encode(encoding)
     except UnicodeError:
         return s.lower() # we don't know how to fold this except in ASCII
-    except LookupError, k:
+    except LookupError as k:
         raise error.Abort(k, hint="please check your locale settings")
 
 def upper(s):
@@ -353,7 +353,7 @@ def upperfallback(s):
         return uu.encode(encoding)
     except UnicodeError:
         return s.upper() # we don't know how to fold this except in ASCII
-    except LookupError, k:
+    except LookupError as k:
         raise error.Abort(k, hint="please check your locale settings")
 
 class normcasespecs(object):
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -215,7 +215,7 @@ def push(repo, remote, force=False, revs
             localwlock = pushop.repo.wlock()
         locallock = pushop.repo.lock()
         pushop.locallocked = True
-    except IOError, err:
+    except IOError as err:
         pushop.locallocked = False
         if err.errno != errno.EACCES:
             raise
@@ -646,16 +646,16 @@ def _pushbundle2(pushop):
     try:
         try:
             reply = pushop.remote.unbundle(stream, ['force'], 'push')
-        except error.BundleValueError, exc:
+        except error.BundleValueError as exc:
             raise util.Abort('missing support for %s' % exc)
         try:
             trgetter = None
             if pushback:
                 trgetter = pushop.trmanager.transaction
             op = bundle2.processbundle(pushop.repo, reply, trgetter)
-        except error.BundleValueError, exc:
+        except error.BundleValueError as exc:
             raise util.Abort('missing support for %s' % exc)
-    except error.PushkeyFailed, exc:
+    except error.PushkeyFailed as exc:
         partid = int(exc.partid)
         if partid not in pushop.pkfailcb:
             raise
@@ -1061,7 +1061,7 @@ def _pullbundle2(pullop):
     bundle = pullop.remote.getbundle('pull', **kwargs)
     try:
         op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
-    except error.BundleValueError, exc:
+    except error.BundleValueError as exc:
         raise util.Abort('missing support for %s' % exc)
 
     if pullop.fetch:
@@ -1425,7 +1425,7 @@ def unbundle(repo, cg, heads, source, ur
                         def recordout(output):
                             r.newpart('output', data=output, mandatory=False)
                 tr.close()
-            except BaseException, exc:
+            except BaseException as exc:
                 exc.duringunbundle2 = True
                 if captureoutput and r is not None:
                     parts = exc._bundle2salvagedoutput = r.salvageoutput()
diff --git a/mercurial/extensions.py b/mercurial/extensions.py
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -53,7 +53,7 @@ def loadpath(path, module_name):
     else:
         try:
             return imp.load_source(module_name, path)
-        except IOError, exc:
+        except IOError as exc:
             if not exc.filename:
                 exc.filename = path # python does not fill this
             raise
@@ -82,7 +82,7 @@ def load(ui, name, path):
             return mod
         try:
             mod = importh("hgext.%s" % name)
-        except ImportError, err:
+        except ImportError as err:
             ui.debug('could not import hgext.%s (%s): trying %s\n'
                      % (name, err, name))
             if ui.debugflag:
@@ -105,7 +105,7 @@ def loadall(ui):
             load(ui, name, path)
         except KeyboardInterrupt:
             raise
-        except Exception, inst:
+        except Exception as inst:
             if path:
                 ui.warn(_("*** failed to import extension %s from %s: %s\n")
                         % (name, path, inst))
diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -280,7 +280,7 @@ def grep(mctx, x):
     try:
         # i18n: "grep" is a keyword
         r = re.compile(getstring(x, _("grep requires a pattern")))
-    except re.error, e:
+    except re.error as e:
         raise error.ParseError(_('invalid match pattern: %s') % e)
     return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())]
 
diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -228,7 +228,7 @@ def help_(ui, name, unknowncmd=False, fu
         try:
             aliases, entry = cmdutil.findcmd(name, commands.table,
                                              strict=unknowncmd)
-        except error.AmbiguousCommand, inst:
+        except error.AmbiguousCommand as inst:
             # py3k fix: except vars can't be used outside the scope of the
             # except block, nor can be used inside a lambda. python issue4617
             prefix = inst.args[0]
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -202,7 +202,7 @@ def share(ui, source, dest=None, update=
     requirements = ''
     try:
         requirements = srcrepo.vfs.read('requires')
-    except IOError, inst:
+    except IOError as inst:
         if inst.errno != errno.ENOENT:
             raise
 
@@ -388,7 +388,7 @@ def clone(ui, peeropts, source, dest=Non
             try:
                 destpath = hgdir
                 util.makedir(destpath, notindexed=True)
-            except OSError, inst:
+            except OSError as inst:
                 if inst.errno == errno.EEXIST:
                     cleandir = None
                     raise util.Abort(_("destination '%s' already exists")
@@ -428,7 +428,7 @@ def clone(ui, peeropts, source, dest=Non
             try:
                 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
                                 # only pass ui when no srcrepo
-            except OSError, inst:
+            except OSError as inst:
                 if inst.errno == errno.EEXIST:
                     cleandir = None
                     raise util.Abort(_("destination '%s' already exists")
diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -153,7 +153,7 @@ def staticfile(directory, fname, req):
         req.respond(HTTP_OK, ct, body=data)
     except TypeError:
         raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename')
-    except OSError, err:
+    except OSError as err:
         if err.errno == errno.ENOENT:
             raise ErrorResponse(HTTP_NOT_FOUND)
         else:
diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -190,7 +190,7 @@ class hgweb(object):
                 if cmd in perms:
                     self.check_perm(req, perms[cmd])
                 return protocol.call(self.repo, req, cmd)
-            except ErrorResponse, inst:
+            except ErrorResponse as inst:
                 # A client that sends unbundle without 100-continue will
                 # break if we respond early.
                 if (cmd == 'unbundle' and
@@ -269,17 +269,17 @@ class hgweb(object):
 
             return content
 
-        except (error.LookupError, error.RepoLookupError), err:
+        except (error.LookupError, error.RepoLookupError) as err:
             req.respond(HTTP_NOT_FOUND, ctype)
             msg = str(err)
             if (util.safehasattr(err, 'name') and
                 not isinstance(err,  error.ManifestLookupError)):
                 msg = 'revision not found: %s' % err.name
             return tmpl('error', error=msg)
-        except (error.RepoError, error.RevlogError), inst:
+        except (error.RepoError, error.RevlogError) as inst:
             req.respond(HTTP_SERVER_ERROR, ctype)
             return tmpl('error', error=str(inst))
-        except ErrorResponse, inst:
+        except ErrorResponse as inst:
             req.respond(inst, ctype)
             if inst.code == HTTP_NOT_MODIFIED:
                 # Not allowed to return a body on a 304
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -219,10 +219,10 @@ class hgwebdir(object):
                         # ensure caller gets private copy of ui
                         repo = hg.repository(self.ui.copy(), real)
                         return hgweb(repo).run_wsgi(req)
-                    except IOError, inst:
+                    except IOError as inst:
                         msg = inst.strerror
                         raise ErrorResponse(HTTP_SERVER_ERROR, msg)
-                    except error.RepoError, inst:
+                    except error.RepoError as inst:
                         raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
 
                 up = virtualrepo.rfind('/')
@@ -240,7 +240,7 @@ class hgwebdir(object):
             req.respond(HTTP_NOT_FOUND, ctype)
             return tmpl("notfound", repo=virtual)
 
-        except ErrorResponse, err:
+        except ErrorResponse as err:
             req.respond(err, ctype)
             return tmpl('error', error=err.message or '')
         finally:
@@ -336,7 +336,7 @@ class hgwebdir(object):
                 u = self.ui.copy()
                 try:
                     u.readconfig(os.path.join(path, '.hg', 'hgrc'))
-                except Exception, e:
+                except Exception as e:
                     u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
                     continue
                 def get(section, name, default=None):
diff --git a/mercurial/hgweb/request.py b/mercurial/hgweb/request.py
--- a/mercurial/hgweb/request.py
+++ b/mercurial/hgweb/request.py
@@ -111,7 +111,7 @@ class wsgirequest(object):
         if thing:
             try:
                 self.server_write(thing)
-            except socket.error, inst:
+            except socket.error as inst:
                 if inst[0] != errno.ECONNRESET:
                     raise
 
diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py
--- a/mercurial/hgweb/server.py
+++ b/mercurial/hgweb/server.py
@@ -71,7 +71,7 @@ class _httprequesthandler(BaseHTTPServer
     def do_write(self):
         try:
             self.do_hgweb()
-        except socket.error, inst:
+        except socket.error as inst:
             if inst[0] != errno.EPIPE:
                 raise
 
@@ -226,7 +226,7 @@ class _httprequesthandleropenssl(_httpre
         import OpenSSL
         try:
             _httprequesthandler.do_write(self)
-        except OpenSSL.SSL.SysCallError, inst:
+        except OpenSSL.SSL.SysCallError as inst:
             if inst.args[0] != errno.EPIPE:
                 raise
 
@@ -344,6 +344,6 @@ def create_server(ui, app):
     port = util.getport(ui.config('web', 'port', 8000))
     try:
         return cls(ui, app, (address, port), handler)
-    except socket.error, inst:
+    except socket.error as inst:
         raise util.Abort(_("cannot start server at '%s:%d': %s")
                          % (address, port, inst.args[1]))
diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -76,7 +76,7 @@ def rawfile(web, req, tmpl):
 
     try:
         fctx = webutil.filectx(web.repo, req)
-    except error.LookupError, inst:
+    except error.LookupError as inst:
         try:
             content = manifest(web, req, tmpl)
             req.respond(HTTP_OK, web.ctype)
@@ -160,7 +160,7 @@ def file(web, req, tmpl):
         return manifest(web, req, tmpl)
     try:
         return _filerevision(web, req, tmpl, webutil.filectx(web.repo, req))
-    except error.LookupError, inst:
+    except error.LookupError as inst:
         try:
             return manifest(web, req, tmpl)
         except ErrorResponse:
diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -80,7 +80,7 @@ def _pythonhook(ui, repo, name, hname, f
         sys.stdout, sys.stderr, sys.stdin = ui.fout, ui.ferr, ui.fin
 
         r = obj(ui=ui, repo=repo, hooktype=name, **args)
-    except Exception, exc:
+    except Exception as exc:
         if isinstance(exc, util.Abort):
             ui.warn(_('error: %s hook failed: %s\n') %
                          (hname, exc.args[0]))
diff --git a/mercurial/httpclient/__init__.py b/mercurial/httpclient/__init__.py
--- a/mercurial/httpclient/__init__.py
+++ b/mercurial/httpclient/__init__.py
@@ -166,7 +166,7 @@ class HTTPResponse(object):
                 raise HTTPTimeoutException('timeout reading data')
         try:
             data = self.sock.recv(INCOMING_BUFFER_SIZE)
-        except socket.sslerror, e:
+        except socket.sslerror as e:
             if e.args[0] != socket.SSL_ERROR_WANT_READ:
                 raise
             logger.debug('SSL_ERROR_WANT_READ in _select, should retry later')
@@ -555,7 +555,7 @@ class HTTPConnection(object):
                 try:
                     try:
                         data = r[0].recv(INCOMING_BUFFER_SIZE)
-                    except socket.sslerror, e:
+                    except socket.sslerror as e:
                         if e.args[0] != socket.SSL_ERROR_WANT_READ:
                             raise
                         logger.debug('SSL_ERROR_WANT_READ while sending '
@@ -610,7 +610,7 @@ class HTTPConnection(object):
                     # Jump to the next select() call so we load more
                     # data if the server is still sending us content.
                     continue
-                except socket.error, e:
+                except socket.error as e:
                     if e[0] != errno.EPIPE and not was_first:
                         raise
 
@@ -633,7 +633,7 @@ class HTTPConnection(object):
                         else:
                             out = data
                     amt = w[0].send(out)
-                except socket.error, e:
+                except socket.error as e:
                     if e[0] == socket.SSL_ERROR_WANT_WRITE and self.ssl:
                         # This means that SSL hasn't flushed its buffer into
                         # the socket yet.
diff --git a/mercurial/httpclient/socketutil.py b/mercurial/httpclient/socketutil.py
--- a/mercurial/httpclient/socketutil.py
+++ b/mercurial/httpclient/socketutil.py
@@ -64,7 +64,7 @@ except AttributeError:
                 sock = socket.socket(af, socktype, proto)
                 logger.info("connect: (%s, %s)", host, port)
                 sock.connect(sa)
-            except socket.error, msg:
+            except socket.error as msg:
                 logger.info('connect fail: %s %s', host, port)
                 if sock:
                     sock.close()
@@ -100,7 +100,7 @@ else:
             while True:
                 try:
                     return self._ssl.read(buflen)
-                except socket.sslerror, x:
+                except socket.sslerror as x:
                     if x.args[0] == socket.SSL_ERROR_WANT_READ:
                         continue
                     else:
diff --git a/mercurial/httpconnection.py b/mercurial/httpconnection.py
--- a/mercurial/httpconnection.py
+++ b/mercurial/httpconnection.py
@@ -211,7 +211,7 @@ class http2handler(urllib2.HTTPHandler, 
                 path = '/' + path
             h.request(req.get_method(), path, req.data, headers)
             r = h.getresponse()
-        except socket.error, err: # XXX what error?
+        except socket.error as err: # XXX what error?
             raise urllib2.URLError(err)
 
         # Pick apart the HTTPResponse object to get the addinfourl
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -119,11 +119,11 @@ class httppeer(wireproto.wirepeer):
             req.add_unredirected_header('Content-Length', '%d' % size)
         try:
             resp = self.urlopener.open(req)
-        except urllib2.HTTPError, inst:
+        except urllib2.HTTPError as inst:
             if inst.code == 401:
                 raise util.Abort(_('authorization failed'))
             raise
-        except httplib.HTTPException, inst:
+        except httplib.HTTPException as inst:
             self.ui.debug('http error while sending %s command\n' % cmd)
             self.ui.traceback()
             raise IOError(None, inst)
@@ -205,7 +205,7 @@ class httppeer(wireproto.wirepeer):
             if len(vals) < 2:
                 raise error.ResponseError(_("unexpected response:"), r)
             return vals
-        except socket.error, err:
+        except socket.error as err:
             if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
                 raise util.Abort(_('push failed: %s') % err.args[1])
             raise util.Abort(err.args[1])
@@ -267,7 +267,7 @@ def instance(ui, path, create):
             # No luck, try older compatibility check.
             inst.between([(nullid, nullid)])
         return inst
-    except error.RepoError, httpexception:
+    except error.RepoError as httpexception:
         try:
             r = statichttprepo.instance(ui, "static-" + path, create)
             ui.note('(falling back to static-http)\n')
diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py
--- a/mercurial/keepalive.py
+++ b/mercurial/keepalive.py
@@ -251,7 +251,7 @@ class KeepAliveHandler(object):
                 self._cm.add(host, h, 0)
                 self._start_transaction(h, req)
                 r = h.getresponse()
-        except (socket.error, httplib.HTTPException), err:
+        except (socket.error, httplib.HTTPException) as err:
             raise urllib2.URLError(err)
 
         # if not a persistent connection, don't try to reuse it
@@ -343,7 +343,7 @@ class KeepAliveHandler(object):
                     h.putheader('Content-length', '%d' % len(data))
             else:
                 h.putrequest('GET', req.get_selector(), **skipheaders)
-        except (socket.error), err:
+        except (socket.error) as err:
             raise urllib2.URLError(err)
         for k, v in headers.items():
             h.putheader(k, v)
@@ -550,7 +550,7 @@ def safesend(self, str):
                 data = read(blocksize)
         else:
             self.sock.sendall(str)
-    except socket.error, v:
+    except socket.error as v:
         reraise = True
         if v[0] == errno.EPIPE:      # Broken pipe
             if self._HTTPConnection__state == httplib._CS_REQ_SENT:
@@ -605,7 +605,7 @@ def error_handler(url):
                 status, reason = fo.status, fo.reason
             except AttributeError:
                 status, reason = None, None
-        except IOError, e:
+        except IOError as e:
             print "  EXCEPTION: %s" % e
             raise
         else:
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -135,7 +135,7 @@ class localpeer(peer.peerrepository):
                     stream = util.chunkbuffer(ret.getchunks())
                     ret = bundle2.getunbundler(self.ui, stream)
                 return ret
-            except Exception, exc:
+            except Exception as exc:
                 # If the exception contains output salvaged from a bundle2
                 # reply, we need to make sure it is printed before continuing
                 # to fail. So we build a bundle2 with such output and consume
@@ -152,7 +152,7 @@ class localpeer(peer.peerrepository):
                     b = bundle2.getunbundler(self.ui, stream)
                     bundle2.processbundle(self._repo, b)
                 raise
-        except error.PushRaced, exc:
+        except error.PushRaced as exc:
             raise error.ResponseError(_('push failed:'), str(exc))
 
     def lock(self):
@@ -272,7 +272,7 @@ class localrepository(object):
             try:
                 self.requirements = scmutil.readrequires(
                         self.vfs, self.supported)
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno != errno.ENOENT:
                     raise
 
@@ -285,7 +285,7 @@ class localrepository(object):
                 raise error.RepoError(
                     _('.hg/sharedpath points to nonexistent directory %s') % s)
             self.sharedpath = s
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
 
@@ -578,7 +578,7 @@ class localrepository(object):
 
         try:
             fp = self.wfile('.hgtags', 'rb+')
-        except IOError, e:
+        except IOError as e:
             if e.errno != errno.ENOENT:
                 raise
             fp = self.wfile('.hgtags', 'ab')
@@ -1189,7 +1189,7 @@ class localrepository(object):
     def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc):
         try:
             l = lockmod.lock(vfs, lockname, 0, releasefn, desc=desc)
-        except error.LockHeld, inst:
+        except error.LockHeld as inst:
             if not wait:
                 raise
             self.ui.warn(_("waiting for lock on %s held by %r\n") %
@@ -1570,10 +1570,10 @@ class localrepository(object):
                             m[f] = self._filecommit(fctx, m1, m2, linkrev,
                                                     trp, changed)
                             m.setflag(f, fctx.flags())
-                    except OSError, inst:
+                    except OSError as inst:
                         self.ui.warn(_("trouble committing %s!\n") % f)
                         raise
-                    except IOError, inst:
+                    except IOError as inst:
                         errcode = getattr(inst, 'errno', errno.ENOENT)
                         if error or errcode and errcode != errno.ENOENT:
                             self.ui.warn(_("trouble committing %s!\n") % f)
@@ -1888,7 +1888,7 @@ class localrepository(object):
             hookargs['old'] = old
             hookargs['new'] = new
             self.hook('prepushkey', throw=True, **hookargs)
-        except error.HookAbort, exc:
+        except error.HookAbort as exc:
             self.ui.write_err(_("pushkey-abort: %s\n") % exc)
             if exc.hint:
                 self.ui.write_err(_("(%s)\n") % exc.hint)
diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -58,7 +58,7 @@ class lock(object):
             try:
                 self.trylock()
                 return self.timeout - timeout
-            except error.LockHeld, inst:
+            except error.LockHeld as inst:
                 if timeout != 0:
                     time.sleep(1)
                     if timeout > 0:
@@ -78,7 +78,7 @@ class lock(object):
             try:
                 self.vfs.makelock(lockname, self.f)
                 self.held = 1
-            except (OSError, IOError), why:
+            except (OSError, IOError) as why:
                 if why.errno == errno.EEXIST:
                     locker = self.testlock()
                     if locker is not None:
@@ -102,7 +102,7 @@ class lock(object):
         """
         try:
             locker = self.vfs.readlock(self.f)
-        except (OSError, IOError), why:
+        except (OSError, IOError) as why:
             if why.errno == errno.ENOENT:
                 return None
             raise
diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -138,16 +138,16 @@ def _smtp(ui):
                   (username))
         try:
             s.login(username, password)
-        except smtplib.SMTPException, inst:
+        except smtplib.SMTPException as inst:
             raise util.Abort(inst)
 
     def send(sender, recipients, msg):
         try:
             return s.sendmail(sender, recipients, msg)
-        except smtplib.SMTPRecipientsRefused, inst:
+        except smtplib.SMTPRecipientsRefused as inst:
             recipients = [r[1] for r in inst.recipients.values()]
             raise util.Abort('\n' + '\n'.join(recipients))
-        except smtplib.SMTPException, inst:
+        except smtplib.SMTPException as inst:
             raise util.Abort(inst)
 
     return send
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -293,9 +293,9 @@ class match(object):
                     for k, p, source in self._normalize(includepats, default,
                                                         root, cwd, auditor):
                         kindpats.append((k, p, source or pat))
-                except util.Abort, inst:
+                except util.Abort as inst:
                     raise util.Abort('%s: %s' % (pat, inst[0]))
-                except IOError, inst:
+                except IOError as inst:
                     if self._warn:
                         self._warn(_("skipping unreadable pattern file "
                                      "'%s': %s\n") % (pat, inst.strerror))
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -145,7 +145,7 @@ class mergestate(object):
                 else:
                     records.append(('F', l[:-1]))
             f.close()
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
         return records
@@ -170,7 +170,7 @@ class mergestate(object):
                 off += length
                 records.append((rtype, record))
             f.close()
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
         return records
@@ -660,7 +660,7 @@ def batchremove(repo, actions):
         audit(f)
         try:
             unlink(wjoin(f), ignoremissing=True)
-        except OSError, inst:
+        except OSError as inst:
             repo.ui.warn(_("update failed to remove %s: %s!\n") %
                          (f, inst.strerror))
         if i == 100:
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -431,12 +431,12 @@ class fsbackend(abstractbackend):
         isexec = False
         try:
             isexec = self.opener.lstat(fname).st_mode & 0o100 != 0
-        except OSError, e:
+        except OSError as e:
             if e.errno != errno.ENOENT:
                 raise
         try:
             return (self.opener.read(fname), (False, isexec))
-        except IOError, e:
+        except IOError as e:
             if e.errno != errno.ENOENT:
                 raise
             return None, None
@@ -1363,7 +1363,7 @@ class binhunk(object):
                 l = ord(l) - ord('a') + 27
             try:
                 dec.append(base85.b85decode(line[1:])[:l])
-            except ValueError, e:
+            except ValueError as e:
                 raise PatchError(_('could not decode "%s" binary patch: %s')
                                  % (self._fname, str(e)))
             line = getline(lr, self.hunk)
@@ -1938,7 +1938,7 @@ def _applydiff(ui, fp, patcher, backend,
             try:
                 current_file = patcher(ui, gp, backend, store,
                                        eolmode=eolmode)
-            except PatchError, inst:
+            except PatchError as inst:
                 ui.warn(str(inst) + '\n')
                 current_file = None
                 rejects += 1
diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py
--- a/mercurial/pathutil.py
+++ b/mercurial/pathutil.py
@@ -76,7 +76,7 @@ class pathauditor(object):
             curpath = os.path.join(self.root, prefix)
             try:
                 st = os.lstat(curpath)
-            except OSError, err:
+            except OSError as err:
                 # EINVAL can be raised as invalid path syntax under win32.
                 # They must be ignored for patterns can be checked too.
                 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -129,7 +129,7 @@ def _readroots(repo, phasedefaults=None)
         if 'HG_PENDING' in os.environ:
             try:
                 f = repo.svfs('phaseroots.pending')
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno != errno.ENOENT:
                     raise
         if f is None:
@@ -140,7 +140,7 @@ def _readroots(repo, phasedefaults=None)
                 roots[int(phase)].add(bin(nh))
         finally:
             f.close()
-    except IOError, inst:
+    except IOError as inst:
         if inst.errno != errno.ENOENT:
             raise
         if phasedefaults:
diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -115,7 +115,7 @@ def copymode(src, dst, mode=None):
     using umask.'''
     try:
         st_mode = os.lstat(src).st_mode & 0o777
-    except OSError, inst:
+    except OSError as inst:
         if inst.errno != errno.ENOENT:
             raise
         st_mode = mode
@@ -166,7 +166,7 @@ def checklink(path):
             fd.close()
     except AttributeError:
         return False
-    except OSError, inst:
+    except OSError as inst:
         # sshfs might report failure while successfully creating the link
         if inst[0] == errno.EIO and os.path.exists(name):
             os.unlink(name)
@@ -355,7 +355,7 @@ def testpid(pid):
     try:
         os.kill(pid, 0)
         return True
-    except OSError, inst:
+    except OSError as inst:
         return inst.errno != errno.ESRCH
 
 def explainexit(code):
@@ -410,7 +410,7 @@ def statfiles(files):
             st = lstat(nf)
             if getkind(st.st_mode) not in _wantedkinds:
                 st = None
-        except OSError, err:
+        except OSError as err:
             if err.errno not in (errno.ENOENT, errno.ENOTDIR):
                 raise
             st = None
@@ -477,7 +477,7 @@ def termwidth():
                     pass
             except ValueError:
                 pass
-            except IOError, e:
+            except IOError as e:
                 if e[0] == errno.EINVAL:
                     pass
                 else:
@@ -493,7 +493,7 @@ def unlinkpath(f, ignoremissing=False):
     """unlink and remove the directory if it is empty"""
     try:
         os.unlink(f)
-    except OSError, e:
+    except OSError as e:
         if not (ignoremissing and e.errno == errno.ENOENT):
             raise
     # try removing directories that might now be empty
@@ -560,7 +560,7 @@ class unixdomainserver(socket.socket):
                 os.unlink(self.path)
         try:
             self.bind(self.realpath)
-        except socket.error, err:
+        except socket.error as err:
             if err.args[0] == 'AF_UNIX path too long':
                 tmpdir = tempfile.mkdtemp(prefix='hg-%s-' % subsystem)
                 self.realpath = os.path.join(tmpdir, sockname)
@@ -578,7 +578,7 @@ class unixdomainserver(socket.socket):
         def okayifmissing(f, path):
             try:
                 f(path)
-            except OSError, err:
+            except OSError as err:
                 if err.errno != errno.ENOENT:
                     raise
 
diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -205,7 +205,7 @@ def strip(ui, repo, nodelist, backup=Tru
         for undovfs, undofile in repo.undofiles():
             try:
                 undovfs.unlink(undofile)
-            except OSError, e:
+            except OSError as e:
                 if e.errno != errno.ENOENT:
                     ui.warn(_('error removing %s: %s\n') %
                             (undovfs.join(undofile), str(e)))
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -89,7 +89,7 @@ def decompress(bin):
     if t == 'x':
         try:
             return _decompress(bin)
-        except zlib.error, e:
+        except zlib.error as e:
             raise RevlogError(_("revlog decompress error: %s") % str(e))
     if t == 'u':
         return bin[1:]
@@ -246,7 +246,7 @@ class revlog(object):
             if len(i) > 0:
                 v = struct.unpack(versionformat, i[:4])[0]
                 self._initempty = False
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
 
@@ -1571,7 +1571,7 @@ class revlog(object):
             actual = f.tell()
             f.close()
             dd = actual - expected
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
             dd = 0
@@ -1590,7 +1590,7 @@ class revlog(object):
                     databytes += max(0, self.length(r))
                 dd = 0
                 di = actual - len(self) * s - databytes
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
             di = 0
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1019,7 +1019,7 @@ def grep(repo, subset, x):
     try:
         # i18n: "grep" is a keyword
         gr = re.compile(getstring(x, _("grep requires a string")))
-    except re.error, e:
+    except re.error as e:
         raise error.ParseError(_('invalid match pattern: %s') % e)
 
     def matches(x):
@@ -1900,7 +1900,7 @@ def _stringmatcher(pattern):
         pattern = pattern[3:]
         try:
             regex = re.compile(pattern)
-        except re.error, e:
+        except re.error as e:
             raise error.ParseError(_('invalid regular expression: %s')
                                    % e)
         return 're', pattern, regex.search
@@ -2416,7 +2416,7 @@ def _parsealiasdecl(decl):
             return (name, ('func', ('symbol', name)), args, None)
 
         return (decl, None, None, _("invalid format"))
-    except error.ParseError, inst:
+    except error.ParseError as inst:
         return (decl, None, None, parseerrordetail(inst))
 
 def _parsealiasdefn(defn, args):
@@ -2505,7 +2505,7 @@ class revsetalias(object):
             self.replacement = _parsealiasdefn(value, self.args)
             # Check for placeholder injection
             _checkaliasarg(self.replacement, self.args)
-        except error.ParseError, inst:
+        except error.ParseError as inst:
             self.error = _('failed to parse the definition of revset alias'
                            ' "%s": %s') % (self.name, parseerrordetail(inst))
 
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -222,7 +222,7 @@ class abstractvfs(object):
         '''gracefully return an empty string for missing files'''
         try:
             return self.read(path)
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
         return ""
@@ -231,7 +231,7 @@ class abstractvfs(object):
         '''gracefully return an empty array for missing files'''
         try:
             return self.readlines(path, mode=mode)
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
         return []
@@ -491,7 +491,7 @@ class vfs(abstractvfs):
                         if nlink < 1:
                             nlink = 2 # force mktempcopy (issue1922)
                         fd.close()
-                except (OSError, IOError), e:
+                except (OSError, IOError) as e:
                     if e.errno != errno.ENOENT:
                         raise
                     nlink = 0
@@ -519,7 +519,7 @@ class vfs(abstractvfs):
         if self._cansymlink:
             try:
                 os.symlink(src, linkname)
-            except OSError, err:
+            except OSError as err:
                 raise OSError(err.errno, _('could not symlink to %r: %s') %
                               (src, err.strerror), linkname)
         else:
@@ -1058,7 +1058,7 @@ class filecachesubentry(object):
     def stat(path):
         try:
             return util.cachestat(path)
-        except OSError, e:
+        except OSError as e:
             if e.errno != errno.ENOENT:
                 raise
 
diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
--- a/mercurial/statichttprepo.py
+++ b/mercurial/statichttprepo.py
@@ -33,10 +33,10 @@ class httprangereader(object):
             f = self.opener.open(req)
             data = f.read()
             code = f.code
-        except urllib2.HTTPError, inst:
+        except urllib2.HTTPError as inst:
             num = inst.code == 404 and errno.ENOENT or None
             raise IOError(num, inst)
-        except urllib2.URLError, inst:
+        except urllib2.URLError as inst:
             raise IOError(None, inst.reason[1])
 
         if code == 200:
@@ -106,7 +106,7 @@ class statichttprepository(localrepo.loc
 
         try:
             requirements = scmutil.readrequires(self.vfs, self.supported)
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
             requirements = set()
@@ -116,7 +116,7 @@ class statichttprepository(localrepo.loc
                 fp = self.vfs("00changelog.i")
                 fp.read(1)
                 fp.close()
-            except IOError, inst:
+            except IOError as inst:
                 if inst.errno != errno.ENOENT:
                     raise
                 # we do not care about empty old-style repositories here
diff --git a/mercurial/store.py b/mercurial/store.py
--- a/mercurial/store.py
+++ b/mercurial/store.py
@@ -489,7 +489,7 @@ class fncachestore(basicstore):
             ef = self.encode(f)
             try:
                 yield f, ef, self.getsize(ef)
-            except OSError, err:
+            except OSError as err:
                 if err.errno != errno.ENOENT:
                     raise
 
@@ -513,7 +513,7 @@ class fncachestore(basicstore):
         try:
             self.getsize(ef)
             return True
-        except OSError, err:
+        except OSError as err:
             if err.errno != errno.ENOENT:
                 raise
             # nonexistent entry
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -44,10 +44,10 @@ def annotatesubrepoerror(func):
     def decoratedmethod(self, *args, **kargs):
         try:
             res = func(self, *args, **kargs)
-        except SubrepoAbort, ex:
+        except SubrepoAbort as ex:
             # This exception has already been handled
             raise ex
-        except error.Abort, ex:
+        except error.Abort as ex:
             subrepo = subrelpath(self)
             errormsg = str(ex) + ' ' + _('(in subrepo %s)') % subrepo
             # avoid handling this exception by raising a SubrepoAbort exception
@@ -66,7 +66,7 @@ def state(ctx, ui):
         if f in ctx:
             try:
                 data = ctx[f].data()
-            except IOError, err:
+            except IOError as err:
                 if err.errno != errno.ENOENT:
                     raise
                 # handle missing subrepo spec files as removed
@@ -101,7 +101,7 @@ def state(ctx, ui):
                                      % (util.pathto(repo.root, repo.getcwd(),
                                         '.hgsubstate'), (i + 1)))
                 rev[path] = revision
-        except IOError, err:
+        except IOError as err:
             if err.errno != errno.ENOENT:
                 raise
 
@@ -116,7 +116,7 @@ def state(ctx, ui):
             repl = re.sub(r'\\\\([0-9]+)', r'\\\1', repl)
             try:
                 src = re.sub(pattern, repl, src, 1)
-            except re.error, e:
+            except re.error as e:
                 raise util.Abort(_("bad subrepository pattern in %s: %s")
                                  % (p.source('subpaths', pattern), e))
         return src
@@ -734,7 +734,7 @@ class hgsubrepo(abstractsubrepo):
             ctx1 = self._repo[rev1]
             ctx2 = self._repo[rev2]
             return self._repo.status(ctx1, ctx2, **opts)
-        except error.RepoLookupError, inst:
+        except error.RepoLookupError as inst:
             self.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
                          % (inst, subrelpath(self)))
             return scmutil.status([], [], [], [], [], [], [])
@@ -751,7 +751,7 @@ class hgsubrepo(abstractsubrepo):
                                    node1, node2, match,
                                    prefix=posixpath.join(prefix, self._path),
                                    listsubrepos=True, **opts)
-        except error.RepoLookupError, inst:
+        except error.RepoLookupError as inst:
             self.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
                           % (inst, subrelpath(self)))
 
@@ -1280,7 +1280,7 @@ class gitsubrepo(abstractsubrepo):
         try:
             self._gitexecutable = 'git'
             out, err = self._gitnodir(['--version'])
-        except OSError, e:
+        except OSError as e:
             if e.errno != 2 or os.name != 'nt':
                 raise
             self._gitexecutable = 'git.cmd'
diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -120,7 +120,7 @@ def readlocaltags(ui, repo, alltags, tag
     '''Read local tags in repo. Update alltags and tagtypes.'''
     try:
         data = repo.vfs.read("localtags")
-    except IOError, inst:
+    except IOError as inst:
         if inst.errno != errno.ENOENT:
             raise
         return
@@ -545,7 +545,7 @@ class hgtagsfnodescache(object):
                 self._dirtyoffset = None
             finally:
                 f.close()
-        except (IOError, OSError), inst:
+        except (IOError, OSError) as inst:
             repo.ui.log('tagscache',
                         "couldn't write %s: %s\n" % (
                         _fnodescachefile, inst))
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -770,7 +770,7 @@ class templater(object):
             if val[0] in "'\"":
                 try:
                     self.cache[key] = unquotestring(val)
-                except SyntaxError, inst:
+                except SyntaxError as inst:
                     raise SyntaxError('%s: %s' %
                                       (conf.source('', key), inst.args[0]))
             else:
@@ -787,10 +787,10 @@ class templater(object):
         if t not in self.cache:
             try:
                 self.cache[t] = util.readfile(self.map[t][1])
-            except KeyError, inst:
+            except KeyError as inst:
                 raise TemplateNotFound(_('"%s" not in template map') %
                                        inst.args[0])
-            except IOError, inst:
+            except IOError as inst:
                 raise IOError(inst.args[0], _('template file %s: %s') %
                               (self.map[t][1], inst.args[1]))
         return self.cache[t]
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -39,7 +39,7 @@ def _playback(journal, report, opener, v
         else:
             try:
                 opener.unlink(f)
-            except (IOError, OSError), inst:
+            except (IOError, OSError) as inst:
                 if inst.errno != errno.ENOENT:
                     raise
 
@@ -62,10 +62,10 @@ def _playback(journal, report, opener, v
                 target = f or b
                 try:
                     vfs.unlink(target)
-                except (IOError, OSError), inst:
+                except (IOError, OSError) as inst:
                     if inst.errno != errno.ENOENT:
                         raise
-        except (IOError, OSError, util.Abort), inst:
+        except (IOError, OSError, util.Abort) as inst:
             if not c:
                 raise
 
@@ -77,7 +77,7 @@ def _playback(journal, report, opener, v
         for f in backupfiles:
             if opener.exists(f):
                 opener.unlink(f)
-    except (IOError, OSError, util.Abort), inst:
+    except (IOError, OSError, util.Abort) as inst:
         # only pure backup file remains, it is sage to ignore any error
         pass
 
@@ -405,7 +405,7 @@ class transaction(object):
             if not f and b and vfs.exists(b):
                 try:
                     vfs.unlink(b)
-                except (IOError, OSError, util.Abort), inst:
+                except (IOError, OSError, util.Abort) as inst:
                     if not c:
                         raise
                     # Abort may be raise by read only opener
@@ -428,7 +428,7 @@ class transaction(object):
                 if b and vfs.exists(b):
                     try:
                         vfs.unlink(b)
-                    except (IOError, OSError, util.Abort), inst:
+                    except (IOError, OSError, util.Abort) as inst:
                         if not c:
                             raise
                         # Abort may be raise by read only opener
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -153,7 +153,7 @@ class ui(object):
         try:
             cfg.read(filename, fp, sections=sections, remap=remap)
             fp.close()
-        except error.ConfigError, inst:
+        except error.ConfigError as inst:
             if trusted:
                 raise
             self.warn(_("ignored: %s\n") % str(inst))
@@ -605,7 +605,7 @@ class ui(object):
             # including stdout.
             if not getattr(self.ferr, 'closed', False):
                 self.ferr.flush()
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
                 raise
 
diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -159,7 +159,7 @@ if has_https:
                     sock.connect(sa)
                     return sock
 
-                except socket.error, msg:
+                except socket.error as msg:
                     if sock is not None:
                         sock.close()
 
@@ -411,7 +411,7 @@ class httpdigestauthhandler(urllib2.HTTP
         try:
             return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
                         self, auth_header, host, req, headers)
-        except ValueError, inst:
+        except ValueError as inst:
             arg = inst.args[0]
             if arg.startswith("AbstractDigestAuthHandler doesn't know "):
                 return
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -816,7 +816,7 @@ def copyfile(src, dest, hardlink=False):
         try:
             shutil.copyfile(src, dest)
             shutil.copymode(src, dest)
-        except shutil.Error, inst:
+        except shutil.Error as inst:
             raise Abort(str(inst))
 
 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None):
@@ -915,7 +915,7 @@ else:
 def makelock(info, pathname):
     try:
         return os.symlink(info, pathname)
-    except OSError, why:
+    except OSError as why:
         if why.errno == errno.EEXIST:
             raise
     except AttributeError: # no symlink in os
@@ -928,7 +928,7 @@ def makelock(info, pathname):
 def readlock(pathname):
     try:
         return os.readlink(pathname)
-    except OSError, why:
+    except OSError as why:
         if why.errno not in (errno.EINVAL, errno.ENOSYS):
             raise
     except AttributeError: # no symlink in os
@@ -1145,7 +1145,7 @@ def mktempcopy(name, emptyok=False, crea
     try:
         try:
             ifp = posixfile(name, "rb")
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno == errno.ENOENT:
                 return temp
             if not getattr(inst, 'filename', None):
@@ -1204,7 +1204,7 @@ def makedirs(name, mode=None, notindexed
     """recursive directory creation with parent mode inheritance"""
     try:
         makedir(name, notindexed)
-    except OSError, err:
+    except OSError as err:
         if err.errno == errno.EEXIST:
             return
         if err.errno != errno.ENOENT or not name:
@@ -1231,7 +1231,7 @@ def ensuredirs(name, mode=None, notindex
         ensuredirs(parent, mode, notindexed)
     try:
         makedir(name, notindexed)
-    except OSError, err:
+    except OSError as err:
         if err.errno == errno.EEXIST and os.path.isdir(name):
             # someone else seems to have won a directory creation race
             return
diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -108,7 +108,7 @@ def _verify(repo):
             if p2 not in seen and p2 != nullid:
                 err(lr, _("unknown parent 2 %s of %s") %
                     (short(p2), short(node)), f)
-        except Exception, inst:
+        except Exception as inst:
             exc(lr, _("checking parents of %s") % short(node), inst, f)
 
         if node in seen:
@@ -144,7 +144,7 @@ def _verify(repo):
                 refersmf = True
             for f in changes[3]:
                 filelinkrevs.setdefault(_normpath(f), []).append(i)
-        except Exception, inst:
+        except Exception as inst:
             refersmf = True
             exc(i, _("unpacking changeset %s") % short(n), inst)
     ui.progress(_('checking'), None)
@@ -171,7 +171,7 @@ def _verify(repo):
                     err(lr, _("file without name in manifest"))
                 elif f != "/dev/null": # ignore this in very old repos
                     filenodes.setdefault(_normpath(f), {}).setdefault(fn, lr)
-        except Exception, inst:
+        except Exception as inst:
             exc(lr, _("reading manifest delta %s") % short(n), inst)
     ui.progress(_('checking'), None)
 
@@ -237,7 +237,7 @@ def _verify(repo):
 
         try:
             fl = repo.file(f)
-        except error.RevlogError, e:
+        except error.RevlogError as e:
             err(lr, _("broken revlog! (%s)") % e, f)
             continue
 
@@ -272,7 +272,7 @@ def _verify(repo):
             except error.CensoredNodeError:
                 if ui.config("censor", "policy", "abort") == "abort":
                     err(lr, _("censored file data"), f)
-            except Exception, inst:
+            except Exception as inst:
                 exc(lr, _("unpacking %s") % short(n), inst, f)
 
             # check renames
@@ -298,7 +298,7 @@ def _verify(repo):
                             % (f, lr, rp[0], short(rp[1])))
                     else:
                         fl2.rev(rp[1])
-            except Exception, inst:
+            except Exception as inst:
                 exc(lr, _("checking rename of %s") % short(n), inst, f)
 
         # cross-check
diff --git a/mercurial/win32.py b/mercurial/win32.py
--- a/mercurial/win32.py
+++ b/mercurial/win32.py
@@ -467,7 +467,7 @@ def unlink(f):
         try:
             os.rename(f, temp)  # raises OSError EEXIST if temp exists
             break
-        except OSError, e:
+        except OSError as e:
             if e.errno != errno.EEXIST:
                 raise
     else:
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -38,7 +38,7 @@ def posixfile(name, mode='r', buffering=
             fp.seek(0, os.SEEK_END)
 
         return fp
-    except WindowsError, err:
+    except WindowsError as err:
         # convert to a friendlier exception
         raise IOError(err.errno, '%s: %s' % (name, err.strerror))
 
@@ -69,7 +69,7 @@ class winstdout(object):
                 end = start + limit
                 self.fp.write(s[start:end])
                 start = end
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != 0:
                 raise
             self.close()
@@ -78,7 +78,7 @@ class winstdout(object):
     def flush(self):
         try:
             return self.fp.flush()
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno != errno.EINVAL:
                 raise
             self.close()
@@ -259,7 +259,7 @@ def statfiles(files):
                 dmap = dict([(normcase(n), s)
                              for n, k, s in osutil.listdir(dir, True)
                              if getkind(s.st_mode) in _wantedkinds])
-            except OSError, err:
+            except OSError as err:
                 # Python >= 2.5 returns ENOENT and adds winerror field
                 # EINVAL is raised if dir is not a directory.
                 if err.errno not in (errno.ENOENT, errno.EINVAL,
@@ -303,7 +303,7 @@ def unlinkpath(f, ignoremissing=False):
     """unlink and remove the directory if it is empty"""
     try:
         unlink(f)
-    except OSError, e:
+    except OSError as e:
         if not (ignoremissing and e.errno == errno.ENOENT):
             raise
     # try removing directories that might now be empty
@@ -316,7 +316,7 @@ def rename(src, dst):
     '''atomically rename file src to dst, replacing dst if it exists'''
     try:
         os.rename(src, dst)
-    except OSError, e:
+    except OSError as e:
         if e.errno != errno.EEXIST:
             raise
         unlink(dst)
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -705,7 +705,7 @@ def lookup(repo, proto, key):
         c = repo[k]
         r = c.hex()
         success = 1
-    except Exception, inst:
+    except Exception as inst:
         r = str(inst)
         success = 0
     return "%s %s\n" % (success, r)
@@ -800,7 +800,7 @@ def unbundle(repo, proto, heads):
             fp.close()
             os.unlink(tempname)
 
-    except (error.BundleValueError, util.Abort, error.PushRaced), exc:
+    except (error.BundleValueError, util.Abort, error.PushRaced) as exc:
         # handle non-bundle2 case first
         if not getattr(exc, 'duringunbundle2', False):
             try:
@@ -821,7 +821,7 @@ def unbundle(repo, proto, heads):
         try:
             try:
                 raise
-            except error.PushkeyFailed, exc:
+            except error.PushkeyFailed as exc:
                 # check client caps
                 remotecaps = getattr(exc, '_replycaps', None)
                 if (remotecaps is not None
@@ -840,19 +840,19 @@ def unbundle(repo, proto, heads):
                     part.addparam('old', exc.old, mandatory=False)
                 if exc.ret is not None:
                     part.addparam('ret', exc.ret, mandatory=False)
-        except error.BundleValueError, exc:
+        except error.BundleValueError as exc:
             errpart = bundler.newpart('error:unsupportedcontent')
             if exc.parttype is not None:
                 errpart.addparam('parttype', exc.parttype)
             if exc.params:
                 errpart.addparam('params', '\0'.join(exc.params))
-        except util.Abort, exc:
+        except util.Abort as exc:
             manargs = [('message', str(exc))]
             advargs = []
             if exc.hint is not None:
                 advargs.append(('hint', exc.hint))
             bundler.addpart(bundle2.bundlepart('error:abort',
                                                manargs, advargs))
-        except error.PushRaced, exc:
+        except error.PushRaced as exc:
             bundler.newpart('error:pushraced', [('message', str(exc))])
         return streamres(bundler.getchunks())
diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -101,7 +101,7 @@ def _posixworker(ui, func, staticargs, a
         for p in pids:
             try:
                 os.kill(p, signal.SIGTERM)
-            except OSError, err:
+            except OSError as err:
                 if err.errno != errno.ESRCH:
                     raise
     def waitforworkers():
diff --git a/tests/md5sum.py b/tests/md5sum.py
--- a/tests/md5sum.py
+++ b/tests/md5sum.py
@@ -23,7 +23,7 @@ except ImportError:
 for filename in sys.argv[1:]:
     try:
         fp = open(filename, 'rb')
-    except IOError, msg:
+    except IOError as msg:
         sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg))
         sys.exit(1)
 
@@ -34,7 +34,7 @@ for filename in sys.argv[1:]:
             if not data:
                 break
             m.update(data)
-    except IOError, msg:
+    except IOError as msg:
         sys.stderr.write('%s: I/O error: %s\n' % (filename, msg))
         sys.exit(1)
     sys.stdout.write('%s  %s\n' % (m.hexdigest(), filename))
diff --git a/tests/readlink.py b/tests/readlink.py
--- a/tests/readlink.py
+++ b/tests/readlink.py
@@ -5,7 +5,7 @@ import errno, os, sys
 for f in sys.argv[1:]:
     try:
         print f, '->', os.readlink(f)
-    except OSError, err:
+    except OSError as err:
         if err.errno != errno.EINVAL:
             raise
         print f, 'not a symlink'
diff --git a/tests/test-manifest.py b/tests/test-manifest.py
--- a/tests/test-manifest.py
+++ b/tests/test-manifest.py
@@ -325,21 +325,21 @@ class basemanifesttests(object):
         try:
             self.parsemanifest(backwards)
             self.fail('Should have raised ValueError')
-        except ValueError, v:
+        except ValueError as v:
             self.assertIn('Manifest lines not in sorted order.', str(v))
 
     def testNoTerminalNewline(self):
         try:
             self.parsemanifest(A_SHORT_MANIFEST + 'wat')
             self.fail('Should have raised ValueError')
-        except ValueError, v:
+        except ValueError as v:
             self.assertIn('Manifest did not end in a newline.', str(v))
 
     def testNoNewLineAtAll(self):
         try:
             self.parsemanifest('wat')
             self.fail('Should have raised ValueError')
-        except ValueError, v:
+        except ValueError as v:
             self.assertIn('Manifest did not end in a newline.', str(v))
 
     def testHugeManifest(self):
diff --git a/tests/test-trusted.py b/tests/test-trusted.py
--- a/tests/test-trusted.py
+++ b/tests/test-trusted.py
@@ -169,7 +169,7 @@ print "# error handling"
 def assertraises(f, exc=util.Abort):
     try:
         f()
-    except exc, inst:
+    except exc as inst:
         print 'raised', inst.__class__.__name__
     else:
         print 'no exception?!'
@@ -188,10 +188,10 @@ f.close()
 
 try:
     testui(user='abc', group='def', silent=True)
-except error.ParseError, inst:
+except error.ParseError as inst:
     print inst
 
 try:
     testui(debug=True, silent=True)
-except error.ParseError, inst:
+except error.ParseError as inst:
     print inst
diff --git a/tests/test-ui-config.py b/tests/test-ui-config.py
--- a/tests/test-ui-config.py
+++ b/tests/test-ui-config.py
@@ -39,7 +39,7 @@ print repr(testui.config('values', 'unkn
 print "---"
 try:
     print repr(testui.configbool('values', 'string'))
-except error.ConfigError, inst:
+except error.ConfigError as inst:
     print inst
 print repr(testui.configbool('values', 'bool1'))
 print repr(testui.configbool('values', 'bool2'))
diff --git a/tests/tinyproxy.py b/tests/tinyproxy.py
--- a/tests/tinyproxy.py
+++ b/tests/tinyproxy.py
@@ -45,7 +45,7 @@ class ProxyHandler (BaseHTTPServer.BaseH
             host_port = netloc, 80
         print "\t" "connect to %s:%d" % host_port
         try: soc.connect(host_port)
-        except socket.error, arg:
+        except socket.error as arg:
             try: msg = arg[1]
             except (IndexError, TypeError): msg = arg
             self.send_error(404, msg)