comparison mercurial/util.py @ 38575:152f4822d210

pycompat: move rapply() from util I want to use rapply() in utils.* modules, but that would introduce a reference cycle util -> utils.* -> util. Moving rapply() to pycompat should be okay since it mostly serves as a compatibility helper.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 10 Jun 2018 17:07:29 +0900
parents da2a7d8354b2
children 27391d74aaa2
comparison
equal deleted inserted replaced
38574:f442c9494ec7 38575:152f4822d210
128 pass 128 pass
129 129
130 # Python compatibility 130 # Python compatibility
131 131
132 _notset = object() 132 _notset = object()
133
134 def _rapply(f, xs):
135 if xs is None:
136 # assume None means non-value of optional data
137 return xs
138 if isinstance(xs, (list, set, tuple)):
139 return type(xs)(_rapply(f, x) for x in xs)
140 if isinstance(xs, dict):
141 return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
142 return f(xs)
143
144 def rapply(f, xs):
145 """Apply function recursively to every item preserving the data structure
146
147 >>> def f(x):
148 ... return 'f(%s)' % x
149 >>> rapply(f, None) is None
150 True
151 >>> rapply(f, 'a')
152 'f(a)'
153 >>> rapply(f, {'a'}) == {'f(a)'}
154 True
155 >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
156 ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
157
158 >>> xs = [object()]
159 >>> rapply(pycompat.identity, xs) is xs
160 True
161 """
162 if f is pycompat.identity:
163 # fast path mainly for py2
164 return xs
165 return _rapply(f, xs)
166 133
167 def bitsfrom(container): 134 def bitsfrom(container):
168 bits = 0 135 bits = 0
169 for bit in container: 136 for bit in container:
170 bits |= bit 137 bits |= bit