def run(self, params, exercise, silent=False, env=os.environ):
out, err, code = "<STR_LIT>", "<STR_LIT>", -<NUM_LIT:1><EOL>@Spinner.decorate("<STR_LIT>" if not silent else "<STR_LIT>",<EOL>waitmsg="<STR_LIT>" + self.name)<EOL>def inner():<EOL><INDENT>ret = Popen(params, stdout=PIPE, stderr=PIPE, cwd=exercise.path(),<EOL>env=env)<EOL>out, err = ret.communicate()<EOL>return (out.decode("<STR_LIT:utf-8>", "<STR_LIT>"),<EOL>err.decode("<STR_LIT:utf-8>", "<STR_LIT>"),<EOL>ret.returncode)<EOL><DEDENT>try:<EOL><INDENT>out, err, code = inner()<EOL><DEDENT>except OSError as e:<EOL><INDENT>if e.errno in [os.errno.ENOENT, os.errno.EACCES]:<EOL><INDENT>raise MissingProgram(params[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>raise e<EOL><DEDENT><DEDENT>return code, out, err<EOL>
Run a program with Popen and handle common errors
:param params: Parameter list to Popen
:param exercise:
:return: returncode, stdout, stderr