mercurial/smartset.py
changeset 35901 f0827211eb1f
parent 35838 f484b9d95c23
child 35904 fc44c2657dc5
equal deleted inserted replaced
35900:72de5c504833 35901:f0827211eb1f
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from __future__ import absolute_import
     8 from __future__ import absolute_import
     9 
     9 
    10 from . import (
    10 from . import (
       
    11     encoding,
    11     error,
    12     error,
       
    13     pycompat,
    12     util,
    14     util,
    13 )
    15 )
    14 
    16 
    15 def _formatsetrepr(r):
    17 def _formatsetrepr(r):
    16     """Format an optional printable representation of a set
    18     """Format an optional printable representation of a set
    17 
    19 
    18     ========  =================================
    20     ========  =================================
    19     type(r)   example
    21     type(r)   example
    20     ========  =================================
    22     ========  =================================
    21     tuple     ('<not %r>', other)
    23     tuple     ('<not %r>', other)
    22     str       '<branch closed>'
    24     bytes     '<branch closed>'
    23     callable  lambda: '<branch %r>' % sorted(b)
    25     callable  lambda: '<branch %r>' % sorted(b)
    24     object    other
    26     object    other
    25     ========  =================================
    27     ========  =================================
    26     """
    28     """
    27     if r is None:
    29     if r is None:
    28         return ''
    30         return ''
    29     elif isinstance(r, tuple):
    31     elif isinstance(r, tuple):
    30         return r[0] % r[1:]
    32         return r[0] % r[1:]
    31     elif isinstance(r, str):
    33     elif isinstance(r, bytes):
    32         return r
    34         return r
    33     elif callable(r):
    35     elif callable(r):
    34         return r()
    36         return r()
    35     else:
    37     else:
    36         return repr(r)
    38         return pycompat.sysbytes(repr(r))
       
    39 
       
    40 def _typename(o):
       
    41     return pycompat.sysbytes(type(o).__name__).lstrip('_')
    37 
    42 
    38 class abstractsmartset(object):
    43 class abstractsmartset(object):
    39 
    44 
    40     def __nonzero__(self):
    45     def __nonzero__(self):
    41         """True if the smartset is not empty"""
    46         """True if the smartset is not empty"""
   382             start, stop = max(len(data) - stop, 0), max(len(data) - start, 0)
   387             start, stop = max(len(data) - stop, 0), max(len(data) - start, 0)
   383         s = baseset(data[start:stop], istopo=self._istopo)
   388         s = baseset(data[start:stop], istopo=self._istopo)
   384         s._ascending = self._ascending
   389         s._ascending = self._ascending
   385         return s
   390         return s
   386 
   391 
       
   392     @encoding.strmethod
   387     def __repr__(self):
   393     def __repr__(self):
   388         d = {None: '', False: '-', True: '+'}[self._ascending]
   394         d = {None: '', False: '-', True: '+'}[self._ascending]
   389         s = _formatsetrepr(self._datarepr)
   395         s = _formatsetrepr(self._datarepr)
   390         if not s:
   396         if not s:
   391             l = self._list
   397             l = self._list
   392             # if _list has been built from a set, it might have a different
   398             # if _list has been built from a set, it might have a different
   393             # order from one python implementation to another.
   399             # order from one python implementation to another.
   394             # We fallback to the sorted version for a stable output.
   400             # We fallback to the sorted version for a stable output.
   395             if self._ascending is not None:
   401             if self._ascending is not None:
   396                 l = self._asclist
   402                 l = self._asclist
   397             s = repr(l)
   403             s = pycompat.sysbytes(repr(l))
   398         return '<%s%s %s>' % (type(self).__name__, d, s)
   404         return '<%s%s %s>' % (_typename(self), d, s)
   399 
   405 
   400 class filteredset(abstractsmartset):
   406 class filteredset(abstractsmartset):
   401     """Duck type for baseset class which iterates lazily over the revisions in
   407     """Duck type for baseset class which iterates lazily over the revisions in
   402     the subset and contains a function which tests for membership in the
   408     the subset and contains a function which tests for membership in the
   403     revset
   409     revset
   503             x = None
   509             x = None
   504             for x in self:
   510             for x in self:
   505                 pass
   511                 pass
   506             return x
   512             return x
   507 
   513 
       
   514     @encoding.strmethod
   508     def __repr__(self):
   515     def __repr__(self):
   509         xs = [repr(self._subset)]
   516         xs = [pycompat.sysbytes(repr(self._subset))]
   510         s = _formatsetrepr(self._condrepr)
   517         s = _formatsetrepr(self._condrepr)
   511         if s:
   518         if s:
   512             xs.append(s)
   519             xs.append(s)
   513         return '<%s %s>' % (type(self).__name__, ', '.join(xs))
   520         return '<%s %s>' % (_typename(self), ', '.join(xs))
   514 
   521 
   515 def _iterordered(ascending, iter1, iter2):
   522 def _iterordered(ascending, iter1, iter2):
   516     """produce an ordered iteration from two iterators with the same order
   523     """produce an ordered iteration from two iterators with the same order
   517 
   524 
   518     The ascending is used to indicated the iteration direction.
   525     The ascending is used to indicated the iteration direction.
   753         self.reverse()
   760         self.reverse()
   754         val = self.first()
   761         val = self.first()
   755         self.reverse()
   762         self.reverse()
   756         return val
   763         return val
   757 
   764 
       
   765     @encoding.strmethod
   758     def __repr__(self):
   766     def __repr__(self):
   759         d = {None: '', False: '-', True: '+'}[self._ascending]
   767         d = {None: '', False: '-', True: '+'}[self._ascending]
   760         return '<%s%s %r, %r>' % (type(self).__name__, d, self._r1, self._r2)
   768         return '<%s%s %r, %r>' % (_typename(self), d, self._r1, self._r2)
   761 
   769 
   762 class generatorset(abstractsmartset):
   770 class generatorset(abstractsmartset):
   763     """Wrap a generator for lazy iteration
   771     """Wrap a generator for lazy iteration
   764 
   772 
   765     Wrapper structure for generators that provides lazy membership and can
   773     Wrapper structure for generators that provides lazy membership and can
   916             for x in self._consumegen():
   924             for x in self._consumegen():
   917                 pass
   925                 pass
   918             return self.last()
   926             return self.last()
   919         return next(it(), None)
   927         return next(it(), None)
   920 
   928 
       
   929     @encoding.strmethod
   921     def __repr__(self):
   930     def __repr__(self):
   922         d = {False: '-', True: '+'}[self._ascending]
   931         d = {False: '-', True: '+'}[self._ascending]
   923         return '<%s%s>' % (type(self).__name__.lstrip('_'), d)
   932         return '<%s%s>' % (_typename(self), d)
   924 
   933 
   925 class _generatorsetasc(generatorset):
   934 class _generatorsetasc(generatorset):
   926     """Special case of generatorset optimized for ascending generators."""
   935     """Special case of generatorset optimized for ascending generators."""
   927 
   936 
   928     fastasc = generatorset._iterator
   937     fastasc = generatorset._iterator
  1085         else:
  1094         else:
  1086             x = max(self._end - stop, self._start)
  1095             x = max(self._end - stop, self._start)
  1087             y = max(self._end - start, self._start)
  1096             y = max(self._end - start, self._start)
  1088         return _spanset(x, y, self._ascending, self._hiddenrevs)
  1097         return _spanset(x, y, self._ascending, self._hiddenrevs)
  1089 
  1098 
       
  1099     @encoding.strmethod
  1090     def __repr__(self):
  1100     def __repr__(self):
  1091         d = {False: '-', True: '+'}[self._ascending]
  1101         d = {False: '-', True: '+'}[self._ascending]
  1092         return '<%s%s %d:%d>' % (type(self).__name__.lstrip('_'), d,
  1102         return '<%s%s %d:%d>' % (_typename(self), d, self._start, self._end)
  1093                                  self._start, self._end)
       
  1094 
  1103 
  1095 class fullreposet(_spanset):
  1104 class fullreposet(_spanset):
  1096     """a set containing all revisions in the repo
  1105     """a set containing all revisions in the repo
  1097 
  1106 
  1098     This class exists to host special optimization and magic to handle virtual
  1107     This class exists to host special optimization and magic to handle virtual
  1121         other.sort(reverse=self.isdescending())
  1130         other.sort(reverse=self.isdescending())
  1122         return other
  1131         return other
  1123 
  1132 
  1124 def prettyformat(revs):
  1133 def prettyformat(revs):
  1125     lines = []
  1134     lines = []
  1126     rs = repr(revs)
  1135     rs = pycompat.sysbytes(repr(revs))
  1127     p = 0
  1136     p = 0
  1128     while p < len(rs):
  1137     while p < len(rs):
  1129         q = rs.find('<', p + 1)
  1138         q = rs.find('<', p + 1)
  1130         if q < 0:
  1139         if q < 0:
  1131             q = len(rs)
  1140             q = len(rs)