Mercurial > hg
diff hgext/convert/convcmd.py @ 51685:0eb515c7bec8
typing: add trivial type hints to the convert extension's common modules
This started as ensuring that the `encoding` and `orig_encoding` attributes has
a type other than `Any`, so pytype can catch problems where it needs to be str
for stdlib encoding and decoding. It turns out that adding the hint in
`mercurial.encoding` is what was needed, but I picked a bunch of low hanging
fruit while here. There's definitely more to do, and I see a problem where
`shlex.shlex` is being fed bytes instead of str, but there are not enough type
hints yet to make pytype notice.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Thu, 11 Jul 2024 20:54:06 -0400 |
parents | 8edfd28a01d1 |
children | 1eab9e40c0c8 |
line wrap: on
line diff
--- a/hgext/convert/convcmd.py Thu Jul 11 14:46:00 2024 -0400 +++ b/hgext/convert/convcmd.py Thu Jul 11 20:54:06 2024 -0400 @@ -9,6 +9,14 @@ import heapq import os import shutil +import typing + +from typing import ( + AnyStr, + Mapping, + Optional, + Union, +) from mercurial.i18n import _ from mercurial.pycompat import open @@ -36,6 +44,11 @@ subversion, ) +if typing.TYPE_CHECKING: + from mercurial import ( + ui as uimod, + ) + mapfile = common.mapfile MissingTool = common.MissingTool NoRepo = common.NoRepo @@ -53,10 +66,10 @@ svn_sink = subversion.svn_sink svn_source = subversion.svn_source -orig_encoding = b'ascii' +orig_encoding: bytes = b'ascii' -def readauthormap(ui, authorfile, authors=None): +def readauthormap(ui: "uimod.ui", authorfile, authors=None): if authors is None: authors = {} with open(authorfile, b'rb') as afile: @@ -86,7 +99,7 @@ return authors -def recode(s): +def recode(s: AnyStr) -> bytes: if isinstance(s, str): return s.encode(pycompat.sysstr(orig_encoding), 'replace') else: @@ -95,7 +108,7 @@ ) -def mapbranch(branch, branchmap): +def mapbranch(branch: bytes, branchmap: Mapping[bytes, bytes]) -> bytes: """ >>> bmap = {b'default': b'branch1'} >>> for i in [b'', None]: @@ -147,7 +160,7 @@ ] -def convertsource(ui, path, type, revs): +def convertsource(ui: "uimod.ui", path: bytes, type: bytes, revs): exceptions = [] if type and type not in [s[0] for s in source_converters]: raise error.Abort(_(b'%s: invalid source repository type') % type) @@ -163,7 +176,9 @@ raise error.Abort(_(b'%s: missing or unsupported repository') % path) -def convertsink(ui, path, type): +def convertsink( + ui: "uimod.ui", path: bytes, type: bytes +) -> Union[hgconvert.mercurial_sink, subversion.svn_sink]: if type and type not in [s[0] for s in sink_converters]: raise error.Abort(_(b'%s: invalid destination repository type') % type) for name, sink in sink_converters: @@ -178,7 +193,9 @@ class progresssource: - def __init__(self, ui, source, filecount): + def __init__( + self, ui: "uimod.ui", source, filecount: Optional[int] + ) -> None: self.ui = ui self.source = source self.progress = ui.makeprogress( @@ -253,7 +270,7 @@ class converter: - def __init__(self, ui, source, dest, revmapfile, opts): + def __init__(self, ui: "uimod.ui", source, dest, revmapfile, opts) -> None: self.source = source self.dest = dest @@ -280,7 +297,7 @@ self.splicemap = self.parsesplicemap(opts.get(b'splicemap')) self.branchmap = mapfile(ui, opts.get(b'branchmap')) - def parsesplicemap(self, path): + def parsesplicemap(self, path: bytes): """check and validate the splicemap format and return a child/parents dictionary. Format checking has two parts. @@ -356,7 +373,7 @@ return parents - def mergesplicemap(self, parents, splicemap): + def mergesplicemap(self, parents, splicemap) -> None: """A splicemap redefines child/parent relationships. Check the map contains valid revision identifiers and merge the new links in the source graph. @@ -488,7 +505,7 @@ return s - def writeauthormap(self): + def writeauthormap(self) -> None: authorfile = self.authorfile if authorfile: self.ui.status(_(b'writing author map file %s\n') % authorfile) @@ -501,7 +518,7 @@ ) ofile.close() - def readauthormap(self, authorfile): + def readauthormap(self, authorfile) -> None: self.authors = readauthormap(self.ui, authorfile, self.authors) def cachecommit(self, rev): @@ -511,7 +528,7 @@ self.commitcache[rev] = commit return commit - def copy(self, rev): + def copy(self, rev) -> None: commit = self.commitcache[rev] full = self.opts.get(b'full') changes = self.source.getchanges(rev, full) @@ -563,7 +580,7 @@ self.source.converted(rev, newnode) self.map[rev] = newnode - def convert(self, sortmode): + def convert(self, sortmode) -> None: try: self.source.before() self.dest.before() @@ -628,7 +645,7 @@ finally: self.cleanup() - def cleanup(self): + def cleanup(self) -> None: try: self.dest.after() finally: @@ -636,7 +653,9 @@ self.map.close() -def convert(ui, src, dest=None, revmapfile=None, **opts): +def convert( + ui: "uimod.ui", src, dest: Optional[bytes] = None, revmapfile=None, **opts +) -> None: opts = pycompat.byteskwargs(opts) global orig_encoding orig_encoding = encoding.encoding