Mercurial > hg-stable
changeset 28423:0d79d91ba7e3
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 ('<not %r>', other)
str '<branch closed>'
callable lambda: '<branch %r>' % sorted(b)
object other
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 13 Feb 2016 19:25:11 +0900 |
parents | e2c6092ad422 |
children | 534f968d33e5 |
files | mercurial/revset.py tests/test-revset.t |
diffstat | 2 files changed, 52 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- 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 ('<not %r>', other) + str '<branch closed>' + callable lambda: '<branch %r>' % 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=('<not %r>', 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
--- 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: <filteredset - <baseset [1]>> + <baseset [1]>, + <not + <baseset [0]>>> 1 $ try _a_b_c_ ('symbol', '_a_b_c_') @@ -182,7 +184,9 @@ ('symbol', 'a')) * set: <filteredset - <baseset [6]>> + <baseset [6]>, + <not + <baseset [0]>>> 6 $ try .a.b.c. ('symbol', '.a.b.c.') @@ -195,7 +199,9 @@ ('symbol', 'a')) * set: <filteredset - <baseset [7]>> + <baseset [7]>, + <not + <baseset [0]>>> 7 names that should be caught by fallback mechanism @@ -278,7 +284,9 @@ ('symbol', 'a')) * set: <filteredset - <baseset [4]>> + <baseset [4]>, + <not + <baseset [0]>>> 4 $ log '1 or 2'