mercurial/revset.py
changeset 28423 0d79d91ba7e3
parent 28395 0383f7a5e86c
child 28424 534f968d33e5
equal deleted inserted replaced
28422:e2c6092ad422 28423:0d79d91ba7e3
  2728             funcs |= funcsused(s)
  2728             funcs |= funcsused(s)
  2729         if tree[0] == 'func':
  2729         if tree[0] == 'func':
  2730             funcs.add(tree[1][1])
  2730             funcs.add(tree[1][1])
  2731         return funcs
  2731         return funcs
  2732 
  2732 
       
  2733 def _formatsetrepr(r):
       
  2734     """Format an optional printable representation of a set
       
  2735 
       
  2736     ========  =================================
       
  2737     type(r)   example
       
  2738     ========  =================================
       
  2739     tuple     ('<not %r>', other)
       
  2740     str       '<branch closed>'
       
  2741     callable  lambda: '<branch %r>' % sorted(b)
       
  2742     object    other
       
  2743     ========  =================================
       
  2744     """
       
  2745     if r is None:
       
  2746         return ''
       
  2747     elif isinstance(r, tuple):
       
  2748         return r[0] % r[1:]
       
  2749     elif isinstance(r, str):
       
  2750         return r
       
  2751     elif callable(r):
       
  2752         return r()
       
  2753     else:
       
  2754         return repr(r)
       
  2755 
  2733 class abstractsmartset(object):
  2756 class abstractsmartset(object):
  2734 
  2757 
  2735     def __nonzero__(self):
  2758     def __nonzero__(self):
  2736         """True if the smartset is not empty"""
  2759         """True if the smartset is not empty"""
  2737         raise NotImplementedError()
  2760         raise NotImplementedError()
  2808         """Returns a new object with the intersection of the two collections.
  2831         """Returns a new object with the intersection of the two collections.
  2809 
  2832 
  2810         This is part of the mandatory API for smartset."""
  2833         This is part of the mandatory API for smartset."""
  2811         if isinstance(other, fullreposet):
  2834         if isinstance(other, fullreposet):
  2812             return self
  2835             return self
  2813         return self.filter(other.__contains__, cache=False)
  2836         return self.filter(other.__contains__, condrepr=other, cache=False)
  2814 
  2837 
  2815     def __add__(self, other):
  2838     def __add__(self, other):
  2816         """Returns a new object with the union of the two collections.
  2839         """Returns a new object with the union of the two collections.
  2817 
  2840 
  2818         This is part of the mandatory API for smartset."""
  2841         This is part of the mandatory API for smartset."""
  2821     def __sub__(self, other):
  2844     def __sub__(self, other):
  2822         """Returns a new object with the substraction of the two collections.
  2845         """Returns a new object with the substraction of the two collections.
  2823 
  2846 
  2824         This is part of the mandatory API for smartset."""
  2847         This is part of the mandatory API for smartset."""
  2825         c = other.__contains__
  2848         c = other.__contains__
  2826         return self.filter(lambda r: not c(r), cache=False)
  2849         return self.filter(lambda r: not c(r), condrepr=('<not %r>', other),
  2827 
  2850                            cache=False)
  2828     def filter(self, condition, cache=True):
  2851 
       
  2852     def filter(self, condition, condrepr=None, cache=True):
  2829         """Returns this smartset filtered by condition as a new smartset.
  2853         """Returns this smartset filtered by condition as a new smartset.
  2830 
  2854 
  2831         `condition` is a callable which takes a revision number and returns a
  2855         `condition` is a callable which takes a revision number and returns a
  2832         boolean.
  2856         boolean. Optional `condrepr` provides a printable representation of
       
  2857         the given `condition`.
  2833 
  2858 
  2834         This is part of the mandatory API for smartset."""
  2859         This is part of the mandatory API for smartset."""
  2835         # builtin cannot be cached. but do not needs to
  2860         # builtin cannot be cached. but do not needs to
  2836         if cache and util.safehasattr(condition, 'func_code'):
  2861         if cache and util.safehasattr(condition, 'func_code'):
  2837             condition = util.cachefunc(condition)
  2862             condition = util.cachefunc(condition)
  2838         return filteredset(self, condition)
  2863         return filteredset(self, condition, condrepr)
  2839 
  2864 
  2840 class baseset(abstractsmartset):
  2865 class baseset(abstractsmartset):
  2841     """Basic data structure that represents a revset and contains the basic
  2866     """Basic data structure that represents a revset and contains the basic
  2842     operation that it should be able to perform.
  2867     operation that it should be able to perform.
  2843 
  2868 
  2937 class filteredset(abstractsmartset):
  2962 class filteredset(abstractsmartset):
  2938     """Duck type for baseset class which iterates lazily over the revisions in
  2963     """Duck type for baseset class which iterates lazily over the revisions in
  2939     the subset and contains a function which tests for membership in the
  2964     the subset and contains a function which tests for membership in the
  2940     revset
  2965     revset
  2941     """
  2966     """
  2942     def __init__(self, subset, condition=lambda x: True):
  2967     def __init__(self, subset, condition=lambda x: True, condrepr=None):
  2943         """
  2968         """
  2944         condition: a function that decide whether a revision in the subset
  2969         condition: a function that decide whether a revision in the subset
  2945                    belongs to the revset or not.
  2970                    belongs to the revset or not.
       
  2971         condrepr: a tuple of (format, obj, ...), a function or an object that
       
  2972                   provides a printable representation of the given condition.
  2946         """
  2973         """
  2947         self._subset = subset
  2974         self._subset = subset
  2948         self._condition = condition
  2975         self._condition = condition
       
  2976         self._condrepr = condrepr
  2949 
  2977 
  2950     def __contains__(self, x):
  2978     def __contains__(self, x):
  2951         return x in self._subset and self._condition(x)
  2979         return x in self._subset and self._condition(x)
  2952 
  2980 
  2953     def __iter__(self):
  2981     def __iter__(self):
  3023             for x in self:
  3051             for x in self:
  3024                 pass
  3052                 pass
  3025             return x
  3053             return x
  3026 
  3054 
  3027     def __repr__(self):
  3055     def __repr__(self):
  3028         return '<%s %r>' % (type(self).__name__, self._subset)
  3056         xs = [repr(self._subset)]
       
  3057         s = _formatsetrepr(self._condrepr)
       
  3058         if s:
       
  3059             xs.append(s)
       
  3060         return '<%s %s>' % (type(self).__name__, ', '.join(xs))
  3029 
  3061 
  3030 def _iterordered(ascending, iter1, iter2):
  3062 def _iterordered(ascending, iter1, iter2):
  3031     """produce an ordered iteration from two iterators with the same order
  3063     """produce an ordered iteration from two iterators with the same order
  3032 
  3064 
  3033     The ascending is used to indicated the iteration direction.
  3065     The ascending is used to indicated the iteration direction.