Skip to content

Commit

Permalink
minstall: help mypy out with our chown overriding
Browse files Browse the repository at this point in the history
This is an annoying issue to look at, because shutil.chown has (for our
purposes) two signatures:
```python
chown(path: int | AnyPathLike, uid: int | str, group: None = None) -> None: ...
chown(path: int | AnyPathLike, uid: None, group: int | str) -> None: ...
```

This is a really difficult thing to guarantee from our code. We more or
less depend on being able to pass two parameters of `None | int | str`,
and it working. In our only caller we do ensure that at least one of the
variables is not None, but convincing mypy of this is more work than
it's worth.
  • Loading branch information
dcbaker committed Feb 3, 2025
1 parent b825fae commit 418dcc5
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions mesonbuild/minstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ def append_to_log(lf: T.TextIO, line: str) -> None:
lf.write('\n')
lf.flush()


def set_chown(path: str, user: T.Union[str, int, None] = None,
group: T.Union[str, int, None] = None,
dir_fd: T.Optional[int] = None, follow_symlinks: bool = True) -> None:
Expand All @@ -150,10 +149,22 @@ def set_chown(path: str, user: T.Union[str, int, None] = None,
# Not nice, but better than actually rewriting shutil.chown until
# this python bug is fixed: https://bugs.python.org/issue18108

# This is checked by the only (current) caller, but let's be sure
assert user is not None or group is not None, 'ensure that calls to chown are valid'

# This is running into a problem where this may not match any of signatures
# of `shtil.chown`, which (simplified) are:
# chown(path: int | AnyPath, user: int | str, group: None = None)
# chown(path: int | AnyPath, user: None, group: int | str)
# We cannot through easy coercion of the type system force it to say:
# - user is non null and group is null
# - user is null and group is non null
# - user is non null and group is non null

if sys.version_info >= (3, 13):
# pylint: disable=unexpected-keyword-arg
# cannot handle sys.version_info, https://github.com/pylint-dev/pylint/issues/9622
shutil.chown(path, user, group, dir_fd=dir_fd, follow_symlinks=follow_symlinks)
shutil.chown(path, user, group, dir_fd=dir_fd, follow_symlinks=follow_symlinks) # type: ignore[call-overload]
else:
real_os_chown = os.chown

Expand All @@ -169,7 +180,7 @@ def chown(path: T.Union[int, str, 'os.PathLike[str]', bytes, 'os.PathLike[bytes]

try:
os.chown = chown
shutil.chown(path, user, group)
shutil.chown(path, user, group) # type: ignore[call-overload]
finally:
os.chown = real_os_chown

Expand Down

0 comments on commit 418dcc5

Please sign in to comment.