lazyancestors: extract __iter__ to free function
The next patch will keep a reference to the returned iterator in a
field, which would otherwise result in a reference cycle.
Differential Revision: https://phab.mercurial-scm.org/D4517
--- a/mercurial/ancestor.py Thu Aug 30 01:53:21 2018 +0200
+++ b/mercurial/ancestor.py Sun Sep 09 23:16:55 2018 -0700
@@ -259,6 +259,37 @@
missing.reverse()
return missing
+# Extracted from lazyancestors.__iter__ to avoid a reference cycle
+def _lazyancestorsiter(parentrevs, initrevs, stoprev, inclusive):
+ seen = {nullrev}
+ revs = initrevs
+
+ schedule = heapq.heappush
+ nextitem = heapq.heappop
+ see = seen.add
+
+ if inclusive:
+ visit = [-r for r in revs]
+ seen.update(revs)
+ heapq.heapify(visit)
+ else:
+ visit = []
+ heapq.heapify(visit)
+ for r in revs:
+ for parent in parentrevs(r):
+ if parent not in seen:
+ schedule(visit, -parent)
+ see(parent)
+
+ while visit:
+ current = -nextitem(visit)
+ if current >= stoprev:
+ yield current
+ for parent in parentrevs(current):
+ if parent not in seen:
+ schedule(visit, -parent)
+ see(parent)
+
class lazyancestors(object):
def __init__(self, pfunc, revs, stoprev=0, inclusive=False):
"""Create a new object generating ancestors for the given revs. Does
@@ -311,36 +342,9 @@
If inclusive is True, the source revisions are also yielded. The
reverse revision number order is still enforced."""
- seen = {nullrev}
- revs = self._initrevs
-
- parentrevs = self._parentrevs
- stoprev = self._stoprev
- schedule = heapq.heappush
- nextitem = heapq.heappop
- see = seen.add
-
- if self._inclusive:
- visit = [-r for r in revs]
- seen.update(revs)
- heapq.heapify(visit)
- else:
- visit = []
- heapq.heapify(visit)
- for r in revs:
- for parent in parentrevs(r):
- if parent not in seen:
- schedule(visit, -parent)
- see(parent)
-
- while visit:
- current = -nextitem(visit)
- if current >= stoprev:
- yield current
- for parent in parentrevs(current):
- if parent not in seen:
- schedule(visit, -parent)
- see(parent)
+ for rev in _lazyancestorsiter(self._parentrevs, self._initrevs,
+ self._stoprev, self._inclusive):
+ yield rev
def __contains__(self, target):
"""Test whether target is an ancestor of self._initrevs."""