Mercurial > public > mercurial-scm > hg-stable
diff mercurial/cmdutil.py @ 52629:89215c5b714c
cmdutil: switch the `mode` on `cmdutil.makefileobj()` to str
I think the typing around whether `open()` returns `IO[bytes]` or `IO[str]`
hinges on the content of the mode string. Converting from bytes instead of
using a literal can suppress that (though PyCharm currently complains about
this). Instead, we can mandate the use of a (vastly reduced) set of mode
options. For now, none of the 3 callers provide this argument, so it's not a
big deal. Ideally, this would always enforce binary mode.
There's a little extra typing required to pull this off. The `_unclosablefile`
class can't subclass `typing.BinaryIO`, because there were a bunch of test
failures around writing to stdout. Strangely, pytype didn't complain that the
abstract methods on `typing.BinaryIO` weren't overridden in this case. Whatever
was going on, it's a simple proxy class, so we can just cast to the expected
type in the one place it is used.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Mon, 16 Dec 2024 21:50:24 -0500 |
parents | 9d79ffeed7c0 |
children | 24ee91ba9aa8 |
line wrap: on
line diff
--- a/mercurial/cmdutil.py Tue Dec 31 22:36:56 2024 -0500 +++ b/mercurial/cmdutil.py Mon Dec 16 21:50:24 2024 -0500 @@ -17,8 +17,10 @@ from typing import ( Any, AnyStr, + BinaryIO, Dict, Iterable, + Literal, Optional, TYPE_CHECKING, cast, @@ -1360,7 +1362,7 @@ return b''.join(newname) -def makefilename(ctx, pat, **props): +def makefilename(ctx, pat: bytes, **props): if not pat: return pat tmpl = _buildfntemplate(pat, **props) @@ -1376,7 +1378,7 @@ class _unclosablefile: - def __init__(self, fp): + def __init__(self, fp: BinaryIO) -> None: self._fp = fp def close(self): @@ -1395,8 +1397,10 @@ pass -def makefileobj(ctx, pat, mode=b'wb', **props): - writable = mode not in (b'r', b'rb') +def makefileobj( + ctx, pat: bytes, mode: Literal['rb', 'wb'] = 'wb', **props +) -> BinaryIO: + writable = mode not in ('r', 'rb') if isstdiofilename(pat): repo = ctx.repo() @@ -1404,9 +1408,9 @@ fp = repo.ui.fout else: fp = repo.ui.fin - return _unclosablefile(fp) + return typing.cast(BinaryIO, _unclosablefile(fp)) fn = makefilename(ctx, pat, **props) - return open(fn, pycompat.sysstr(mode)) + return open(fn, mode) def openstorage(repo, cmd, file_, opts, returnrevlog=False):