Mercurial > public > mercurial-scm > hg-stable
changeset 52913:6ee3c401882b
vfs: avoid passing None to `shutil.rmtree()` for the exception handler
Even though the code looks like it will handle it, pytype 2024.10.11 complains.
So the simplest thing to do is pass along a no-op function that it would use
internally if it was explicitly provided None.
The specific error was:
/home/mharbison/projects/mercurial/mercurial-devel/mercurial/vfs.py:360:20:
error: in rmtree: Function _RmtreeType.__call__ was called with the wrong arguments [wrong-arg-types]
Expected: (self, path, ignore_errors, *, dir_fd, onexc: Callable[[Callable, str, Exception], object])
Actually passed: (self, path, ignore_errors, onexc: Optional[Callable[[Any, bytes, Any], Any]])
Attributes of protocol Callable[[Callable, str, Exception], object] are not implemented on None: __call__
return shutil.rmtree(
~~~~~~~~~~~~~~
self.join(path), ignore_errors=ignore_errors, onexc=onexc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
)
~~~~~~~~~~~~~
Note that it expects a str on the callback. I thought maybe there would be an
@overload, and it could handle both. But looking at the code in Python 3.11,
they call `os.fsdecode(path)` on some platforms when given bytes, and pass that
str to the callback. So adjust the typehint accordingly, and leave a note.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Tue, 11 Feb 2025 22:44:21 -0500 |
parents | 0fd4b2af347b |
children | 3e8a3db5f5e8 |
files | mercurial/vfs.py |
diffstat | 1 files changed, 9 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/vfs.py Thu Feb 13 11:40:56 2025 -0500 +++ b/mercurial/vfs.py Tue Feb 11 22:44:21 2025 -0500 @@ -343,7 +343,11 @@ """ if forcibly: - def onexc(function, path: bytes, excinfo): + def onexc(function: Callable, path: str, excinfo: Exception): + # Note: str is passed here even if bytes are passed to rmtree + # on platforms where `shutil._use_fd_functions == True`. It is + # bytes otherwise. Fortunately, the methods used here accept + # both. if function is not os.remove: raise # read-only files cannot be unlinked under Windows @@ -354,7 +358,10 @@ os.remove(path) else: - onexc = None + + def onexc(*args): + pass + try: # pytype: disable=wrong-keyword-args return shutil.rmtree(