'Wraps an existing function f, and transforms
path arguments to "resolved paths" and
user arguments to uids.
By default transforms the first (zeroth) argument as
a path, but can be customized.
This lets us write:
def open(self, name, mode="r"):
return open(self._resolve_path(name), mode)
as
open = _wrap(__builtin__.open)
NOTE: No transformation is done on the keyword args;
they are not accepted.  (The alternative would be to
require the names of the keyword transformations.)'

def _wrap(f, paths=None, users=None, groups=None):

    if (users is None):
        users = []
    if (groups is None):
        groups = []
    if ((paths is None) and (0 not in users) and (0 not in groups)):
        paths = [0]
    assert (not reduce(set.intersection, map(set, [paths, users, groups])))
    def wrapped(*args):
        self = args[0]
        newargs = list(args[1:])
        for i in paths:
            newargs[i] = self._resolve_path(newargs[i])
        for i in users:
            newargs[i] = pwd.getpwnam(newargs[i]).pw_uid
        for i in groups:
            newargs[i] = grp.getgrnam(newargs[i]).gr_gid
        return f(*newargs)
    return wrapped
