changeset 52640:24ee91ba9aa8

pyupgrade: drop usage of py3 aliases for `OSError` These were different classes in py2, but now a handful of error classes are just an alias of `OSError`, like `IOError`, `EnvironmentError`, `WindowsError`, etc. This is the result of running a hacked version of `pyupgrade` 3.19.1[1] $ hg files -0 'relglob:**.py' | xargs -0 \ pyupgrade --py38-plus --keep-percent-format --keep-mock --keep-runtime-typing The hack is because it doesn't have command line switches to disable most changes, so it makes tons of unrelated changes all at once. The hack is to 1) patch `pyupgrade._main._fix_tokens()` to immediately return its content arg 2) change `pyupgrade._data.register_decorator()` to only register the function if it's from the fixer we're interested in: if func.__module__ in ( "pyupgrade._plugins.exceptions", ): FUNCS[tp].append(func) return func [1] https://github.com/asottile/pyupgrade
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 05 Jan 2025 21:03:17 -0500
parents 9db77d46de79
children 9bd6854aab86
files contrib/automation/hgautomation/ssh.py contrib/check-code.py contrib/pull_logger.py contrib/synthrepo.py hgdemandimport/tracing.py hgext/blackbox.py hgext/convert/common.py hgext/convert/convcmd.py hgext/convert/cvs.py hgext/convert/cvsps.py hgext/convert/git.py hgext/convert/monotone.py hgext/convert/subversion.py hgext/eol.py hgext/factotum.py hgext/fastannotate/revmap.py hgext/fsmonitor/__init__.py hgext/fsmonitor/pywatchman/__init__.py hgext/fsmonitor/state.py hgext/gpg.py hgext/largefiles/lfutil.py hgext/largefiles/overrides.py hgext/largefiles/proto.py hgext/largefiles/remotestore.py hgext/lfs/blobstore.py hgext/lfs/wireprotolfsserver.py hgext/mq.py hgext/narrow/narrowcommands.py hgext/phabricator.py hgext/remotefilelog/__init__.py hgext/remotefilelog/basestore.py hgext/remotefilelog/fileserverclient.py hgext/remotefilelog/remotefilelogserver.py hgext/remotefilelog/shallowutil.py hgext/zeroconf/Zeroconf.py hgext/zeroconf/__init__.py i18n/polib.py mercurial/branching/rev_cache.py mercurial/branchmap.py mercurial/bundle2.py mercurial/cmdutil.py mercurial/commandserver.py mercurial/config.py mercurial/configuration/rcutil.py mercurial/context.py mercurial/dispatch.py mercurial/extensions.py mercurial/hgweb/hgwebdir_mod.py mercurial/hgweb/server.py mercurial/hook.py mercurial/httppeer.py mercurial/keepalive.py mercurial/localrepo.py mercurial/lock.py mercurial/loggingutil.py mercurial/manifest.py mercurial/match.py mercurial/patch.py mercurial/posix.py mercurial/pure/osutil.py mercurial/revset.py mercurial/scmposix.py mercurial/scmutil.py mercurial/sparse.py mercurial/sshpeer.py mercurial/statichttprepo.py mercurial/store.py mercurial/streamclone.py mercurial/tags.py mercurial/templater.py mercurial/transaction.py mercurial/ui.py mercurial/url.py mercurial/util.py mercurial/utils/procutil.py mercurial/utils/resourceutil.py mercurial/utils/urlutil.py mercurial/win32.py mercurial/windows.py mercurial/wireprotov1server.py setup.py tests/hghave.py tests/killdaemons.py tests/md5sum.py tests/mockmakedate.py tests/run-tests.py tests/test-stdio.py tests/testlib/badserverext.py tests/tinyproxy.py
diffstat 89 files changed, 182 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/automation/hgautomation/ssh.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/contrib/automation/hgautomation/ssh.py	Sun Jan 05 21:03:17 2025 -0500
@@ -46,7 +46,7 @@
                 )
 
                 return client
-            except socket.error:
+            except OSError:
                 pass
             except paramiko.AuthenticationException:
                 raise
--- a/contrib/check-code.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/contrib/check-code.py	Sun Jan 05 21:03:17 2025 -0500
@@ -816,7 +816,7 @@
             except UnicodeDecodeError as e:
                 print("%s while reading %s" % (e, f))
                 return result
-    except IOError as e:
+    except OSError as e:
         print("Skipping %s, %s" % (f, str(e).split(':', 1)[0]))
         return result
 
--- a/contrib/pull_logger.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/contrib/pull_logger.py	Sun Jan 05 21:03:17 2025 -0500
@@ -76,7 +76,7 @@
 
     try:
         write_to_log(repo, log_entry)
-    except (IOError, error.LockError) as err:
+    except (OSError, error.LockError) as err:
         msg = stringutil.forcebytestr(err)
         repo.ui.warn(_(b'unable to append to pull log: %s\n') % msg)
 
--- a/contrib/synthrepo.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/contrib/synthrepo.py	Sun Jan 05 21:03:17 2025 -0500
@@ -327,7 +327,7 @@
     dictfile = opts.get('dict') or '/usr/share/dict/words'
     try:
         fp = open(dictfile, 'rU')
-    except IOError as err:
+    except OSError as err:
         raise error.Abort('%s: %s' % (dictfile, err.strerror))
     words = fp.read().splitlines()
     fp.close()
--- a/hgdemandimport/tracing.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgdemandimport/tracing.py	Sun Jan 05 21:03:17 2025 -0500
@@ -42,13 +42,13 @@
         # problems too.
         try:
             _pipe.write('START %s %s\n' % (_session, whence))
-        except IOError:
+        except OSError:
             pass
         yield
     finally:
         try:
             _pipe.write('END %s %s\n' % (_session, whence))
-        except IOError:
+        except OSError:
             pass
 
 
@@ -59,5 +59,5 @@
     # See above in log() for why this is in a try/except.
     try:
         _pipe.write('COUNTER %s %d %s\n' % (_session, amount, l))
-    except IOError:
+    except OSError:
         pass
--- a/hgext/blackbox.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/blackbox.py	Sun Jan 05 21:03:17 2025 -0500
@@ -136,7 +136,7 @@
                 fp.write(msg)
                 if debug_to_stderr:
                     ui.write_err(msg)
-        except (IOError, OSError) as err:
+        except OSError as err:
             # deactivate this to avoid failed logging again
             self._trackedevents.clear()
             ui.debug(
--- a/hgext/convert/common.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/common.py	Sun Jan 05 21:03:17 2025 -0500
@@ -600,7 +600,7 @@
         if self.fp is None:
             try:
                 self.fp = open(self.path, 'ab')
-            except IOError as err:
+            except OSError as err:
                 raise error.Abort(
                     _(b'could not open map file %r: %s')
                     % (self.path, encoding.strtolocal(err.strerror))
--- a/hgext/convert/convcmd.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/convcmd.py	Sun Jan 05 21:03:17 2025 -0500
@@ -339,7 +339,7 @@
                     else:
                         m[child] = p1 + p2
         # if file does not exist or error reading, exit
-        except IOError:
+        except OSError:
             raise error.Abort(
                 _(b'splicemap file not found or error reading %s:') % path
             )
--- a/hgext/convert/cvs.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/cvs.py	Sun Jan 05 21:03:17 2025 -0500
@@ -172,7 +172,7 @@
                             if part1 == format:
                                 passw = part2
                                 break
-                    except IOError as inst:
+                    except OSError as inst:
                         if inst.errno != errno.ENOENT:
                             if not getattr(inst, 'filename', None):
                                 inst.filename = cvspass
--- a/hgext/convert/cvsps.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/cvsps.py	Sun Jan 05 21:03:17 2025 -0500
@@ -154,7 +154,7 @@
             directory = prefix
             if prefix == b".":
                 prefix = b""
-        except IOError:
+        except OSError:
             raise logerror(_(b'not a CVS sandbox'))
 
         if prefix and not prefix.endswith(pycompat.ossep):
@@ -163,7 +163,7 @@
         # Use the Root file in the sandbox, if it exists
         try:
             root = util.readfile(os.path.join(b'CVS', b'Root')).strip()
-        except IOError:
+        except OSError:
             pass
 
     if not root:
--- a/hgext/convert/git.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/git.py	Sun Jan 05 21:03:17 2025 -0500
@@ -195,7 +195,7 @@
 
     def catfile(self, rev, ftype):
         if rev == sha1nodeconstants.nullhex:
-            raise IOError
+            raise OSError
         self.catfilepipe[0].write(rev + b'\n')
         self.catfilepipe[0].flush()
         info = self.catfilepipe[1].readline().split()
--- a/hgext/convert/monotone.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/monotone.py	Sun Jan 05 21:03:17 2025 -0500
@@ -49,7 +49,7 @@
             try:
                 with open(path, 'rb') as f:
                     header = f.read(16)
-            except IOError:
+            except OSError:
                 header = b''
             if header != b'SQLite format 3\x00':
                 raise norepo
--- a/hgext/convert/subversion.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/convert/subversion.py	Sun Jan 05 21:03:17 2025 -0500
@@ -224,7 +224,7 @@
             strict_node_history,
             receiver,
         )
-    except IOError:
+    except OSError:
         # Caller may interrupt the iteration
         pickle.dump(None, fp, protocol)
     except Exception as inst:
@@ -1366,7 +1366,7 @@
         stdin.write(arg)
         try:
             stdin.close()
-        except IOError:
+        except OSError:
             raise error.Abort(
                 _(
                     b'Mercurial failed to run itself, check'
--- a/hgext/eol.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/eol.py	Sun Jan 05 21:03:17 2025 -0500
@@ -279,7 +279,7 @@
                 else:
                     data = repo[node][b'.hgeol'].data()
                 return eolfile(ui, repo.root, data)
-            except (IOError, LookupError):
+            except (OSError, LookupError):
                 pass
     except errormod.ConfigError as inst:
         ui.warn(
--- a/hgext/factotum.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/factotum.py	Sun Jan 05 21:03:17 2025 -0500
@@ -111,7 +111,7 @@
                         else:
                             raise error.Abort(_(b'malformed password string'))
                     return (user, passwd)
-        except (OSError, IOError):
+        except OSError:
             raise error.Abort(_(b'factotum not responding'))
         finally:
             os.close(fd)
--- a/hgext/fastannotate/revmap.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/fastannotate/revmap.py	Sun Jan 05 21:03:17 2025 -0500
@@ -254,6 +254,6 @@
             f.seek(-_hshlen, io.SEEK_END)
             if f.tell() > len(revmap.HEADER):
                 hsh = f.read(_hshlen)
-    except IOError:
+    except OSError:
         pass
     return hsh
--- a/hgext/fsmonitor/__init__.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/fsmonitor/__init__.py	Sun Jan 05 21:03:17 2025 -0500
@@ -567,7 +567,7 @@
             else:
                 fn = b'fsmonitorfail.log'
                 f = self.vfs.open(fn, b'wb')
-        except (IOError, OSError):
+        except OSError:
             self.ui.warn(_(b'warning: unable to write to %s\n') % fn)
             return
 
--- a/hgext/fsmonitor/pywatchman/__init__.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/fsmonitor/pywatchman/__init__.py	Sun Jan 05 21:03:17 2025 -0500
@@ -377,7 +377,7 @@
             sock.settimeout(self.timeout)
             sock.connect(self.sockpath)
             self.sock = sock
-        except socket.error as e:
+        except OSError as e:
             sock.close()
             raise SocketConnectError(self.sockpath, e)
 
@@ -562,7 +562,7 @@
             # other way this shows up is if the client has gotten in a weird
             # state, so let's bail out
             CancelIoEx(self.pipe, olap)
-            raise IOError("Async read yielded 0 bytes; unpossible!")
+            raise OSError("Async read yielded 0 bytes; unpossible!")
 
         # Holds precisely the bytes that we read from the prior request
         buf = buf[:nread]
@@ -1168,7 +1168,7 @@
                 res = self.receive()
 
             return res
-        except EnvironmentError as ee:
+        except OSError as ee:
             # When we can depend on Python 3, we can use PEP 3134
             # exception chaining here.
             raise WatchmanEnvironmentError(
--- a/hgext/fsmonitor/state.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/fsmonitor/state.py	Sun Jan 05 21:03:17 2025 -0500
@@ -40,7 +40,7 @@
     def get(self):
         try:
             file = self._vfs(b'fsmonitor.state', b'rb')
-        except IOError as inst:
+        except OSError as inst:
             self._identity = util.filestat(None)
             if inst.errno != errno.ENOENT:
                 raise
@@ -122,7 +122,7 @@
             file = self._vfs(
                 b'fsmonitor.state', b'wb', atomictemp=True, checkambig=True
             )
-        except (IOError, OSError):
+        except OSError:
             self._ui.warn(_(b"warning: unable to write out fsmonitor state\n"))
             return
 
--- a/hgext/gpg.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/gpg.py	Sun Jan 05 21:03:17 2025 -0500
@@ -167,7 +167,7 @@
         fn = b"localsigs"
         for item in parsefile(repo.vfs(fn), fn):
             yield item
-    except IOError:
+    except OSError:
         pass
 
 
--- a/hgext/largefiles/lfutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/largefiles/lfutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -558,7 +558,7 @@
         lfile = splitstandin(standin)
         try:
             hash = readasstandin(wctx[standin])
-        except IOError:
+        except OSError:
             hash = None
         standins.append((lfile, hash))
     return standins
--- a/hgext/largefiles/overrides.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/largefiles/overrides.py	Sun Jan 05 21:03:17 2025 -0500
@@ -891,7 +891,7 @@
             ):
                 destlfile = dest.replace(lfutil.shortname, b'')
                 if not opts[b'force'] and os.path.exists(destlfile):
-                    raise IOError(
+                    raise OSError(
                         b'', _(b'destination largefile already exists')
                     )
             copiedfiles.append((src, dest))
--- a/hgext/largefiles/proto.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/largefiles/proto.py	Sun Jan 05 21:03:17 2025 -0500
@@ -46,10 +46,10 @@
                 tmpfp.write(p)
             tmpfp._fp.seek(0)
             if sha != lfutil.hexsha1(tmpfp._fp):
-                raise IOError(0, _(b'largefile contents do not match hash'))
+                raise OSError(0, _(b'largefile contents do not match hash'))
             tmpfp.close()
             lfutil.linktousercache(repo, sha)
-        except IOError as e:
+        except OSError as e:
             repo.ui.warn(
                 _(b'largefiles: failed to put %s into store: %s\n')
                 % (sha, e.strerror)
@@ -154,7 +154,7 @@
                             _(b'putlfile failed:'), output
                         )
                     return int(ret)
-                except IOError:
+                except OSError:
                     return 1
                 except ValueError:
                     raise error.ResponseError(
--- a/hgext/largefiles/remotestore.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/largefiles/remotestore.py	Sun Jan 05 21:03:17 2025 -0500
@@ -62,7 +62,7 @@
         try:
             with lfutil.httpsendfile(self.ui, filename) as fd:
                 return self._put(hash, fd)
-        except IOError as e:
+        except OSError as e:
             raise error.Abort(
                 _(b'remotestore: could not open file %s: %s')
                 % (filename, stringutil.forcebytestr(e))
@@ -84,7 +84,7 @@
             raise error.Abort(
                 b'%s: %s' % (urlutil.hidepassword(self.url), e.reason)
             )
-        except IOError as e:
+        except OSError as e:
             raise basestore.StoreError(
                 filename, hash, self.url, stringutil.forcebytestr(e)
             )
--- a/hgext/lfs/blobstore.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/lfs/blobstore.py	Sun Jan 05 21:03:17 2025 -0500
@@ -13,7 +13,6 @@
 import json
 import os
 import re
-import socket
 
 from typing import (
     Optional,
@@ -89,7 +88,7 @@
         # self.vfs.  Raise the same error as a normal vfs when asked to read a
         # file that doesn't exist.  The only difference is the full file path
         # isn't available in the error.
-        raise IOError(
+        raise OSError(
             errno.ENOENT,
             pycompat.sysstr(b'%s: No such file or directory' % oid),
         )
@@ -595,7 +594,7 @@
                         self._basictransfer(obj, action, localstore)
                         yield 1, obj.get(b'oid')
                         break
-                    except socket.error as ex:
+                    except OSError as ex:
                         if retry > 0:
                             self.ui.note(
                                 _(b'lfs: failed: %r (remaining retry %d)\n')
--- a/hgext/lfs/wireprotolfsserver.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/lfs/wireprotolfsserver.py	Sun Jan 05 21:03:17 2025 -0500
@@ -229,7 +229,7 @@
                 # The client will skip this upload, but make sure it remains
                 # available locally.
                 store.linkfromusercache(oid)
-        except IOError as inst:
+        except OSError as inst:
             if inst.errno != errno.ENOENT:
                 _logexception(req)
 
--- a/hgext/mq.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/mq.py	Sun Jan 05 21:03:17 2025 -0500
@@ -504,7 +504,7 @@
                 curpath = os.path.join(path, b'patches')
             else:
                 curpath = os.path.join(path, b'patches-' + cur)
-        except IOError:
+        except OSError:
             curpath = os.path.join(path, b'patches')
         self.path = patchdir or curpath
         self.opener = vfsmod.vfs(self.path)
@@ -1048,7 +1048,7 @@
 
             try:
                 ph = patchheader(self.join(patchname), self.plainmode)
-            except IOError:
+            except OSError:
                 self.ui.warn(_(b"unable to read %s\n") % patchname)
                 err = 1
                 break
@@ -1394,7 +1394,7 @@
             try:
                 # if patch file write fails, abort early
                 p = self.opener(patchfn, b"w")
-            except IOError as e:
+            except OSError as e:
                 raise error.Abort(
                     _(b'cannot write patch "%s": %s')
                     % (patchfn, encoding.strtolocal(e.strerror))
@@ -2533,7 +2533,7 @@
                         fp = hg.openpath(self.ui, filename)
                         text = fp.read()
                         fp.close()
-                except (OSError, IOError):
+                except OSError:
                     raise error.Abort(_(b"unable to read file %s") % filename)
                 patchf = self.opener(patchname, b"w")
                 patchf.write(text)
@@ -3927,7 +3927,7 @@
         try:
             fh = repo.vfs(_allqueues, b'r')
             fh.close()
-        except IOError:
+        except OSError:
             return True
 
         return False
@@ -3941,7 +3941,7 @@
             fh.close()
             if current not in queues:
                 queues.append(current)
-        except IOError:
+        except OSError:
             queues = [_defaultqueue]
 
         return sorted(queues)
--- a/hgext/narrow/narrowcommands.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/narrow/narrowcommands.py	Sun Jan 05 21:03:17 2025 -0500
@@ -97,7 +97,7 @@
         ui.status(_(b"reading narrowspec from '%s'\n") % filepath)
         try:
             fdata = util.readfile(filepath)
-        except IOError as inst:
+        except OSError as inst:
             raise error.Abort(
                 _(b"cannot read narrowspecs from '%s': %s")
                 % (filepath, encoding.strtolocal(inst.strerror))
@@ -532,7 +532,7 @@
         filepath = os.path.join(encoding.getcwd(), newrules)
         try:
             fdata = util.readfile(filepath)
-        except IOError as inst:
+        except OSError as inst:
             raise error.StorageError(
                 _(b"cannot read narrowspecs from '%s': %s")
                 % (filepath, encoding.strtolocal(inst.strerror))
--- a/hgext/phabricator.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/phabricator.py	Sun Jan 05 21:03:17 2025 -0500
@@ -233,7 +233,7 @@
         result = True
     except ValueError:
         ui.warn(_(b"invalid JSON in %s\n") % wdirvfs.join(b".arcconfig"))
-    except IOError:
+    except OSError:
         pass
 
     cfg = util.sortdict()
--- a/hgext/remotefilelog/__init__.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/remotefilelog/__init__.py	Sun Jan 05 21:03:17 2025 -0500
@@ -920,7 +920,7 @@
                 repackmod.incrementalrepack(repo)
                 filesrepacked = True
                 continue
-            except (IOError, repackmod.RepackAlreadyRunning):
+            except (OSError, repackmod.RepackAlreadyRunning):
                 # If repack cannot be performed due to not enough disk space
                 # continue doing garbage collection of loose files w/o repack
                 pass
--- a/hgext/remotefilelog/basestore.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/remotefilelog/basestore.py	Sun Jan 05 21:03:17 2025 -0500
@@ -227,7 +227,7 @@
                         f.write(b"corrupt %s during read\n" % filepath)
                 os.rename(filepath, filepath + b".corrupt")
                 raise KeyError(b"corrupt local cache file %s" % filepath)
-        except IOError:
+        except OSError:
             raise KeyError(
                 b"no file found at %s for %s:%s" % (filepath, name, hex(node))
             )
--- a/hgext/remotefilelog/fileserverclient.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/remotefilelog/fileserverclient.py	Sun Jan 05 21:03:17 2025 -0500
@@ -193,7 +193,7 @@
                 self.pipei.write(request)
                 if flush:
                     self.pipei.flush()
-            except IOError:
+            except OSError:
                 self.close()
 
     def receiveline(self):
@@ -203,7 +203,7 @@
             result = self.pipeo.readline()[:-1]
             if not result:
                 self.close()
-        except IOError:
+        except OSError:
             self.close()
 
         return result
--- a/hgext/remotefilelog/remotefilelogserver.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/remotefilelog/remotefilelogserver.py	Sun Jan 05 21:03:17 2025 -0500
@@ -271,7 +271,7 @@
             try:
                 f = util.atomictempfile(filecachepath, b"wb")
                 f.write(text)
-            except (IOError, OSError):
+            except OSError:
                 # Don't abort if the user only has permission to read,
                 # and not write.
                 pass
--- a/hgext/remotefilelog/shallowutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/remotefilelog/shallowutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -326,7 +326,7 @@
     # we should never have empty files
     if not result:
         os.remove(path)
-        raise IOError(b"empty file: %s" % path)
+        raise OSError(b"empty file: %s" % path)
 
     return result
 
@@ -474,7 +474,7 @@
     try:
         os.chown(path, -1, gid)
         os.chmod(path, 0o2775)
-    except (IOError, OSError) as ex:
+    except OSError as ex:
         if warn:
             warn(_(b'unable to chown/chmod on %s: %s\n') % (path, ex))
 
--- a/hgext/zeroconf/Zeroconf.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/zeroconf/Zeroconf.py	Sun Jan 05 21:03:17 2025 -0500
@@ -1010,7 +1010,7 @@
         sock = self.zeroconf.socket
         try:
             data, (addr, port) = sock.recvfrom(_MAX_MSG_ABSOLUTE)
-        except socket.error as e:
+        except OSError as e:
             if e.errno == errno.EBADF:
                 # some other thread may close the socket
                 return
--- a/hgext/zeroconf/__init__.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/hgext/zeroconf/__init__.py	Sun Jan 05 21:03:17 2025 -0500
@@ -60,7 +60,7 @@
         s.connect(('1.0.0.1', 0))
         ip = s.getsockname()[0]
         return ip
-    except socket.error:
+    except OSError:
         pass
 
     # Generic method, sometimes gives useless results
@@ -79,7 +79,7 @@
         s.connect(('1.0.0.1', 1))
         ip = s.getsockname()[0]
         return ip
-    except socket.error:
+    except OSError:
         pass
 
     return dumbip
--- a/i18n/polib.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/i18n/polib.py	Sun Jan 05 21:03:17 2025 -0500
@@ -459,7 +459,7 @@
             string, the method to use for output.
         """
         if self.fpath is None and fpath is None:
-            raise IOError('You must provide a file path to save() method')
+            raise OSError('You must provide a file path to save() method')
         contents = getattr(self, repr_method)()
         if fpath is None:
             fpath = self.fpath
@@ -1393,7 +1393,7 @@
             if tokens[0] in keywords and nb_tokens > 1:
                 line = line[len(tokens[0]) :].lstrip()
                 if re.search(r'([^\\]|^)"', line[1:-1]):
-                    raise IOError(
+                    raise OSError(
                         'Syntax error in po file %s (line %s): '
                         'unescaped double quote found'
                         % (self.instance.fpath, self.current_line)
@@ -1413,7 +1413,7 @@
             elif line[:1] == '"':
                 # we are on a continuation line
                 if re.search(r'([^\\]|^)"', line[1:-1]):
-                    raise IOError(
+                    raise OSError(
                         'Syntax error in po file %s (line %s): '
                         'unescaped double quote found'
                         % (self.instance.fpath, self.current_line)
@@ -1444,7 +1444,7 @@
 
             elif tokens[0] == '#|':
                 if nb_tokens <= 1:
-                    raise IOError(
+                    raise OSError(
                         'Syntax error in po file %s (line %s)'
                         % (self.instance.fpath, self.current_line)
                     )
@@ -1460,7 +1460,7 @@
 
                 if nb_tokens == 2:
                     # Invalid continuation line.
-                    raise IOError(
+                    raise OSError(
                         'Syntax error in po file %s (line %s): '
                         'invalid continuation line'
                         % (self.instance.fpath, self.current_line)
@@ -1469,7 +1469,7 @@
                 # we are on a "previous translation" comment line,
                 if tokens[1] not in prev_keywords:
                     # Unknown keyword in previous translation comment.
-                    raise IOError(
+                    raise OSError(
                         'Syntax error in po file %s (line %s): '
                         'unknown keyword %s'
                         % (self.instance.fpath, self.current_line, tokens[1])
@@ -1482,7 +1482,7 @@
                 self.process(prev_keywords[tokens[1]])
 
             else:
-                raise IOError(
+                raise OSError(
                     'Syntax error in po file %s (line %s)'
                     % (self.instance.fpath, self.current_line)
                 )
@@ -1554,7 +1554,7 @@
             if action():
                 self.current_state = state
         except Exception:
-            raise IOError(
+            raise OSError(
                 'Syntax error in po file (line %s)' % self.current_line
             )
 
@@ -1759,14 +1759,14 @@
         elif magic_number == MOFile.MAGIC_SWAPPED:
             ii = '>II'
         else:
-            raise IOError('Invalid mo file, magic number is incorrect !')
+            raise OSError('Invalid mo file, magic number is incorrect !')
         self.instance.magic_number = magic_number
         # parse the version number and the number of strings
         version, numofstrings = self._readbinary(ii, 8)
         # from MO file format specs: "A program seeing an unexpected major
         # revision number should stop reading the MO file entirely"
         if version not in (0, 1):
-            raise IOError('Invalid mo file, unexpected major revision number')
+            raise OSError('Invalid mo file, unexpected major revision number')
         self.instance.version = version
         # original strings and translation strings hash table offset
         msgids_hash_offset, msgstrs_hash_offset = self._readbinary(ii, 8)
--- a/mercurial/branching/rev_cache.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/branching/rev_cache.py	Sun Jan 05 21:03:17 2025 -0500
@@ -157,7 +157,7 @@
         try:
             try:
                 bndata = repo.cachevfs.read(_rbcnames)
-            except (IOError, OSError):
+            except OSError:
                 # If we don't have "v2" data, we might have "v1" data worth
                 # using.
                 #
@@ -170,7 +170,7 @@
                 self._names = [
                     encoding.tolocal(bn) for bn in bndata.split(b'\0')
                 ]
-        except (IOError, OSError):
+        except OSError:
             if readonly:
                 # don't try to use cache - fall back to the slow path
                 self.branchinfo = self._branchinfo
@@ -205,7 +205,7 @@
                     with repo.cachevfs(_rbc_legacy_revs) as fp:
                         data = fp.read()
                 self._rbcrevs = rbcrevs(data)
-            except (IOError, OSError) as inst:
+            except OSError as inst:
                 repo.ui.debug(
                     b"couldn't read revision branch cache: %s\n"
                     % stringutil.forcebytestr(inst)
@@ -352,7 +352,7 @@
                     wlock = repo.wlock(wait=False)
                 self._writerevs(repo, start)
 
-        except (IOError, OSError, error.Abort, error.LockError) as inst:
+        except (OSError, error.Abort, error.LockError) as inst:
             repo.ui.debug(
                 b"couldn't write revision branch cache%s: %s\n"
                 % (step, stringutil.forcebytestr(inst))
--- a/mercurial/branchmap.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/branchmap.py	Sun Jan 05 21:03:17 2025 -0500
@@ -525,7 +525,7 @@
                 # invalidate the cache
                 raise ValueError('tip differs')
             bcache._load_heads(repo, lineiter)
-        except (IOError, OSError):
+        except OSError:
             return None
 
         except Exception as inst:
@@ -632,7 +632,7 @@
                 nodecount,
             )
             self._state = STATE_CLEAN
-        except (IOError, OSError, error.Abort) as inst:
+        except (OSError, error.Abort) as inst:
             # Abort may be raised by read only opener, so log and continue
             repo.ui.debug(
                 b"couldn't write branch cache: %s\n"
--- a/mercurial/bundle2.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/bundle2.py	Sun Jan 05 21:03:17 2025 -0500
@@ -1617,7 +1617,7 @@
         if self._seekable:
             try:
                 return self._fp.tell()
-            except IOError as e:
+            except OSError as e:
                 if e.errno == errno.ESPIPE:
                     self._seekable = False
                 else:
--- a/mercurial/cmdutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/cmdutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -1163,7 +1163,7 @@
                 message = ui.fin.read()
             else:
                 message = b'\n'.join(util.readfile(logfile).splitlines())
-        except IOError as inst:
+        except OSError as inst:
             raise error.Abort(
                 _(b"can't read commit message '%s': %s")
                 % (logfile, encoding.strtolocal(inst.strerror))
@@ -1796,7 +1796,7 @@
                     # Linux CLI behavior.
                     util.copyfile(src, target, copystat=rename)
                 srcexists = True
-            except IOError as inst:
+            except OSError as inst:
                 if inst.errno == errno.ENOENT:
                     ui.warn(_(b'%s: deleted in working directory\n') % relsrc)
                     srcexists = False
--- a/mercurial/commandserver.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/commandserver.py	Sun Jan 05 21:03:17 2025 -0500
@@ -724,7 +724,7 @@
                 super(unixcmdserverrepo, self).close()
                 try:
                     self._cmdserveripc.send(self.root)
-                except socket.error:
+                except OSError:
                     self.ui.log(
                         b'cmdserver', b'failed to send repo root to master\n'
                     )
--- a/mercurial/config.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/config.py	Sun Jan 05 21:03:17 2025 -0500
@@ -196,7 +196,7 @@
                 expanded = util.expandpath(m.group(1))
                 try:
                     include(expanded, remap=remap, sections=sections)
-                except IOError as inst:
+                except OSError as inst:
                     if inst.errno != errno.ENOENT:
                         raise error.ConfigError(
                             _(b"cannot include %s (%s)")
--- a/mercurial/configuration/rcutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/configuration/rcutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -144,7 +144,7 @@
             hgvfs = vfs.vfs(os.path.join(path, b".hg"))
             sharedvfs = localrepo._getsharedvfs(hgvfs, requirements)
             return [sharedvfs.join(b"hgrc")]
-    except IOError:
+    except OSError:
         pass
     return []
 
--- a/mercurial/context.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/context.py	Sun Jan 05 21:03:17 2025 -0500
@@ -963,7 +963,7 @@
     def isbinary(self):
         try:
             return stringutil.binary(self.data())
-        except IOError:
+        except OSError:
             return False
 
     def isexec(self):
@@ -1854,7 +1854,7 @@
                         fixup.append((f, cache_info))
                     else:
                         clean.append(f)
-            except (IOError, OSError):
+            except OSError:
                 # A file become inaccessible in between? Mark it as deleted,
                 # matching dirstate behavior (issue5584).
                 # The dirstate has more complex behavior around whether a
--- a/mercurial/dispatch.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/dispatch.py	Sun Jan 05 21:03:17 2025 -0500
@@ -109,7 +109,7 @@
         assert ui.fout is not None  # help pytype
         try:
             ui.fout.flush()
-        except IOError as e:
+        except OSError as e:
             err = e
             status = -1
 
@@ -124,7 +124,7 @@
             ui.ferr.flush()
         # There's not much we can do about an I/O error here. So (possibly)
         # change the status code and move on.
-        except IOError:
+        except OSError:
             status = -1
 
     return status
@@ -208,13 +208,13 @@
         try:
             fp.flush()
             continue
-        except IOError:
+        except OSError:
             pass
         # Otherwise mark it as closed to silence "Exception ignored in"
         # message emitted by the interpreter finalizer.
         try:
             fp.close()
-        except IOError:
+        except OSError:
             pass
 
 
@@ -500,7 +500,7 @@
             if not suggested:
                 ui.warn(nocmdmsg)
                 ui.warn(_(b"(use 'hg help' for a list of commands)\n"))
-    except IOError:
+    except OSError:
         raise
     except KeyboardInterrupt:
         raise
--- a/mercurial/extensions.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/extensions.py	Sun Jan 05 21:03:17 2025 -0500
@@ -804,7 +804,7 @@
     try:
         with open(path, 'rb') as src:
             doc = _moduledoc(src)
-    except IOError:
+    except OSError:
         return
 
     if doc:  # extracting localized synopsis
@@ -919,7 +919,7 @@
 def _finddisabledcmd(ui, cmd, name, path, strict):
     try:
         cmdtable = _disabledcmdtable(path)
-    except (IOError, SyntaxError):
+    except (OSError, SyntaxError):
         return
     try:
         aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
--- a/mercurial/hgweb/hgwebdir_mod.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/hgweb/hgwebdir_mod.py	Sun Jan 05 21:03:17 2025 -0500
@@ -152,7 +152,7 @@
                 try:
                     hg.repository(ui, path)
                     directory = False
-                except (IOError, error.RepoError):
+                except (OSError, error.RepoError):
                     pass
 
         parts = [
@@ -211,7 +211,7 @@
         # update time with local timezone
         try:
             r = hg.repository(ui, path)
-        except IOError:
+        except OSError:
             u.warn(_(b'error accessing repository at %s\n') % path)
             continue
         except error.RepoError:
@@ -475,7 +475,7 @@
                         # ensure caller gets private copy of ui
                         repo = hg.repository(self.ui.copy(), real)
                         return hgweb_mod.hgweb(repo).run_wsgi(req, res)
-                    except IOError as inst:
+                    except OSError as inst:
                         msg = encoding.strtolocal(inst.strerror)
                         raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                     except error.RepoError as inst:
--- a/mercurial/hgweb/server.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/hgweb/server.py	Sun Jan 05 21:03:17 2025 -0500
@@ -409,7 +409,7 @@
     port = urlutil.getport(ui.config(b'web', b'port'))
     try:
         return cls(ui, app, (address, port), handler)
-    except socket.error as inst:
+    except OSError as inst:
         raise error.Abort(
             _(b"cannot start server at '%s:%d': %s")
             % (address, port, encoding.strtolocal(inst.args[1]))
--- a/mercurial/hook.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/hook.py	Sun Jan 05 21:03:17 2025 -0500
@@ -313,14 +313,14 @@
         # remote side available to the client immediately.
         try:
             procutil.stderr.flush()
-        except IOError as err:
+        except OSError as err:
             if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
                 raise error.StdioError(err)
 
         if _redirect and oldstdout >= 0:
             try:
                 procutil.stdout.flush()  # write hook output to stderr fd
-            except IOError as err:
+            except OSError as err:
                 if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
                     raise error.StdioError(err)
             os.dup2(oldstdout, stdoutno)
--- a/mercurial/httppeer.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/httppeer.py	Sun Jan 05 21:03:17 2025 -0500
@@ -11,7 +11,6 @@
 import errno
 import io
 import os
-import socket
 import struct
 import typing
 
@@ -303,7 +302,7 @@
             % urlutil.hidepassword(req.get_full_url())
         )
         ui.traceback()
-        raise IOError(None, inst)
+        raise OSError(None, inst)
     finally:
         if ui.debugflag and ui.configbool(b'devel', b'debug.peer-request'):
             code = res.code if res else -1
@@ -522,7 +521,7 @@
             # like generic socket errors. They lack any values in
             # .args on Python 3 which breaks our socket.error block.
             raise
-        except socket.error as err:
+        except OSError as err:
             if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
                 raise error.Abort(_(b'push failed: %s') % err.args[1])
             raise error.Abort(err.args[1])
--- a/mercurial/keepalive.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/keepalive.py	Sun Jan 05 21:03:17 2025 -0500
@@ -86,7 +86,6 @@
 
 import collections
 import hashlib
-import socket
 import sys
 import threading
 
@@ -249,7 +248,7 @@
             raise urlerr.urlerror(
                 _(b'bad HTTP status line: %s') % pycompat.sysbytes(err.line)
             )
-        except (socket.error, httplib.HTTPException) as err:
+        except (OSError, httplib.HTTPException) as err:
             raise urlerr.urlerror(err)
 
         # If not a persistent connection, don't try to reuse it. Look
@@ -282,7 +281,7 @@
             r = h.getresponse()
             # note: just because we got something back doesn't mean it
             # worked.  We'll check the version below, too.
-        except (socket.error, httplib.HTTPException):
+        except (OSError, httplib.HTTPException):
             r = None
         except:  # re-raises
             # adding this block just in case we've missed
@@ -354,7 +353,7 @@
                     urllibcompat.getselector(req),
                     **skipheaders,
                 )
-        except socket.error as err:
+        except OSError as err:
             raise urlerr.urlerror(err)
         for k, v in headers.items():
             h.putheader(k, v)
--- a/mercurial/localrepo.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/localrepo.py	Sun Jan 05 21:03:17 2025 -0500
@@ -877,19 +877,19 @@
         try:
             ui.readconfig(sharedvfs.join(b'hgrc'), root=sharedvfs.base)
             ret = True
-        except IOError:
+        except OSError:
             pass
 
     try:
         ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
         ret = True
-    except IOError:
+    except OSError:
         pass
 
     try:
         ui.readconfig(hgvfs.join(b'hgrc-not-shared'), root=wdirvfs.base)
         ret = True
-    except IOError:
+    except OSError:
         pass
 
     return ret
@@ -2814,7 +2814,7 @@
                     b'repository tip rolled back to revision %d (undo %s)\n'
                 ) % (oldtip, desc)
             parentgone = any(self[p].rev() > oldtip for p in parents)
-        except IOError:
+        except OSError:
             msg = _(b'rolling back unknown transaction\n')
             desc = None
             parentgone = True
@@ -3966,7 +3966,7 @@
             try:
                 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
                 sharedpath = util.pconvert(sharedpath)
-            except (IOError, ValueError) as e:
+            except (OSError, ValueError) as e:
                 # ValueError is raised on Windows if the drive letters differ
                 # on each path.
                 raise error.Abort(
--- a/mercurial/lock.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/lock.py	Sun Jan 05 21:03:17 2025 -0500
@@ -287,7 +287,7 @@
                 with self._maybedelayedinterrupt():
                     self.vfs.makelock(lockname, self.f)
                     self.held = 1
-            except (OSError, IOError) as why:
+            except OSError as why:
                 if why.errno == errno.EEXIST:
                     locker = self._readlock()
                     if locker is None:
--- a/mercurial/loggingutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/loggingutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -97,7 +97,7 @@
                 maxsize=self._maxsize,
             ) as fp:
                 fp.write(line)
-        except IOError as err:
+        except OSError as err:
             ui.debug(
                 b'cannot write to %s: %s\n'
                 % (self._name, stringutil.forcebytestr(err))
@@ -119,7 +119,7 @@
         try:
             self._fp.write(line)
             self._fp.flush()
-        except IOError as err:
+        except OSError as err:
             ui.debug(
                 b'cannot write to %s: %s\n'
                 % (
--- a/mercurial/manifest.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/manifest.py	Sun Jan 05 21:03:17 2025 -0500
@@ -1582,7 +1582,7 @@
                     if len(value) != size:
                         break
                     set(node, value)
-        except IOError:
+        except OSError:
             # the file is allowed to be missing
             pass
 
@@ -1606,7 +1606,7 @@
                     if node is self._head:
                         break
                     node = node.prev
-        except IOError:
+        except OSError:
             # We could not write the cache (eg: permission error)
             # the content can be missing.
             #
--- a/mercurial/match.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/match.py	Sun Jan 05 21:03:17 2025 -0500
@@ -368,7 +368,7 @@
                 else:
                     files = files.splitlines()
                 files = [f for f in files if f]
-            except EnvironmentError:
+            except OSError:
                 raise error.Abort(_(b"unable to read file list (%s)") % pat)
             for k, p, source in _donormalize(
                 files, default, root, cwd, auditor, warn
@@ -391,7 +391,7 @@
                         inst.message,
                     )
                 )
-            except IOError as inst:
+            except OSError as inst:
                 if warn:
                     warn(
                         _(b"skipping unreadable pattern file '%s': %s\n")
--- a/mercurial/patch.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/patch.py	Sun Jan 05 21:03:17 2025 -0500
@@ -2023,7 +2023,7 @@
     try:
         pos = lr.fp.tell()
         fp = lr.fp
-    except IOError:
+    except OSError:
         fp = stringio(lr.fp.read())
     gitlr = linereader(fp)
     gitlr.push(firstline)
--- a/mercurial/posix.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/posix.py	Sun Jan 05 21:03:17 2025 -0500
@@ -260,7 +260,7 @@
                     copymode(storedir, cachedir)
                 else:
                     copymode(basedir, cachedir)
-            except (IOError, OSError):
+            except OSError:
                 # we other fallback logic triggers
                 pass
         if os.path.isdir(cachedir):
@@ -310,7 +310,7 @@
         finally:
             if fn is not None:
                 unlink(fn)
-    except (IOError, OSError):
+    except OSError:
         # we don't care, the user probably won't be able to commit anyway
         return False
 
@@ -783,7 +783,7 @@
                 if not s:
                     break
                 chunks.append(s)
-            except IOError:
+            except OSError:
                 break
 
         return b''.join(chunks)
--- a/mercurial/pure/osutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/pure/osutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -119,7 +119,7 @@
 
     def _raiseioerror(name):
         err = ctypes.WinError()  # pytype: disable=module-attr
-        raise IOError(
+        raise OSError(
             err.errno, '%s: %s' % (encoding.strfromlocal(name), err.strerror)
         )
 
--- a/mercurial/revset.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/revset.py	Sun Jan 05 21:03:17 2025 -0500
@@ -1372,7 +1372,7 @@
                 rn = _node(repo, n)
                 if rn is not None:
                     listed_rev.add(rn)
-    except IOError as exc:
+    except OSError as exc:
         m = _(b'cannot open nodes file "%s": %s')
         m %= (path, encoding.strtolocal(exc.strerror))
         raise error.Abort(m)
--- a/mercurial/scmposix.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/scmposix.py	Sun Jan 05 21:03:17 2025 -0500
@@ -95,7 +95,7 @@
                 return width, height
         except ValueError:
             pass
-        except IOError as e:
+        except OSError as e:
             if e.errno == errno.EINVAL:
                 pass
             else:
--- a/mercurial/scmutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/scmutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -258,7 +258,7 @@
             # SSLError of Python 2.7.9 contains a unicode
             reason = encoding.unitolocal(reason)
         ui.error(_(b"abort: error: %s\n") % stringutil.forcebytestr(reason))
-    except (IOError, OSError) as inst:
+    except OSError as inst:
         if hasattr(inst, "args") and inst.args and inst.args[0] == errno.EPIPE:
             pass
         elif getattr(inst, "strerror", None):  # common IOError or OSError
--- a/mercurial/sparse.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/sparse.py	Sun Jan 05 21:03:17 2025 -0500
@@ -357,7 +357,7 @@
                     default=b'relpath',
                 )
                 matchers.append(matcher)
-        except IOError:
+        except OSError:
             pass
 
     if not matchers:
--- a/mercurial/sshpeer.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/sshpeer.py	Sun Jan 05 21:03:17 2025 -0500
@@ -169,7 +169,7 @@
         try:
             for l in pipee:
                 ui.status(_(b'remote: '), l)
-        except (IOError, ValueError):
+        except (OSError, ValueError):
             pass
 
         pipee.close()
@@ -316,7 +316,7 @@
 
         stdin.write(b''.join(handshake))
         stdin.flush()
-    except IOError:
+    except OSError:
         badresponse()
 
     # Assume version 1 of wire protocol by default.
@@ -350,7 +350,7 @@
                 ui.debug(b'remote: ', l)
             lines.append(l)
             max_noise -= 1
-        except IOError:
+        except OSError:
             badresponse()
     else:
         badresponse()
@@ -709,7 +709,7 @@
             peer._call(
                 b"protocaps", caps=b' '.join(sorted(_clientcapabilities()))
             )
-        except IOError:
+        except OSError:
             peer._cleanup()
             raise error.RepoError(_(b'capability exchange failed'))
 
--- a/mercurial/statichttprepo.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/statichttprepo.py	Sun Jan 05 21:03:17 2025 -0500
@@ -72,9 +72,9 @@
             # Explicitly convert the exception to str as Py3 will try
             # convert it to local encoding and with as the HTTPResponse
             # instance doesn't support encode.
-            raise IOError(num, str(inst))
+            raise OSError(num, str(inst))
         except urlerr.urlerror as inst:
-            raise IOError(None, inst.reason)
+            raise OSError(None, inst.reason)
 
         if code == 200:
             # HTTPRangeHandler does nothing if remote does not support
@@ -140,7 +140,7 @@
 
         def __call__(self, path, mode=b'r', *args, **kw):
             if mode not in (b'r', b'rb'):
-                raise IOError('Permission denied')
+                raise OSError('Permission denied')
             f = b"/".join((self.base, urlreq.quote(path)))
             return httprangereader(f, urlopener)
 
--- a/mercurial/store.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/store.py	Sun Jan 05 21:03:17 2025 -0500
@@ -1028,7 +1028,7 @@
         self._dirty = False
         try:
             fp = self.vfs(b'fncache', mode=b'rb')
-        except IOError:
+        except OSError:
             # skip nonexistent file
             self.entries = set()
             return
--- a/mercurial/streamclone.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/streamclone.py	Sun Jan 05 21:03:17 2025 -0500
@@ -678,7 +678,7 @@
             self._flush_some_on_disk()
         try:
             return self._keep_one(src)
-        except IOError as err:
+        except OSError as err:
             if err.errno not in (errno.ENOENT, errno.EPERM):
                 raise
             return None
--- a/mercurial/tags.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/tags.py	Sun Jan 05 21:03:17 2025 -0500
@@ -436,7 +436,7 @@
         cachefile = repo.cachevfs(_filename(repo), b'r')
         # force reading the file for static-http
         cachelines = iter(cachefile)
-    except IOError:
+    except OSError:
         cachefile = None
 
     cacherev = None
@@ -581,7 +581,7 @@
     filename = _filename(repo)
     try:
         cachefile = repo.cachevfs(filename, b'w', atomictemp=True)
-    except (OSError, IOError):
+    except OSError:
         return
 
     ui.log(
@@ -609,7 +609,7 @@
 
     try:
         cachefile.close()
-    except (OSError, IOError):
+    except OSError:
         pass
 
 
@@ -692,7 +692,7 @@
     if local:
         try:
             fp = repo.vfs(b'localtags', b'r+')
-        except IOError:
+        except OSError:
             fp = repo.vfs(b'localtags', b'a')
         else:
             prevtags = fp.read()
@@ -768,7 +768,7 @@
 
         try:
             data = repo.cachevfs.read(_fnodescachefile)
-        except (OSError, IOError):
+        except OSError:
             data = b""
         self._raw = bytearray(data)
 
@@ -976,7 +976,7 @@
                 self._dirtyoffset = None
             finally:
                 f.close()
-        except (IOError, OSError) as inst:
+        except OSError as inst:
             repo.ui.log(
                 b'tagscache',
                 b"couldn't write cache/%s: %s\n"
--- a/mercurial/templater.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/templater.py	Sun Jan 05 21:03:17 2025 -0500
@@ -962,12 +962,12 @@
                 raise templateutil.TemplateNotFound(
                     _(b'"%s" not in template map') % inst.args[0]
                 )
-            except IOError as inst:
+            except OSError as inst:
                 reason = _(b'template file %s: %s') % (
                     self._map[t],
                     stringutil.forcebytestr(inst.args[1]),
                 )
-                raise IOError(inst.args[0], encoding.strfromlocal(reason))
+                raise OSError(inst.args[0], encoding.strfromlocal(reason))
         return self._parse(self.cache[t])
 
     def _parse(self, tmpl):
@@ -1170,5 +1170,5 @@
 ) -> Tuple[Optional[bytes], Optional[BinaryIO]]:
     try:
         return open_template(name, templatepath)
-    except (EnvironmentError, ImportError):
+    except (OSError, ImportError):
         return None, None
--- a/mercurial/transaction.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/transaction.py	Sun Jan 05 21:03:17 2025 -0500
@@ -126,7 +126,7 @@
         try:
             util.copyfile(backuppath, filepath, checkambig=checkambig)
             backupfiles.append((vfs, b))
-        except IOError as exc:
+        except OSError as exc:
             e_msg = stringutil.forcebytestr(exc)
             report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
             raise
@@ -169,7 +169,7 @@
                     )
                 fp.truncate(o)
                 fp.close()
-            except IOError:
+            except OSError:
                 report(_(b"failed to truncate %s\n") % f)
                 raise
         else:
@@ -206,7 +206,7 @@
                     # in both case, our target result (delete the file) is
                     # already achieved.
                     pass
-        except (IOError, OSError, error.Abort):
+        except (OSError, error.Abort):
             if not c:
                 raise
 
@@ -219,7 +219,7 @@
         for vfs, f in backupfiles:
             if vfs.exists(f):
                 vfs.unlink(f)
-    except (IOError, OSError, error.Abort):
+    except (OSError, error.Abort):
         # only pure backup file remains, it is sage to ignore any error
         pass
 
@@ -709,7 +709,7 @@
             if not f and b and vfs.exists(b):
                 try:
                     vfs.unlink(b)
-                except (IOError, OSError, error.Abort) as inst:
+                except (OSError, error.Abort) as inst:
                     if not c:
                         raise
                     # Abort may be raise by read only opener
@@ -737,7 +737,7 @@
             if b and vfs.exists(b):
                 try:
                     vfs.unlink(b)
-                except (IOError, OSError, error.Abort) as inst:
+                except (OSError, error.Abort) as inst:
                     if not c:
                         raise
                     # Abort may be raise by read only opener
--- a/mercurial/ui.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/ui.py	Sun Jan 05 21:03:17 2025 -0500
@@ -464,7 +464,7 @@
     ) -> None:
         try:
             fp = resourceutil.open_resource(name[0], name[1])
-        except IOError:
+        except OSError:
             if not sections:  # ignore unless we were looking for something
                 return
             raise
@@ -478,7 +478,7 @@
     ) -> None:
         try:
             fp = open(filename, 'rb')
-        except IOError:
+        except OSError:
             if not sections:  # ignore unless we were looking for something
                 return
             raise
@@ -1261,7 +1261,7 @@
                     label = opts.get('label', b'')
                     msg = self.label(msg, label)
                 dest.write(msg)
-        except IOError as err:
+        except OSError as err:
             raise error.StdioError(err)
         finally:
             self._blockedtimes[b'stdio_blocked'] += (
@@ -1310,7 +1310,7 @@
             # including stdout.
             if dest is self._ferr and not getattr(dest, 'closed', False):
                 dest.flush()
-        except IOError as err:
+        except OSError as err:
             if dest is self._ferr and err.errno in (
                 errno.EPIPE,
                 errno.EIO,
@@ -1350,13 +1350,13 @@
         try:
             try:
                 self._fout.flush()
-            except IOError as err:
+            except OSError as err:
                 if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
                     raise error.StdioError(err)
             finally:
                 try:
                     self._ferr.flush()
-                except IOError as err:
+                except OSError as err:
                     if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
                         raise error.StdioError(err)
         finally:
--- a/mercurial/url.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/url.py	Sun Jan 05 21:03:17 2025 -0500
@@ -297,7 +297,7 @@
             list(iter(res.fp.readline, b'\r\n'))
         else:
             self.close()
-            raise socket.error(
+            raise OSError(
                 "Tunnel connection failed: %d %s" % (status, reason.strip())
             )
 
--- a/mercurial/util.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/util.py	Sun Jan 05 21:03:17 2025 -0500
@@ -2023,7 +2023,7 @@
                 m = "the `nb_bytes` argument is incompatible with `hardlink`"
                 raise error.ProgrammingError(m)
             return
-        except (IOError, OSError) as exc:
+        except OSError as exc:
             if exc.errno != errno.EEXIST and no_hardlink_cb is not None:
                 no_hardlink_cb()
             # fall back to normal copy
@@ -2089,7 +2089,7 @@
         if hardlink:
             try:
                 oslink(src, dst)
-            except (IOError, OSError) as exc:
+            except OSError as exc:
                 if exc.errno != errno.EEXIST:
                     hardlink = False
                 # XXX maybe try to relink if the file exist ?
@@ -2490,7 +2490,7 @@
     try:
         try:
             ifp = posixfile(name, b"rb")
-        except IOError as inst:
+        except OSError as inst:
             if inst.errno == errno.ENOENT:
                 return temp
             if not getattr(inst, 'filename', None):
--- a/mercurial/utils/procutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/utils/procutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -55,10 +55,10 @@
     """Dummy file object to simulate closed stdio behavior"""
 
     def readinto(self, b):
-        raise IOError(errno.EBADF, 'Bad file descriptor')
+        raise OSError(errno.EBADF, 'Bad file descriptor')
 
     def write(self, b):
-        raise IOError(errno.EBADF, 'Bad file descriptor')
+        raise OSError(errno.EBADF, 'Bad file descriptor')
 
 
 class LineBufferedWrapper:
--- a/mercurial/utils/resourceutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/utils/resourceutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -95,7 +95,7 @@
 
         try:
             return os.path.isfile(pycompat.fsdecode(path))
-        except (IOError, OSError):
+        except OSError:
             return False
 
     def contents(package: bytes) -> "Iterator[bytes]":
--- a/mercurial/utils/urlutil.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/utils/urlutil.py	Sun Jan 05 21:03:17 2025 -0500
@@ -54,7 +54,7 @@
 
     try:
         return socket.getservbyname(pycompat.sysstr(port))
-    except socket.error:
+    except OSError:
         raise error.Abort(
             _(b"no port number associated with service '%s'") % port
         )
--- a/mercurial/win32.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/win32.py	Sun Jan 05 21:03:17 2025 -0500
@@ -718,7 +718,7 @@
     if os.path.isdir(path):
         # use EPERM because it is POSIX prescribed value, even though
         # unlink(2) on directories returns EISDIR on Linux
-        raise IOError(
+        raise OSError(
             errno.EPERM,
             r"Unlinking directory not permitted: '%s'"
             % encoding.strfromlocal(path),
@@ -749,7 +749,7 @@
         except FileExistsError:
             pass
     else:
-        raise IOError(errno.EEXIST, "No usable temporary filename found")
+        raise OSError(errno.EEXIST, "No usable temporary filename found")
 
     try:
         os.unlink(temp)
--- a/mercurial/windows.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/windows.py	Sun Jan 05 21:03:17 2025 -0500
@@ -191,9 +191,9 @@
             return mixedfilemodewrapper(fp)
 
         return fp
-    except WindowsError as err:  # pytype: disable=name-error
+    except OSError as err:
         # convert to a friendlier exception
-        raise IOError(
+        raise OSError(
             err.errno, '%s: %s' % (encoding.strfromlocal(name), err.strerror)
         )
 
@@ -242,25 +242,25 @@
     def close(self):
         try:
             self.fp.close()
-        except IOError:
+        except OSError:
             pass
 
     def write(self, s):
         try:
             return self.fp.write(s)
-        except IOError as inst:
+        except OSError as inst:
             if inst.errno != 0 and not win32.lasterrorwaspipeerror(inst):
                 raise
             self.close()
-            raise IOError(errno.EPIPE, 'Broken pipe')
+            raise OSError(errno.EPIPE, 'Broken pipe')
 
     def flush(self):
         try:
             return self.fp.flush()
-        except IOError as inst:
+        except OSError as inst:
             if not win32.lasterrorwaspipeerror(inst):
                 raise
-            raise IOError(errno.EPIPE, 'Broken pipe')
+            raise OSError(errno.EPIPE, 'Broken pipe')
 
 
 def openhardlinks() -> bool:
@@ -744,7 +744,7 @@
 
                 # never let a Unicode string escape into the wild
                 return encoding.unitolocal(val)
-        except EnvironmentError:
+        except OSError:
             pass
 
 
--- a/mercurial/wireprotov1server.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/mercurial/wireprotov1server.py	Sun Jan 05 21:03:17 2025 -0500
@@ -488,7 +488,7 @@
         repo.ui.debug(b'sending pullbundle "%s"\n' % path)
         try:
             return repo.vfs.open(path)
-        except IOError:
+        except OSError:
             repo.ui.debug(b'pullbundle "%s" not accessible\n' % path)
             continue
     return None
--- a/setup.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/setup.py	Sun Jan 05 21:03:17 2025 -0500
@@ -256,7 +256,7 @@
             res = (True, retcode, out, err)
             if retcode == 0 and not filterhgerr(err):
                 return True
-        except EnvironmentError as e:
+        except OSError as e:
             res = (False, e)
         attempts.append((cmd, res))
         return False
--- a/tests/hghave.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/hghave.py	Sun Jan 05 21:03:17 2025 -0500
@@ -252,7 +252,7 @@
         os.close(fd)
         os.remove(path)
         return True
-    except (IOError, OSError):
+    except OSError:
         return False
 
 
@@ -269,7 +269,7 @@
             exec_flags_cannot_flip = (os.stat(fn).st_mode & 0o777) == m
         finally:
             os.unlink(fn)
-    except (IOError, OSError):
+    except OSError:
         # we don't care, the user probably won't be able to commit anyway
         return False
     return not (new_file_has_exec or exec_flags_cannot_flip)
--- a/tests/killdaemons.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/killdaemons.py	Sun Jan 05 21:03:17 2025 -0500
@@ -123,7 +123,7 @@
             kill(pid, logfn, tryhard)
         if remove:
             os.unlink(pidfile)
-    except IOError:
+    except OSError:
         pass
 
 
--- a/tests/md5sum.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/md5sum.py	Sun Jan 05 21:03:17 2025 -0500
@@ -22,7 +22,7 @@
 for filename in sys.argv[1:]:
     try:
         fp = open(filename, 'rb')
-    except IOError as msg:
+    except OSError as msg:
         sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg))
         sys.exit(1)
 
@@ -30,7 +30,7 @@
     try:
         for data in iter(lambda: fp.read(8192), b''):
             m.update(data)
-    except IOError as msg:
+    except OSError 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))
--- a/tests/mockmakedate.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/mockmakedate.py	Sun Jan 05 21:03:17 2025 -0500
@@ -12,7 +12,7 @@
     try:
         with open(filename, 'rb') as timef:
             time = float(timef.read()) + 1
-    except IOError:
+    except OSError:
         time = 0.0
     with open(filename, 'wb') as timef:
         timef.write(pycompat.bytestr(time))
--- a/tests/run-tests.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/run-tests.py	Sun Jan 05 21:03:17 2025 -0500
@@ -292,7 +292,7 @@
         s.bind(('localhost', port))
         s.close()
         return True
-    except (socket.error, OSError) as exc:
+    except OSError as exc:
         if exc.errno == errno.EADDRINUSE:
             return True
         elif exc.errno in (
@@ -323,7 +323,7 @@
         return True
     except PermissionError:
         return False
-    except socket.error as exc:
+    except OSError as exc:
         if WINDOWS and exc.errno == errno.WSAEACCES:
             return False
         if exc.errno not in (
--- a/tests/test-stdio.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/test-stdio.py	Sun Jan 05 21:03:17 2025 -0500
@@ -88,7 +88,7 @@
         for fd in fds:
             try:
                 os.close(fd)
-            except EnvironmentError:
+            except OSError:
                 pass
 
 
--- a/tests/testlib/badserverext.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/testlib/badserverext.py	Sun Jan 05 21:03:17 2025 -0500
@@ -425,12 +425,12 @@
                 self.__shutdown_request = True
 
                 # Simulate failure to stop processing this request.
-                raise socket.error('close before accept')
+                raise OSError('close before accept')
 
             if self._ui.configbool(b'badserver', b'close-after-accept'):
                 request, client_address = super(badserver, self).get_request()
                 request.close()
-                raise socket.error('close after accept')
+                raise OSError('close after accept')
 
             return super(badserver, self).get_request()
 
--- a/tests/tinyproxy.py	Mon Jan 06 14:15:40 2025 -0500
+++ b/tests/tinyproxy.py	Sun Jan 05 21:03:17 2025 -0500
@@ -73,7 +73,7 @@
         print("\t" "connect to %s:%d" % host_port)
         try:
             soc.connect(host_port)
-        except socket.error as e:
+        except OSError as e:
             self.send_error(404, e.strerror)
             return 0
         return 1
@@ -149,7 +149,7 @@
                         out = soc
                     try:
                         data = i.recv(8192)
-                    except socket.error:
+                    except OSError:
                         break
                     if data:
                         out.send(data)