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. |