def __call__(self, *cmd_args, **kw):
        args = self.prefix_args + cmd_args
        rc = kw.pop('rc', None)
        out = kw.pop('out', None)
        err = kw.pop('err', None)
        stdin = kw.pop('stdin', None)
        if self.instance is None:
            log.debug('Executing locally:\n%s', args)
            popen_kw = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            if stdin is not None:
                popen_kw['stdin'] = subprocess.PIPE
            proc = subprocess.Popen(args, **popen_kw)
            _out, _err = proc.communicate(input=stdin)
            _rc = proc.returncode
        else:
            cmd = shjoin(args)
            log.debug('Executing on instance %s:\n%s', self.instance.uid, cmd)
            chan = self.instance.conn.get_transport().open_session()
            if stdin is not None:
                rin = chan.makefile('wb', -1)
            rout = chan.makefile('rb', -1)
            rerr = chan.makefile_stderr('rb', -1)
            forward = None
            if self.instance.conn._ploy_forward_agent:
                forward = self.instance.paramiko.agent.AgentRequestHandler(chan)
            chan.exec_command(cmd)
            if stdin is not None:
                rin.write(stdin)
                rin.flush()
                chan.shutdown_write()
            _out = rout.read()
            _err = rerr.read()
            _rc = chan.recv_exit_status()
            chan.close()
            if forward is not None:
                forward.close()
        result = []
        if rc is None:
            result.append(_rc)
        else:
            try:
                if not any(x == _rc for x in rc):
                    raise subprocess.CalledProcessError(_rc, ' '.join(args), _err)
            except __HOLE__:
                pass
            if rc != _rc:
                raise subprocess.CalledProcessError(_rc, ' '.join(args), _err)
        if out is None:
            if self.splitlines:
                _out = _out.splitlines()
            result.append(_out)
        else:
            if out != _out:
                if _rc == 0:
                    log.error(_out)
                raise subprocess.CalledProcessError(_rc, ' '.join(args), _err)
        if err is None:
            if self.splitlines:
                _err = _err.splitlines()
            result.append(_err)
        else:
            if err != _err:
                if _rc == 0:
                    log.error(_err)
                raise subprocess.CalledProcessError(_rc, ' '.join(args), _err)
        if len(result) == 0:
            return
        elif len(result) == 1:
            return result[0]
        return tuple(result)
dataset/ETHPy150Open ployground/ploy/ploy/common.py/Executor.__call__