Mercurial > hg
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 |