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.
--- a/mercurial/cmdutil.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/cmdutil.py Sun Jun 10 17:07:29 2018 +0900
@@ -1680,7 +1680,7 @@
fm.write('date', '(%s) ', fm.formatdate(marker.date()))
meta = marker.metadata().copy()
meta.pop('date', None)
- smeta = util.rapply(pycompat.maybebytestr, meta)
+ smeta = pycompat.rapply(pycompat.maybebytestr, meta)
fm.write('metadata', '{%s}', fm.formatdict(smeta, fmt='%r: %r', sep=', '))
fm.plain('\n')
--- a/mercurial/pycompat.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/pycompat.py Sun Jun 10 17:07:29 2018 +0900
@@ -47,6 +47,39 @@
def identity(a):
return a
+def _rapply(f, xs):
+ if xs is None:
+ # assume None means non-value of optional data
+ return xs
+ if isinstance(xs, (list, set, tuple)):
+ return type(xs)(_rapply(f, x) for x in xs)
+ if isinstance(xs, dict):
+ return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
+ return f(xs)
+
+def rapply(f, xs):
+ """Apply function recursively to every item preserving the data structure
+
+ >>> def f(x):
+ ... return 'f(%s)' % x
+ >>> rapply(f, None) is None
+ True
+ >>> rapply(f, 'a')
+ 'f(a)'
+ >>> rapply(f, {'a'}) == {'f(a)'}
+ True
+ >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
+ ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
+
+ >>> xs = [object()]
+ >>> rapply(identity, xs) is xs
+ True
+ """
+ if f is identity:
+ # fast path mainly for py2
+ return xs
+ return _rapply(f, xs)
+
if ispy3:
import builtins
import functools
--- a/mercurial/revset.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/revset.py Sun Jun 10 17:07:29 2018 +0900
@@ -112,7 +112,7 @@
return None
def _sortedb(xs):
- return sorted(util.rapply(pycompat.maybebytestr, xs))
+ return sorted(pycompat.rapply(pycompat.maybebytestr, xs))
# operator methods
--- a/mercurial/scmutil.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/scmutil.py Sun Jun 10 17:07:29 2018 +0900
@@ -865,7 +865,7 @@
continue
from . import bookmarks # avoid import cycle
repo.ui.debug('moving bookmarks %r from %s to %s\n' %
- (util.rapply(pycompat.maybebytestr, oldbmarks),
+ (pycompat.rapply(pycompat.maybebytestr, oldbmarks),
hex(oldnode), hex(newnode)))
# Delete divergent bookmarks being parents of related newnodes
deleterevs = repo.revs('parents(roots(%ln & (::%n))) - parents(%n)',
--- a/mercurial/smartset.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/smartset.py Sun Jun 10 17:07:29 2018 +0900
@@ -29,7 +29,7 @@
if r is None:
return ''
elif isinstance(r, tuple):
- return r[0] % util.rapply(pycompat.maybebytestr, r[1:])
+ return r[0] % pycompat.rapply(pycompat.maybebytestr, r[1:])
elif isinstance(r, bytes):
return r
elif callable(r):
--- a/mercurial/ui.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/ui.py Sun Jun 10 17:07:29 2018 +0900
@@ -156,10 +156,10 @@
}
def _maybestrurl(maybebytes):
- return util.rapply(pycompat.strurl, maybebytes)
+ return pycompat.rapply(pycompat.strurl, maybebytes)
def _maybebytesurl(maybestr):
- return util.rapply(pycompat.bytesurl, maybestr)
+ return pycompat.rapply(pycompat.bytesurl, maybestr)
class httppasswordmgrdbproxy(object):
"""Delays loading urllib2 until it's needed."""
--- a/mercurial/util.py Thu Jul 05 09:53:00 2018 +0530
+++ b/mercurial/util.py Sun Jun 10 17:07:29 2018 +0900
@@ -131,39 +131,6 @@
_notset = object()
-def _rapply(f, xs):
- if xs is None:
- # assume None means non-value of optional data
- return xs
- if isinstance(xs, (list, set, tuple)):
- return type(xs)(_rapply(f, x) for x in xs)
- if isinstance(xs, dict):
- return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
- return f(xs)
-
-def rapply(f, xs):
- """Apply function recursively to every item preserving the data structure
-
- >>> def f(x):
- ... return 'f(%s)' % x
- >>> rapply(f, None) is None
- True
- >>> rapply(f, 'a')
- 'f(a)'
- >>> rapply(f, {'a'}) == {'f(a)'}
- True
- >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
- ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
-
- >>> xs = [object()]
- >>> rapply(pycompat.identity, xs) is xs
- True
- """
- if f is pycompat.identity:
- # fast path mainly for py2
- return xs
- return _rapply(f, xs)
-
def bitsfrom(container):
bits = 0
for bit in container: