D7515: pytype: [WIP] suppress various warnings inline to get a clean run

mharbison72 (Matt Harbison) phabricator at mercurial-scm.org
Tue Dec 17 12:47:44 EST 2019


mharbison72 edited the summary of this revision.
mharbison72 updated this revision to Diff 18818.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7515?vs=18368&id=18818

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7515/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7515

AFFECTED FILES
  mercurial/bundlerepo.py
  mercurial/commands.py
  mercurial/dagparser.py
  mercurial/debugcommands.py
  mercurial/error.py
  mercurial/exchange.py
  mercurial/hg.py
  mercurial/hgweb/server.py
  mercurial/hgweb/webcommands.py
  mercurial/manifest.py
  mercurial/namespaces.py
  mercurial/obsutil.py
  mercurial/patch.py
  mercurial/profiling.py
  mercurial/pycompat.py
  mercurial/shelve.py
  mercurial/subrepo.py
  mercurial/ui.py
  mercurial/unionrepo.py
  mercurial/upgrade.py
  mercurial/util.py
  mercurial/verify.py
  mercurial/wireprotoframing.py
  mercurial/wireprotoserver.py
  mercurial/wireprotov1peer.py
  mercurial/wireprotov1server.py
  mercurial/wireprotov2server.py
  tests/test-check-pytype.t

CHANGE DETAILS

diff --git a/tests/test-check-pytype.t b/tests/test-check-pytype.t
--- a/tests/test-check-pytype.t
+++ b/tests/test-check-pytype.t
@@ -9,25 +9,16 @@
 endeavor to empty this list out over time, as some of these are
 probably hiding real problems.
 
-
-  $ pytype mercurial \
-  >    -x mercurial/bundlerepo.py \
+  $ pytype -k mercurial \
   >    -x mercurial/chgserver.py \
   >    -x mercurial/context.py \
   >    -x mercurial/crecord.py \
   >    -x mercurial/encoding.py \
-  >    -x mercurial/error.py \
-  >    -x mercurial/exchange.py \
   >    -x mercurial/lsprof.py \
-  >    -x mercurial/policy.py
-  >    -x mercurial/pycompat.py \
   >    -x mercurial/urllibcompat.py \
   >    -x mercurial/i18n.py \
   >    -x mercurial/sslutil.py \
-  >    -x mercurial/scmwindows.py \
   >    -x mercurial/keepalive.py \
-  >    -x mercurial/windows.py \
-  >    -x mercurial/wireprotoframing.py \
   >    -x mercurial/utils/stringutil.py \
   >    -x mercurial/hgweb/server.py \
   >    -x mercurial/hgweb/wsgicgi.py \
@@ -35,4 +26,10 @@
   >    -x mercurial/interfaces \
   >    -x mercurial/cffi \
   >    -x mercurial/pure \
-  >    -x mercurial/thirdparty
+  >    -x mercurial/thirdparty \
+  >    -x mercurial/httppeer.py \
+  >    -x mercurial/repoview.py \
+  >    -x mercurial/localrepo.py \
+  >    -x mercurial/revlog.py \
+  >    -x mercurial/merge.py \
+  >    -x mercurial/testing/storage.py
diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py
--- a/mercurial/wireprotov2server.py
+++ b/mercurial/wireprotov2server.py
@@ -88,7 +88,12 @@
     try:
         checkperm(rctx, req, b'pull' if permission == b'ro' else b'push')
     except hgwebcommon.ErrorResponse as e:
-        res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
+        # line 91, in handlehttpv2request: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: mercurial.hgweb.common.ErrorResponse)
+        # +    The following methods aren't implemented on mercurial.hgweb.common.ErrorResponse:
+        # +    __iter__
+        res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))  # pytype: disable=wrong-arg-types
         for k, v in e.headers:
             res.headers[k] = v
         res.setbodybytes(b'permission denied')
@@ -582,7 +587,9 @@
 
         caps[b'commands'][command] = {
             b'args': args,
-            b'permissions': [entry.permission],
+            # line 585, in _capabilitiesv2: unsupported operand type(s) for item assignment: 'Set[bytes]' [unsupported-operands]
+            # +    No attribute '__setitem__' on Set[bytes]
+            b'permissions': [entry.permission],  # pytype: disable=unsupported-operands
         }
 
         if entry.extracapabilitiesfn:
@@ -609,7 +616,11 @@
                 if key in target:
                     entry[key] = target[key]
 
-            caps[b'redirect'][b'targets'].append(entry)
+            # line 612, in _capabilitiesv2: No attribute 'append' on dict [attribute-error]
+            # +    In Union[List[bytes], List[nothing], dict]
+            # +  Called from (traceback):
+            # +    line 544, in httpv2apidescriptor
+            caps[b'redirect'][b'targets'].append(entry)  # pytype: disable=attribute-error
 
     return proto.addcapabilities(repo, caps)
 
diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py
--- a/mercurial/wireprotov1server.py
+++ b/mercurial/wireprotov1server.py
@@ -726,12 +726,17 @@
                         part.addparam(b'old', exc.old, mandatory=False)
                     if exc.ret is not None:
                         part.addparam(b'ret', exc.ret, mandatory=False)
-            except error.BundleValueError as exc:
+            except error.BundleValueError as exc:  # Should be BundleUnknownFeatureError
                 errpart = bundler.newpart(b'error:unsupportedcontent')
-                if exc.parttype is not None:
-                    errpart.addparam(b'parttype', exc.parttype)
-                if exc.params:
-                    errpart.addparam(b'params', b'\0'.join(exc.params))
+                # TODO: These are bugs!
+                # line 731, in unbundle: No attribute 'parttype' on mercurial.error.BundleValueError [attribute-error]
+                if exc.parttype is not None:  # pytype: disable=attribute-error
+                    # line 732, in unbundle: No attribute 'parttype' on mercurial.error.BundleValueError [attribute-error]
+                    errpart.addparam(b'parttype', exc.parttype)  # pytype: disable=attribute-error
+                # line 733, in unbundle: No attribute 'params' on mercurial.error.BundleValueError [attribute-error]
+                if exc.params:  # pytype: disable=attribute-error
+                    # line 734, in unbundle: No attribute 'params' on mercurial.error.BundleValueError [attribute-error]
+                    errpart.addparam(b'params', b'\0'.join(exc.params))  # pytype: disable=attribute-error
             except error.Abort as exc:
                 manargs = [(b'message', stringutil.forcebytestr(exc))]
                 advargs = []
diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py
--- a/mercurial/wireprotov1peer.py
+++ b/mercurial/wireprotov1peer.py
@@ -60,12 +60,19 @@
 
     def plain(*args, **opts):
         batchable = f(*args, **opts)
-        encargsorres, encresref = next(batchable)
+        # line 63, in plain: No attribute '__iter__' on bool [attribute-error]
+        encargsorres, encresref = next(batchable)  # pytype: disable=attribute-error
         if not encresref:
             return encargsorres  # a local result in this case
         self = args[0]
         cmd = pycompat.bytesurl(f.__name__)  # ensure cmd is ascii bytestr
-        encresref.set(self._submitone(cmd, encargsorres))
+        # line 68, in plain: No attribute 'set' on bytes [attribute-error]
+        # +    In Union[bytes, future]
+        # line 68, in plain: No attribute 'set' on bytes [attribute-error]
+        # +    In Optional[Union[bytes, future]]
+        # line 68, in plain: No attribute 'set' on int [attribute-error]
+        # +    In Union[future, int]
+        encresref.set(self._submitone(cmd, encargsorres))  # pytype: disable=attribute-error
         return next(batchable)
 
     setattr(plain, 'batchable', f)
@@ -360,7 +367,10 @@
         self.requirecap(b'lookup', _(b'look up remote revision'))
         f = future()
         yield {b'key': encoding.fromlocal(key)}, f
-        d = f.value
+        # line 363, in lookup: No attribute 'value' on future [attribute-error]
+        # +  Called from (traceback):
+        # +    line 62, in plain
+        d = f.value  # pytype: disable=attribute-error
         success, data = d[:-1].split(b" ", 1)
         if int(success):
             yield bin(data)
@@ -371,7 +381,10 @@
     def heads(self):
         f = future()
         yield {}, f
-        d = f.value
+        # line 374, in heads: No attribute 'value' on future [attribute-error]
+        # +  Called from (traceback):
+        # +    line 62, in plain
+        d = f.value  # pytype: disable=attribute-error
         try:
             yield wireprototypes.decodelist(d[:-1])
         except ValueError:
@@ -381,7 +394,10 @@
     def known(self, nodes):
         f = future()
         yield {b'nodes': wireprototypes.encodelist(nodes)}, f
-        d = f.value
+        # line 384, in known: No attribute 'value' on future [attribute-error]
+        # +  Called from (traceback):
+        # +    line 62, in plain
+        d = f.value  # pytype: disable=attribute-error
         try:
             yield [bool(int(b)) for b in pycompat.iterbytestr(d)]
         except ValueError:
@@ -391,7 +407,10 @@
     def branchmap(self):
         f = future()
         yield {}, f
-        d = f.value
+        # line 394, in branchmap: No attribute 'value' on future [attribute-error]
+        # +  Called from (traceback):
+        # +    line 62, in plain
+        d = f.value  # pytype: disable=attribute-error
         try:
             branchmap = {}
             for branchpart in d.splitlines():
@@ -410,7 +429,10 @@
         f = future()
         self.ui.debug(b'preparing listkeys for "%s"\n' % namespace)
         yield {b'namespace': encoding.fromlocal(namespace)}, f
-        d = f.value
+        # line 413, in listkeys: No attribute 'value' on future [attribute-error]
+        # +  Called from (traceback):
+        # +    line 62, in plain
+        d = f.value  # pytype: disable=attribute-error
         self.ui.debug(
             b'received listkey for "%s": %i bytes\n' % (namespace, len(d))
         )
@@ -428,7 +450,10 @@
             b'old': encoding.fromlocal(old),
             b'new': encoding.fromlocal(new),
         }, f
-        d = f.value
+        # line 431, in pushkey: No attribute 'value' on future [attribute-error]
+        # +  Called from (traceback):
+        # +    line 62, in plain
+        d = f.value  # pytype: disable=attribute-error
         d, output = d.split(b'\n', 1)
         try:
             d = bool(int(d))
diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -234,10 +234,21 @@
     except hgwebcommon.ErrorResponse as e:
         for k, v in e.headers:
             res.headers[k] = v
-        res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
+        # line 237, in handlewsgirequest: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: mercurial.hgweb.common.ErrorResponse)
+        # +    The following methods aren't implemented on mercurial.hgweb.common.ErrorResponse:
+        # +    __iter__
+        res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))  # pytype: disable=wrong-arg-types
         # TODO This response body assumes the failed command was
         # "unbundle." That assumption is not always valid.
-        res.setbodybytes(b'0\n%s\n' % pycompat.bytestr(e))
+
+        # line 240, in handlewsgirequest: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: mercurial.hgweb.common.ErrorResponse)
+        # +    The following methods aren't implemented on mercurial.hgweb.common.ErrorResponse:
+        # +    __iter__
+        res.setbodybytes(b'0\n%s\n' % pycompat.bytestr(e))  # pytype: disable=wrong-arg-types
 
     return True
 
@@ -248,7 +259,11 @@
     # Registered APIs are made available via config options of the name of
     # the protocol.
     for k, v in API_HANDLERS.items():
-        section, option = v[b'config']
+        # line 251, in _availableapis: No attribute '__iter__' on Callable[[Any, Any, Any, Any, Any], None] [attribute-error]
+        # +    In Union[Callable[[Any, Any, Any, Any, Any], None], Callable[[Any, Any], Any]]
+        # line 251, in _availableapis: No attribute '__iter__' on Callable[[Any, Any], Any] [attribute-error]
+        # +    In Union[Callable[[Any, Any, Any, Any, Any], None], Callable[[Any, Any], Any]]
+        section, option = v[b'config']  # pytype: disable=attribute-error
         if repo.ui.configbool(section, option):
             apis.add(k)
 
diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py
--- a/mercurial/wireprotoframing.py
+++ b/mercurial/wireprotoframing.py
@@ -468,7 +468,13 @@
     ):
         value = getattr(location, a)
         if value is not None:
-            data[b'location'][pycompat.bytestr(a)] = value
+            # line 471, in createalternatelocationresponseframe: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+            # +    Expected: (self, ints: Iterable[int])
+            # +    Actually passed: (self, ints: str)
+            # line 471, in createalternatelocationresponseframe: unsupported operand type(s) for item assignment: 'bytes' [unsupported-operands]
+            # +    No attribute '__setitem__' on bytes
+            data[b'location'][pycompat.bytestr(a
+            )] = value  # pytype: disable=unsupported-operands,wrong-arg-types
 
     payload = b''.join(cborutil.streamencode(data))
 
@@ -493,7 +499,9 @@
     m = {b'status': b'error', b'error': {b'message': message,}}
 
     if args:
-        m[b'error'][b'args'] = args
+        # line 496, in createcommanderrorresponse: unsupported operand type(s) for item assignment: 'bytes' [unsupported-operands]
+        # +    No attribute '__setitem__' on bytes
+        m[b'error'][b'args'] = args  # pytype: disable=unsupported-operands
 
     overall = b''.join(cborutil.streamencode(m))
 
@@ -759,7 +767,8 @@
 
 class zstdbaseencoder(object):
     def __init__(self, level):
-        from . import zstd
+        # line 762, in __init__: Can't find module 'mercurial.zstd'. [import-error]
+        from . import zstd  # pytype: disable=import-error
 
         self._zstd = zstd
         cctx = zstd.ZstdCompressor(level=level)
@@ -787,7 +796,8 @@
 
 class zstdbasedecoder(object):
     def __init__(self, maxwindowsize):
-        from . import zstd
+        # line 790, in __init__: Can't find module 'mercurial.zstd'. [import-error]
+        from . import zstd  # pytype: disable=import-error
 
         dctx = zstd.ZstdDecompressor(max_window_size=maxwindowsize)
         self._decompressor = dctx.decompressobj()
@@ -817,7 +827,8 @@
         return
 
     try:
-        from . import zstd
+        # line 820, in populatestreamencoders: Can't find module 'mercurial.zstd'. [import-error]
+        from . import zstd  # pytype: disable=import-error
 
         zstd.__version__
     except ImportError:
@@ -1370,8 +1381,17 @@
             self._state = b'idle'
 
         # Decode the payloads as CBOR.
-        entry[b'payload'].seek(0)
-        request = cborutil.decodeall(entry[b'payload'].getvalue())[0]
+        # line 1373, in _makeruncommandresult: No attribute 'seek' on bool [attribute-error]
+        # +    In Optional[Union[bool, io.BytesIO]]
+        # +  Called from (traceback):
+        # +    line 1568, in _onframeidle
+        entry[b'payload'].seek(0)  # pytype: disable=attribute-error
+
+        # line 1374, in _makeruncommandresult: No attribute 'getvalue' on bool [attribute-error]
+        # +    In Optional[Union[bool, io.BytesIO]]
+        # +  Called from (traceback):
+        # +    line 1568, in _onframeidle
+        request = cborutil.decodeall(entry[b'payload'].getvalue())[0]  # pytype: disable=attribute-error
 
         if b'name' not in request:
             self._state = b'errored'
@@ -1392,7 +1412,11 @@
                 b'command': request[b'name'],
                 b'args': request[b'args'],
                 b'redirect': request.get(b'redirect'),
-                b'data': entry[b'data'].getvalue() if entry[b'data'] else None,
+                # line 1395, in _makeruncommandresult: No attribute 'getvalue' on bool [attribute-error]
+                # +    In Optional[Union[bool, io.BytesIO]]
+                # +  Called from (traceback):
+                # +    line 1568, in _onframeidle
+                b'data': entry[b'data'].getvalue() if entry[b'data'] else None,  # pytype: disable=attribute-error
             },
         )
 
@@ -1618,7 +1642,15 @@
                     _(b'mismatch between expect data flag and previous frame')
                 )
 
-            entry[b'payload'].write(frame.payload)
+            # line 1621, in _onframecommandreceiving: No attribute 'write' on bool [attribute-error]
+            # +    In Optional[Union[bool, io.BytesIO]]
+            # +  Called from (traceback):
+            # +    line 1135, in onframerecv
+            # line 1621, in _onframecommandreceiving: No attribute 'write' on None [attribute-error]
+            # +    In Optional[Union[bool, io.BytesIO]]
+            # +  Called from (traceback):
+            # +    line 1135, in onframerecv
+            entry[b'payload'].write(frame.payload)  # pytype: disable=attribute-error
 
             if not moreframes:
                 entry[b'requestdone'] = True
diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -81,7 +81,28 @@
 
     def _exc(self, linkrev, msg, inst, filename=None):
         """record exception raised during the verify process"""
-        fmsg = pycompat.bytestr(inst)
+        # line 84, in _exc: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: Exception)
+        # +    The following methods aren't implemented on Exception:
+        # +    __iter__
+        # +  Called from (traceback):
+        # +    line 172, in _checkentry
+        # line 84, in _exc: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: Exception)
+        # +    The following methods aren't implemented on Exception:
+        # +    __iter__
+        # +  Called from (traceback):
+        # +    line 275, in _verifychangelog
+        # line 84, in _exc: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: Exception)
+        # +    The following methods aren't implemented on Exception:
+        # +    __iter__
+        # +  Called from (traceback):
+        # +    line 606, in _verifyfiles
+        fmsg = pycompat.bytestr(inst)  # pytype: disable=wrong-arg-types
         if not fmsg:
             fmsg = pycompat.byterepr(inst)
         self._err(linkrev, b"%s: %s" % (msg, fmsg), filename)
@@ -431,7 +452,11 @@
                 filenodes.setdefault(f, {}).update(onefilenodes)
 
         if not dir and subdirnodes:
-            subdirprogress.complete()
+            # line 434, in _verifymanifest: No attribute 'complete' on None [attribute-error]
+            # +    In Optional[Any]
+            # +  Called from (traceback):
+            # +    line 202, in verify
+            subdirprogress.complete()  # pytype: disable=attribute-error
             if self.warnorphanstorefiles:
                 for f in sorted(storefiles):
                     self._warn(_(b"warning: orphan data file '%s'") % f)
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -293,7 +293,8 @@
 
 
 try:
-    buffer = buffer
+    # Name 'buffer' is not defined [name-error]
+    buffer = buffer  # pytype: disable=name-error
 except NameError:
 
     def buffer(sliceable, offset=0, length=None):
@@ -1234,7 +1235,10 @@
         """call this before writes, return self or a copied new object"""
         if getattr(self, '_copied', 0):
             self._copied -= 1
-            return self.__class__(self)
+            # Function cow.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+            #     Expected: (self)
+            #     Actually passed: (self, _)
+            return self.__class__(self)  # pytype: disable=wrong-arg-count
         return self
 
     def copy(self):
diff --git a/mercurial/upgrade.py b/mercurial/upgrade.py
--- a/mercurial/upgrade.py
+++ b/mercurial/upgrade.py
@@ -818,7 +818,12 @@
     progress = None
 
     def oncopiedrevision(rl, rev, node):
-        progress.increment()
+        # XXX: It looks like there is no `else` where this is set, and it ends
+        #      up calling progress.complete() at the end of the loop (not
+        #      detected).
+        # line 821, in oncopiedrevision: No attribute 'increment' on None [attribute-error]
+        # +    In Optional[Any]
+        progress.increment()  # pytype: disable=attribute-error
 
     sidedatacompanion = getsidedatacompanion(srcrepo, dstrepo)
 
diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py
--- a/mercurial/unionrepo.py
+++ b/mercurial/unionrepo.py
@@ -194,7 +194,8 @@
         self.repo2 = repo2
         self._url = url
 
-        self.ui.setconfig(b'phases', b'publish', False, b'unionrepo')
+        # in __init__: No attribute 'ui' on unionrepository [attribute-error]
+        self.ui.setconfig(b'phases', b'publish', False, b'unionrepo')  # pytype: disable=attribute-error
 
     @localrepo.unfilteredpropertycache
     def changelog(self):
@@ -219,7 +220,13 @@
 
     def file(self, f):
         return unionfilelog(
-            self.svfs, f, self.repo2.svfs, self.unfiltered()._clrev, self
+            # line 222, in file: No attribute 'svfs' on unionrepository [attribute-error]
+            # line 222, in file: No attribute 'unfiltered' on unionrepository [attribute-error]
+            self.svfs,  # pytype: disable=attribute-error
+            f,
+            self.repo2.svfs,
+            self.unfiltered()._clrev,  # pytype: disable=attribute-error
+            self
         )
 
     def close(self):
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -1627,8 +1627,12 @@
         # choices containing spaces, ASCII, or basically anything
         # except an ampersand followed by a character.
         m = re.match(br'(?s)(.+?)\$\$([^\$]*&[^ \$].*)', prompt)
-        msg = m.group(1)
-        choices = [p.strip(b' ') for p in m.group(2).split(b'$$')]
+        # line 1630, in extractchoices: No attribute 'group' on None [attribute-error]
+        # +    In Optional[Match[bytes]]
+        msg = m.group(1)  # pytype: disable=attribute-error
+        # line 1631, in extractchoices: No attribute 'group' on None [attribute-error]
+        # +    In Optional[Match[bytes]]
+        choices = [p.strip(b' ') for p in m.group(2).split(b'$$')]  # pytype: disable=attribute-error
 
         def choicetuple(s):
             ampidx = s.index(b'&')
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -1874,7 +1874,9 @@
             if info.issym():
                 data = info.linkname
             else:
-                data = tar.extractfile(info).read()
+                # line 1866, in archive: No attribute 'read' on None [attribute-error]
+                # +    In Optional[IO[bytes]]
+                data = tar.extractfile(info).read()  # pytype: disable=attribute-error
             archiver.addfile(prefix + bname, info.mode, info.issym(), data)
             total += 1
             progress.increment()
diff --git a/mercurial/shelve.py b/mercurial/shelve.py
--- a/mercurial/shelve.py
+++ b/mercurial/shelve.py
@@ -202,7 +202,10 @@
                 nodemod.bin(h) for h in d[b'nodestoremove'].split(b' ')
             ]
         except (ValueError, TypeError, KeyError) as err:
-            raise error.CorruptedState(pycompat.bytestr(err))
+            # line 205, in _verifyandtransform: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+            # +    Expected: (self, ints: Iterable[int])
+            # +    Actually passed: (self, ints: Union[KeyError, TypeError, ValueError])
+            raise error.CorruptedState(pycompat.bytestr(err))  # pytype: disable=wrong-arg-types
 
     @classmethod
     def _getversion(cls, repo):
@@ -211,7 +214,12 @@
         try:
             version = int(fp.readline().strip())
         except ValueError as err:
-            raise error.CorruptedState(pycompat.bytestr(err))
+            # line 214, in _getversion: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+            # +    Expected: (self, ints: Iterable[int])
+            # +    Actually passed: (self, ints: ValueError)
+            # +    The following methods aren't implemented on ValueError:
+            # +    __iter__
+            raise error.CorruptedState(pycompat.bytestr(err))  # pytype: disable=wrong-arg-types
         finally:
             fp.close()
         return version
diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -296,7 +296,10 @@
     def _wrapattrfunc(f):
         @functools.wraps(f)
         def w(object, name, *args):
-            return f(object, sysstr(name), *args)
+            # Function builtins.delattr expects 2 arg(s), got 3 [wrong-arg-count]
+            #      Expected: (object, name)
+            #      Actually passed: (object, name, _)
+            return f(object, sysstr(name), *args)  # pytype: disable=wrong-arg-count
 
         return w
 
diff --git a/mercurial/profiling.py b/mercurial/profiling.py
--- a/mercurial/profiling.py
+++ b/mercurial/profiling.py
@@ -269,7 +269,9 @@
                 exception_type, exception_value, traceback
             )
             if self._output == b'blackbox':
-                val = b'Profile:\n%s' % self._fp.getvalue()
+                # line 274, in __exit__: No attribute 'getvalue' on IO[Union[bytes, str]] [attribute-error]
+                # +    In Union[Any, IO[Union[bytes, str]], io.BytesIO]
+                val = b'Profile:\n%s' % self._fp.getvalue()  # pytype: disable=attribute-error
                 # ui.log treats the input as a format string,
                 # so we need to escape any % signs.
                 val = val.replace(b'%', b'%%')
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -106,7 +106,10 @@
     def mimesplit(stream, cur):
         def msgfp(m):
             fp = stringio()
-            g = mail.Generator(fp, mangle_from_=False)
+            # Function Generator.__init__ was called with the wrong arguments [wrong-arg-types]
+            #     Expected: (self, outfp: TextIO, ...)
+            #     Actually passed: (self, outfp: io.BytesIO, ...)
+            g = mail.Generator(fp, mangle_from_=False)  # pytype: disable=wrong-arg-types
             g.flatten(m)
             fp.seek(0)
             return fp
@@ -273,7 +276,10 @@
     ok_types = (b'text/plain', b'text/x-diff', b'text/x-patch')
     message = b''
     for part in msg.walk():
-        content_type = pycompat.bytestr(part.get_content_type())
+        # line 279, in _extract: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: str)
+        content_type = pycompat.bytestr(part.get_content_type())  # pytype: disable=wrong-arg-types
         ui.debug(b'Content-Type: %s\n' % content_type)
         if content_type not in ok_types:
             continue
diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -800,7 +800,9 @@
 
     values = []
     for sset in fullsuccessorsets:
-        values.append({b'successors': sset, b'markers': sset.markers})
+        # line 803, in successorsandmarkers: No attribute 'markers' on List[nothing] [attribute-error]
+        # +    In Union[Any, List[nothing], _succs]
+        values.append({b'successors': sset, b'markers': sset.markers})  # pytype: disable=attribute-error
 
     return values
 
diff --git a/mercurial/namespaces.py b/mercurial/namespaces.py
--- a/mercurial/namespaces.py
+++ b/mercurial/namespaces.py
@@ -97,7 +97,9 @@
 
         """
         if order is not None:
-            self._names.insert(order, namespace.name, namespace)
+            # XXX: This is a bug!
+            # No attribute 'insert' on mercurial.util.sortdict [attribute-error]
+            self._names.insert(order, namespace.name, namespace)  # pytype: disable=attribute-error
         else:
             self._names[namespace.name] = namespace
 
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -125,7 +125,9 @@
 def unhexlify(data, extra, pos, length):
     s = bin(data[pos : pos + length])
     if extra:
-        s += chr(extra & 0xFF)
+        # line 128, in unhexlify: unsupported operand type(s) for +: 'bytes' and 'str' [unsupported-operands]
+        # +    Function __add__ on bytes expects bytes
+        s += chr(extra & 0xFF)  # pytype: disable=unsupported-operands
     return s
 
 
@@ -1628,8 +1630,25 @@
             _checkforbidden(added)
             # combine the changed lists into one sorted iterator
             work = heapq.merge(
-                [(x, False) for x in sorted(added)],
-                [(x, True) for x in sorted(removed)],
+                # line 1631, in add: Built-in function sorted was called with the wrong arguments [wrong-arg-types]
+                # +    Expected: (iterable: Iterable, ...)
+                # +    Actually passed: (iterable: None)
+                # +    The following methods aren't implemented on None:
+                # +    __iter__
+                # +  Called from (traceback):
+                # +    line 1684, in writesubtree
+                # line 1632, in add: Built-in function sorted was called with the wrong arguments [wrong-arg-types]
+                # +    Expected: (iterable: Iterable, ...)
+                # +    Actually passed: (iterable: None)
+                # +    The following methods aren't implemented on None:
+                # +    __iter__
+                # +  Called from (traceback):
+                # +    line 1684, in writesubtree
+
+                # XXX: writesubtree() below passes None.  Not clear if this
+                # branch can't happen because of `if` test above.
+                [(x, False) for x in sorted(added)],  # pytype: disable=wrong-arg-types
+                [(x, True) for x in sorted(removed)],  # pytype: disable=wrong-arg-types
             )
 
             arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -1162,9 +1162,17 @@
         # would required a dedicated "revnav" class
         nav = templateutil.mappinglist([])
         if descend:
-            it = dagop.blockdescendants(fctx, *lrange)
+            # line 1165, in filelog: Missing parameter 'toline' in call to function mercurial.dagop.blockdescendants [missing-parameter]
+            # +    Expected: (fctx, fromline, toline)
+            # +    Actually passed: (fctx, fromline)
+            # XXX: This seems correct, because lrange is a tuple of 2.
+            # Why not complain about formatlinerange() below?
+            it = dagop.blockdescendants(fctx, *lrange)  # pytype: disable=missing-parameter
         else:
-            it = dagop.blockancestors(fctx, *lrange)
+            # line 1167, in filelog: Missing parameter 'toline' in call to function mercurial.dagop.blockancestors [missing-parameter]
+            # +    Expected: (fctx, fromline, toline, followfirst)
+            # +    Actually passed: (fctx, fromline)
+            it = dagop.blockancestors(fctx, *lrange)  # pytype: disable=missing-parameter
         for i, (c, lr) in enumerate(it, 1):
             diffs = None
             if patch:
diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py
--- a/mercurial/hgweb/server.py
+++ b/mercurial/hgweb/server.py
@@ -426,9 +426,14 @@
         except AttributeError:
             reload(sys)
         oldenc = sys.getdefaultencoding()
-        sys.setdefaultencoding(b"latin1")  # or any full 8-bit encoding
+
+        # Note: none of this was detected with pytype 2019.12.06.  It was
+        # flagged in the past with an older version, on a Mac.
+        # or any full 8-bit encoding
+        sys.setdefaultencoding(b"latin1")  # pytype: disable=module-attr
+        import mimetypes
         mimetypes.init()
-        sys.setdefaultencoding(oldenc)
+        sys.setdefaultencoding(oldenc)  # pytype: disable=module-attr
 
     address = ui.config(b'web', b'address')
     port = util.getport(ui.config(b'web', b'port'))
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -65,7 +65,11 @@
     # Python 2 raises TypeError, Python 3 ValueError.
     except (TypeError, ValueError) as e:
         raise error.Abort(
-            _(b'invalid path %s: %s') % (path, pycompat.bytestr(e))
+            # line 68, in _local: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+            # +    Expected: (self, ints: Iterable[int])
+            # +    Actually passed: (self, ints: Union[TypeError, ValueError])
+            _(b'invalid path %s: %s') % (path, pycompat.bytestr(e  # pytype: disable=wrong-arg-types
+            ))
         )
 
     return isfile and bundlerepo or localrepo
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1954,7 +1954,15 @@
             # make sure to always includes bookmark data when migrating
             # `hg incoming --bundle` to using this function.
             pullop.stepsdone.add(b'request-bookmarks')
-            kwargs.setdefault(b'listkeys', []).append(b'bookmarks')
+            # line 1944, in _pullbundle2: No attribute 'append' on bool [attribute-error]
+            # +    In Union[Any, List[bytes], List[nothing], bool]
+            # +  Called from (traceback):
+            # +    line 1673, in _fullpullbundle2
+            # line 1944, in _pullbundle2: No attribute 'append' on Set[bytes] [attribute-error]
+            # +    In Union[Any, List[bytes], List[nothing], Set[bytes], bool]
+            # line 1944, in _pullbundle2: No attribute 'append' on bool [attribute-error]
+            # +    In Union[Any, List[bytes], List[nothing], Set[bytes], bool]
+            kwargs.setdefault(b'listkeys', []).append(b'bookmarks')  # pytype: disable=attribute-error
 
     # If this is a full pull / clone and the server supports the clone bundles
     # feature, tell the server whether we attempted a clone bundle. The
@@ -2758,9 +2766,15 @@
                             lockandtr[0] = repo.wlock()
                         lockandtr[1] = repo.lock()
                         lockandtr[2] = repo.transaction(source)
-                        lockandtr[2].hookargs[b'source'] = source
-                        lockandtr[2].hookargs[b'url'] = url
-                        lockandtr[2].hookargs[b'bundle2'] = b'1'
+                        # line 2748, in gettransaction: No attribute 'hookargs' on None [attribute-error]
+                        # +    In Optional[Any]
+                        # line 2749, in gettransaction: No attribute 'hookargs' on None [attribute-error]
+                        # +    In Optional[Any]
+                        # line 2750, in gettransaction: No attribute 'hookargs' on None [attribute-error]
+                        # +    In Optional[Any]
+                        lockandtr[2].hookargs[b'source'] = source  # pytype: disable=attribute-error
+                        lockandtr[2].hookargs[b'url'] = url  # pytype: disable=attribute-error
+                        lockandtr[2].hookargs[b'bundle2'] = b'1'  # pytype: disable=attribute-error
                     return lockandtr[2]
 
                 # Do greedy locking by default until we're satisfied with lazy
diff --git a/mercurial/error.py b/mercurial/error.py
--- a/mercurial/error.py
+++ b/mercurial/error.py
@@ -35,7 +35,62 @@
 
     def __init__(self, *args, **kw):
         self.hint = kw.pop('hint', None)
-        super(Hint, self).__init__(*args, **kw)
+        #   line 38, in __init__: Function AmbiguousPrefixLookupError.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 76, in __init__
+        #   line 38, in __init__: Function CensoredNodeError.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 384, in __init__
+        #   line 38, in __init__: Function FilteredLookupError.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 76, in __init__
+        #   line 38, in __init__: Function LookupError.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 76, in __init__
+        #   line 38, in __init__: Function ManifestLookupError.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 76, in __init__
+        #   line 38, in __init__: Function ProgrammingError.__init__ expects 1 arg(s), got 3 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _, _)
+        #   Called from (traceback):
+        #     line 309, in __init__
+        #   line 38, in __init__: Function PushkeyFailed.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 371, in __init__
+        #   line 38, in __init__: Function ResponseExpected.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 161, in __init__
+        #   line 38, in __init__: Function UnknownIdentifier.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 186, in __init__
+        #   line 38, in __init__: Function UnknownVersion.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 242, in __init__
+        #   line 38, in __init__: Function UnsupportedMergeRecords.__init__ expects 1 arg(s), got 2 [wrong-arg-count]
+        #     Expected: (self)
+        #     Actually passed: (self, _)
+        #   Called from (traceback):
+        #     line 230, in __init__
+        super(Hint, self).__init__(*args, **kw)  # pytype: disable=wrong-arg-count
 
 
 class StorageError(Hint, Exception):
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -386,7 +386,11 @@
         return b'{%s}' % (
             b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
         )
-    return pycompat.bytestr(repr(thing))
+    # line 389, in _quasirepr: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+    # +    Expected: (self, ints: Iterable[int])
+    # +    Actually passed: (self, ints: str)
+    return pycompat.bytestr(repr(thing)  # pytype: disable=wrong-arg-types
+    )
 
 
 def _debugbundle2(ui, gen, all=None, **opts):
@@ -2179,8 +2183,14 @@
                 )
                 tr.close()
             except ValueError as exc:
+                # line 2183, in debugobsolete: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+                # +    Expected: (self, ints: Iterable[int])
+                # +    Actually passed: (self, ints: ValueError)
+                # +    The following methods aren't implemented on ValueError:
+                # +    __iter__
                 raise error.Abort(
-                    _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
+                    _(b'bad obsmarker input: %s') % pycompat.bytestr(exc  # pytype: disable=wrong-arg-types
+                    )
                 )
             finally:
                 tr.release()
@@ -2861,7 +2871,11 @@
     def fmtchunktype(chunktype):
         if chunktype == b'empty':
             return b'    %s     : ' % chunktype
-        elif chunktype in pycompat.bytestr(string.ascii_letters):
+        # line 2864, in fmtchunktype: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: str)
+        elif chunktype in pycompat.bytestr(string.ascii_letters   # pytype: disable=wrong-arg-types
+        ):
             return b'    0x%s (%s)  : ' % (hex(chunktype), chunktype)
         else:
             return b'    0x%s      : ' % hex(chunktype)
diff --git a/mercurial/dagparser.py b/mercurial/dagparser.py
--- a/mercurial/dagparser.py
+++ b/mercurial/dagparser.py
@@ -168,9 +168,12 @@
     if not desc:
         return
 
+    # line 172, in parsedag: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+    # +    Expected: (self, ints: Iterable[int])
+    # +    Actually passed: (self, ints: str)
     wordchars = pycompat.bytestr(
-        string.ascii_letters + string.digits
-    )  # pytype: disable=wrong-arg-types
+        string.ascii_letters + string.digits  # pytype: disable=wrong-arg-types
+    )
 
     labels = {}
     p1 = -1
@@ -179,9 +182,12 @@
     def resolve(ref):
         if not ref:
             return p1
+        # line 183, in resolve: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: str)
         elif ref[0] in pycompat.bytestr(
-            string.digits
-        ):  # pytype: disable=wrong-arg-types
+            string.digits  # pytype: disable=wrong-arg-types
+        ):
             return r - int(ref)
         else:
             return labels[ref]
@@ -215,9 +221,12 @@
 
     c = nextch()
     while c != b'\0':
+        # line 219, in parsedag: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: str)
         while c in pycompat.bytestr(
-            string.whitespace
-        ):  # pytype: disable=wrong-arg-types
+            string.whitespace  # pytype: disable=wrong-arg-types
+        ):
             c = nextch()
         if c == b'.':
             yield b'n', (r, [p1])
@@ -225,9 +234,12 @@
             r += 1
             c = nextch()
         elif c == b'+':
+            #  line 229, in parsedag: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+            # +    Expected: (self, ints: Iterable[int])
+            # +    Actually passed: (self, ints: str)
             c, digs = nextrun(
-                nextch(), pycompat.bytestr(string.digits)
-            )  # pytype: disable=wrong-arg-types
+                nextch(), pycompat.bytestr(string.digits)  # pytype: disable=wrong-arg-types
+            )
             n = int(digs)
             for i in pycompat.xrange(0, n):
                 yield b'n', (r, [p1])
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3383,8 +3383,14 @@
     try:
         regexp = util.re.compile(pattern, reflags)
     except re.error as inst:
+        # line 3403, in grep: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
+        # +    Expected: (self, ints: Iterable[int])
+        # +    Actually passed: (self, ints: re.error)
+        # +    The following methods aren't implemented on re.error:
+        # +    __iter__
         ui.warn(
-            _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
+            _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst  # pytype: disable=wrong-arg-types
+            )
         )
         return 1
     sep, eol = b':', b'\n'
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -41,6 +41,10 @@
     vfs as vfsmod,
 )
 
+from .interfaces import (
+    repository,
+)
+
 
 class bundlerevlog(revlog.revlog):
     def __init__(self, opener, indexfile, cgunpacker, linkmapper):
@@ -250,6 +254,8 @@
     """
 
     def __init__(self, bundlepath, url, tempparent):
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         self._tempparent = tempparent
         self._url = url
 
@@ -310,6 +316,8 @@
         )
 
     def _handlebundle2part(self, bundle, part):
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         if part.type != b'changegroup':
             return
 
@@ -327,6 +335,8 @@
     def _writetempbundle(self, readfn, suffix, header=b''):
         """Write a temporary file to disk
         """
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         fdtemp, temp = self.vfs.mkstemp(prefix=b"hg-bundle-", suffix=suffix)
         self.tempfile = temp
 
@@ -373,6 +383,8 @@
     def _consumemanifest(self):
         """Consumes the manifest portion of the bundle, setting filestart so the
         file portion can be read."""
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         self._cgunpacker.seek(self.manstart)
         self._cgunpacker.manifestheader()
         for delta in self._cgunpacker.deltaiter():
@@ -398,9 +410,13 @@
         return self.filestart
 
     def url(self):
-        return self._url
+        # TODO: figure out why pytype doesn't see this attribute that's set in
+        # the constructor.
+        return self._url  # pytype: disable=attribute-error
 
     def file(self, f):
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         if not self._cgfilespos:
             self._cgunpacker.seek(self.filestart)
             self._cgfilespos = _getfilestarts(self._cgunpacker)
@@ -414,6 +430,8 @@
 
     def close(self):
         """Close assigned bundle file immediately."""
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         self._bundlefile.close()
         if self.tempfile is not None:
             self.vfs.unlink(self.tempfile)
@@ -431,6 +449,8 @@
 
     # Check if parents exist in localrepo before setting
     def setparents(self, p1, p2=nullid):
+        assert isinstance(self, repository.ilocalrepositorymain)  # help pytype
+
         p1rev = self.changelog.rev(p1)
         p2rev = self.changelog.rev(p2)
         msg = _(b"setting parent to node %s that only exists in the bundle\n")



To: mharbison72, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list