def __init__( self, args, *, block=True, encoding=DEFAULT_ENCODING, env=None, timeout=None, **other_kwargs ): self.blocking = block self.env = env self.script = Script.parse(args) if env is not None: env = dict(os.environ, **env) other_kwargs["env"] = env other_kwargs["stdout"] = subprocess.PIPE other_kwargs["stderr"] = subprocess.PIPE self._process = subprocess.Popen( args, universal_newlines=True, encoding=encoding, **other_kwargs ) self._endtime = None if timeout is not None: self._endtime = _time() + timeout self.out_buffer = [] self.err_buffer = [] self._start_polling()
def run_command(cmd, *args, is_verbose=False, **kwargs): """ Take an input command and run it, handling exceptions and error codes and returning its stdout and stderr. :param cmd: The list of command and arguments. :type cmd: list :returns: A 2-tuple of the output and error from the command :rtype: Tuple[str, str] :raises: exceptions.PipenvCmdError """ from pipenv._compat import decode_for_output from pipenv.cmdparse import Script catch_exceptions = kwargs.pop("catch_exceptions", True) if isinstance(cmd, ((str,), list, tuple)): cmd = Script.parse(cmd) if not isinstance(cmd, Script): raise TypeError("Command input must be a string, list or tuple") if "env" not in kwargs: kwargs["env"] = os.environ.copy() kwargs["env"]["PYTHONIOENCODING"] = "UTF-8" command = [cmd.command, *cmd.args] if is_verbose: click_echo(f"Running command: $ {cmd.cmdify()}") c = subprocess_run(command, *args, **kwargs) if is_verbose: click_echo( "Command output: {}".format(crayons.cyan(decode_for_output(c.stdout))), err=True, ) if c.returncode and catch_exceptions: raise PipenvCmdError(cmd.cmdify(), c.stdout, c.stderr, c.returncode) return c
def resolve(cmd, sp, project): from pipenv._compat import decode_output from pipenv.cmdparse import Script from pipenv.vendor.vistir.misc import echo c = subprocess_run(Script.parse(cmd).cmd_args, block=False, env=os.environ.copy()) is_verbose = project.s.is_verbose() err = "" for line in iter(c.stderr.readline, ""): line = decode_output(line) if not line.rstrip(): continue err += line if is_verbose: sp.hide_and_write(line.rstrip()) c.wait() returncode = c.poll() out = c.stdout.read() if returncode != 0: sp.red.fail( environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!")) echo(out.strip(), err=True) if not is_verbose: echo(err, err=True) sys.exit(returncode) if is_verbose: echo(out.strip(), err=True) return subprocess.CompletedProcess(c.args, returncode, out, err)
def build_script(self, name, extra_args=None): # type: (str, Optional[List[str]]) -> Script try: script = Script.parse(self.parsed_pipfile["scripts"][name]) except KeyError: script = Script(name) if extra_args: script.extend(extra_args) return script
def test_cmdify_complex(): script = Script.parse(' '.join([ '"C:\\Program Files\\Python36\\python.exe" -c', """ "print(\'Double quote: \\\"\')" """.strip(), ])) assert script.cmdify() == ' '.join([ '"C:\\Program Files\\Python36\\python.exe"', '"-c"', """ "print(\'Double quote: \\\"\')" """.strip(), ]), script
def test_cmdify_quote_if_paren_in_command(): """Ensure ONLY the command is quoted if it contains parentheses. """ script = Script.parse(' '.join([ '"C:\\Python36(x86)\\python.exe"', '-c', "print(123)", ])) assert script.cmdify() == ' '.join([ '"C:\\Python36(x86)\\python.exe"', '-c', "print(123)", ]), script
def test_parse(): script = Script.parse(['python', '-c', "print('hello')"]) assert script.command == 'python' assert script.args == ['-c', "print('hello')"], script
def test_parse_error(): with pytest.raises(ScriptEmptyError) as e: Script.parse('') assert str(e.value) == "[]"