# HG changeset patch # User Yuya Nishihara # Date 1455359111 -32400 # Node ID 0d79d91ba7e307b56f209e526b459d05e1912336 # Parent e2c6092ad4229e468b1afd8bb4a43fa4e84f85bf revset: add extra data to filteredset for better inspection A filteredset is heavily used, but it cannot provide a printable information how given set is filtered because a condition is an arbitrary callable object. This patch adds an optional "condrepr" object that is used only by repr(). To minimize the maintaining/runtime overhead of "condrepr", its type is overloaded as follows: type example -------- --------------------------------- tuple ('', other) str '' callable lambda: '' % sorted(b) object other diff -r e2c6092ad422 -r 0d79d91ba7e3 mercurial/revset.py --- a/mercurial/revset.py Tue Mar 01 10:18:47 2016 +0000 +++ b/mercurial/revset.py Sat Feb 13 19:25:11 2016 +0900 @@ -2730,6 +2730,29 @@ funcs.add(tree[1][1]) return funcs +def _formatsetrepr(r): + """Format an optional printable representation of a set + + ======== ================================= + type(r) example + ======== ================================= + tuple ('', other) + str '' + callable lambda: '' % sorted(b) + object other + ======== ================================= + """ + if r is None: + return '' + elif isinstance(r, tuple): + return r[0] % r[1:] + elif isinstance(r, str): + return r + elif callable(r): + return r() + else: + return repr(r) + class abstractsmartset(object): def __nonzero__(self): @@ -2810,7 +2833,7 @@ This is part of the mandatory API for smartset.""" if isinstance(other, fullreposet): return self - return self.filter(other.__contains__, cache=False) + return self.filter(other.__contains__, condrepr=other, cache=False) def __add__(self, other): """Returns a new object with the union of the two collections. @@ -2823,19 +2846,21 @@ This is part of the mandatory API for smartset.""" c = other.__contains__ - return self.filter(lambda r: not c(r), cache=False) - - def filter(self, condition, cache=True): + return self.filter(lambda r: not c(r), condrepr=('', other), + cache=False) + + def filter(self, condition, condrepr=None, cache=True): """Returns this smartset filtered by condition as a new smartset. `condition` is a callable which takes a revision number and returns a - boolean. + boolean. Optional `condrepr` provides a printable representation of + the given `condition`. This is part of the mandatory API for smartset.""" # builtin cannot be cached. but do not needs to if cache and util.safehasattr(condition, 'func_code'): condition = util.cachefunc(condition) - return filteredset(self, condition) + return filteredset(self, condition, condrepr) class baseset(abstractsmartset): """Basic data structure that represents a revset and contains the basic @@ -2939,13 +2964,16 @@ the subset and contains a function which tests for membership in the revset """ - def __init__(self, subset, condition=lambda x: True): + def __init__(self, subset, condition=lambda x: True, condrepr=None): """ condition: a function that decide whether a revision in the subset belongs to the revset or not. + condrepr: a tuple of (format, obj, ...), a function or an object that + provides a printable representation of the given condition. """ self._subset = subset self._condition = condition + self._condrepr = condrepr def __contains__(self, x): return x in self._subset and self._condition(x) @@ -3025,7 +3053,11 @@ return x def __repr__(self): - return '<%s %r>' % (type(self).__name__, self._subset) + xs = [repr(self._subset)] + s = _formatsetrepr(self._condrepr) + if s: + xs.append(s) + return '<%s %s>' % (type(self).__name__, ', '.join(xs)) def _iterordered(ascending, iter1, iter2): """produce an ordered iteration from two iterators with the same order diff -r e2c6092ad422 -r 0d79d91ba7e3 tests/test-revset.t --- a/tests/test-revset.t Tue Mar 01 10:18:47 2016 +0000 +++ b/tests/test-revset.t Sat Feb 13 19:25:11 2016 +0900 @@ -169,7 +169,9 @@ ('symbol', 'a')) * set: > + , + >> 1 $ try _a_b_c_ ('symbol', '_a_b_c_') @@ -182,7 +184,9 @@ ('symbol', 'a')) * set: > + , + >> 6 $ try .a.b.c. ('symbol', '.a.b.c.') @@ -195,7 +199,9 @@ ('symbol', 'a')) * set: > + , + >> 7 names that should be caught by fallback mechanism @@ -278,7 +284,9 @@ ('symbol', 'a')) * set: > + , + >> 4 $ log '1 or 2'