##// END OF EJS Templates
interfaces: make the `peer` mixin not a Protocol to fix Python 3.10 failures...
interfaces: make the `peer` mixin not a Protocol to fix Python 3.10 failures I can't find any documentation on this, but it appears that Protocol class attributes don't get inherited in subclasses that explicitly subclass a Protocol until Python 3.11, which caused a ton of failures in CI on macOS and Windows (which both test using Python 3.9). The problem started with 1df97507c6b8, and typically manifested as most tests failing to access `ui` on various `peer` classes. Here's a short proof of concept: from __future__ import annotations from typing import ( Protocol, ) class peer(Protocol): limitedarguments: bool = False def __init__(self, arg1, arg2, remotehidden: bool = False) -> None: self.arg1 = arg1 self.arg2 = arg2 class subclass(peer): def __init__(self, arg1, arg2): super(subclass, self).__init__(arg1, arg2, False) sub = subclass(1, 2) print("sub.arg1 is %r" % sub.arg1) When run with Python 3.8.10, 3.9.13, and 3.10.11, the result is: $ py -3.8 prot-test.py Traceback (most recent call last): File "prot-test.py", line 20, in <module> print("sub.arg1 is %r" % sub.arg1) AttributeError: 'subclass' object has no attribute 'arg1' On Python 3.11.9, 3.12.7, and 3.13.0, the result is: $ py -3.11 ../prot-test.py sub.arg1 is 1 Explicitly adding annotations to `peer` like `limitedarguments` didn't help.

File last commit:

r52756:f4733654 default
r53403:199b0e62 default
Show More
treediscovery.py
207 lines | 7.0 KiB | text/x-python | PythonLexer
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 # discovery.py - protocol changeset discovery functions
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2010 Olivia Mackall <olivia@selenic.com>
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 #
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Gregory Szorc
treediscovery: use absolute_import
r25987
Martin von Zweigbergk
util: drop alias for collections.deque...
r25113 import collections
Gregory Szorc
treediscovery: use absolute_import
r25987
from .i18n import _
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 from .node import short
Gregory Szorc
treediscovery: use absolute_import
r25987 from . import (
error,
)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
Augie Fackler
formatting: blacken the codebase...
r43346
debugdiscovery: display the number of roundtrip used...
r46726 def findcommonincoming(repo, remote, heads=None, force=False, audit=None):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 """Return a tuple (common, fetch, heads) used to identify the common
subset of nodes between repo and remote.
"common" is a list of (at least) the heads of the common subset.
"fetch" is a list of roots of the nodes that would be incoming, to be
supplied to changegroupsubset.
"heads" is either the supplied heads, or else the remote's heads.
"""
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 knownnode = repo.changelog.hasnode
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 search = []
fetch = set()
seen = set()
seenbranch = set()
base = set()
if not heads:
Gregory Szorc
treediscovery: switch to command executor interface...
r37652 with remote.commandexecutor() as e:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 heads = e.callcommand(b'heads', {}).result()
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
debugdiscovery: display the number of roundtrip used...
r46726 if audit is not None:
audit[b'total-roundtrips'] = 1
debug-discovery: gather the right number of roundtrips for tree discovery...
r50297 audit[b'total-roundtrips-heads'] = 1
audit[b'total-roundtrips-branches'] = 0
audit[b'total-roundtrips-between'] = 0
discovery: also audit the number of queries done...
r49881 audit[b'total-queries'] = 0
debug-discovery: also gather details on tree-discovery queries type...
r50296 audit[b'total-queries-branches'] = 0
audit[b'total-queries-between'] = 0
debugdiscovery: display the number of roundtrip used...
r46726
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if repo.changelog.tip() == repo.nullid:
base.add(repo.nullid)
if heads != [repo.nullid]:
return [repo.nullid], [repo.nullid], list(heads)
return [repo.nullid], [], heads
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
# assume we're closer to the tip than the root
# and start by examining the heads
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b"searching for changes\n"))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
unknown = []
for h in heads:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if not knownnode(h):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 unknown.append(h)
else:
base.add(h)
Peter Arrenbrecht
treediscovery: fix regression when run against older repos (issue2793)...
r14199 if not unknown:
return list(base), [], list(heads)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 req = set(unknown)
reqcnt = 0
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 progress = repo.ui.makeprogress(_(b'searching'), unit=_(b'queries'))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
# search through remote branches
# a 'branch' here is a linear segment of history, with four parts:
# head, root, first parent, second parent
# (a branch always has two parents (or none) by definition)
Gregory Szorc
treediscovery: switch to command executor interface...
r37652 with remote.commandexecutor() as e:
discovery: also audit the number of queries done...
r49881 if audit is not None:
audit[b'total-queries'] += len(unknown)
debug-discovery: also gather details on tree-discovery queries type...
r50296 audit[b'total-queries-branches'] += len(unknown)
debug-discovery: gather the right number of roundtrips for tree discovery...
r50297 audit[b'total-roundtrips'] += 1
audit[b'total-roundtrips-branches'] += 1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branches = e.callcommand(b'branches', {b'nodes': unknown}).result()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
unknown = collections.deque(branches)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 while unknown:
r = []
while unknown:
Bryan O'Sullivan
cleanup: use the deque type where appropriate...
r16803 n = unknown.popleft()
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 if n[0] in seen:
continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"examining %s:%s\n" % (short(n[0]), short(n[1])))
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if n[0] == repo.nullid: # found the end of the branch
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 pass
elif n in seenbranch:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"branch already found\n")
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 continue
Augie Fackler
formatting: blacken the codebase...
r43346 elif n[1] and knownnode(n[1]): # do we know the base?
repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"found incomplete branch %s:%s\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (short(n[0]), short(n[1]))
)
search.append(n[0:2]) # schedule branch range for scanning
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 seenbranch.add(n)
else:
if n[1] not in seen and n[1] not in fetch:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(n[2]) and knownnode(n[3]):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"found new changeset %s\n" % short(n[1]))
Augie Fackler
formatting: blacken the codebase...
r43346 fetch.add(n[1]) # earliest unknown
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 for p in n[2:4]:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(p):
Augie Fackler
formatting: blacken the codebase...
r43346 base.add(p) # latest known
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
for p in n[2:4]:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if p not in req and not knownnode(p):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 r.append(p)
req.add(p)
seen.add(n[0])
if r:
Manuel Jacob
py3: replace `pycompat.xrange` by `range`
r50179 for p in range(0, len(r), 10):
tree-discovery: fix the request debug output and progress location...
r50300 reqcnt += 1
progress.increment()
if repo.ui.debugflag:
msg = b"request %d: %s\n"
msg %= (reqcnt, b" ".join(map(short, r)))
repo.ui.debug(msg)
Gregory Szorc
treediscovery: switch to command executor interface...
r37652 with remote.commandexecutor() as e:
discovery: also audit the number of queries done...
r49881 subset = r[p : p + 10]
if audit is not None:
audit[b'total-queries'] += len(subset)
debug-discovery: also gather details on tree-discovery queries type...
r50296 audit[b'total-queries-branches'] += len(subset)
debug-discovery: gather the right number of roundtrips for tree discovery...
r50297 audit[b'total-roundtrips'] += 1
audit[b'total-roundtrips-branches'] += 1
Augie Fackler
formatting: blacken the codebase...
r43346 branches = e.callcommand(
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 b'branches',
{
discovery: also audit the number of queries done...
r49881 b'nodes': subset,
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 },
Augie Fackler
formatting: blacken the codebase...
r43346 ).result()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
for b in branches:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"received %s:%s\n" % (short(b[0]), short(b[1]))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 unknown.append(b)
# do binary search on the branches we found
while search:
newsearch = []
reqcnt += 1
Martin von Zweigbergk
treediscovery: use progress helper...
r38419 progress.increment()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
with remote.commandexecutor() as e:
discovery: also audit the number of queries done...
r49881 if audit is not None:
audit[b'total-queries'] += len(search)
debug-discovery: also gather details on tree-discovery queries type...
r50296 audit[b'total-queries-between'] += len(search)
debug-discovery: gather the right number of roundtrips for tree discovery...
r50297 audit[b'total-roundtrips'] += 1
audit[b'total-roundtrips-between'] += 1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 between = e.callcommand(b'between', {b'pairs': search}).result()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
for n, l in zip(search, between):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 l.append(n[1])
p = n[0]
f = 1
for i in l:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"narrowing %d:%d %s\n" % (f, len(l), short(i)))
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(i):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 if f <= 2:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"found new branch changeset %s\n" % short(p)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 fetch.add(p)
base.add(i)
else:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"narrowed branch search to %s:%s\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (short(p), short(i))
)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 newsearch.append((p, i))
break
p, f = i, f * 2
search = newsearch
# sanity check our fetch list
for f in fetch:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(f):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.RepoError(_(b"already have changeset ") + short(f[:4]))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
base = list(base)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if base == [repo.nullid]:
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 if force:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.warn(_(b"warning: repository is unrelated\n"))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"repository is unrelated"))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"found new changesets starting at "
+ b" ".join([short(f) for f in fetch])
+ b"\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
Martin von Zweigbergk
treediscovery: use progress helper...
r38419 progress.complete()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"%d total queries\n" % reqcnt)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
return base, list(fetch), heads