def test_parse_no_shebang_from_binary(self):
     """Handle binaries."""
     self.assertEqual(parse(_from_filename(struct.pack("2i",
                                                       *(99999, 99999)),
                                           self.addCleanup,
                                           mode="wb")),
                      [])
    def test_parse_multi_part_shebang_linux(self, mode):
        """Parse a multi-part shebang, keeping env."""
        if platform.system() == "Windows":
            self.skipTest("""Keeping env only makes sense on POSIX.""")

        self.assertEqual(parse(mode("#!/usr/bin/env python\n",
                                    self.addCleanup)),
                         ["/usr/bin/env", "python"])
    def test_parse_multi_part_shebang_windows_nonenv(self, mode):
        """Parse a multi-part shebang, keeping non-env."""
        if platform.system() != "Windows":
            self.skipTest("""Discarding env only makes sense on Windows.""")

        self.assertEqual(parse(mode("#!/usr/bin/nonenv python\n",
                                    self.addCleanup)),
                         ["/usr/bin/nonenv", "python"])
    def test_filename_without_extension(self):
        """Regression test for no-PATHEXT no-extension."""
        tmpdir = mkdtemp()
        self.addCleanup(shutil.rmtree, tmpdir)

        filename = os.path.join(tmpdir, u"foo")
        with io.open(filename, "w") as f:
            f.write(u"#!/usr/bin/python\n")

        self.assertEqual(parse(filename), ["/usr/bin/python"])
    def test_unicode(self):
        """A filename can be text which in python 2 is not `str`."""
        tmpdir = mkdtemp()
        self.addCleanup(shutil.rmtree, tmpdir)

        filename = os.path.join(tmpdir, u"foo.sh")
        with io.open(filename, "w") as f:
            f.write(u"#!/usr/bin/python\n")

        self.assertEqual(parse(filename), ["/usr/bin/python"])
    def test_popen_script(self):
        """Run a python script with subprocess.check_call."""
        script = ("#!/usr/bin/env python\n"
                  "import sys\n"
                  "sys.exit(0)\n")
        tempdir = mkdtemp(dir=os.getcwd(), prefix="parseshebang_acceptance")
        self.addCleanup(shutil.rmtree, tempdir)
        with open(os.path.join(tempdir, "script.py"), "w") as script_file:
            script_file.write(script)

        os.chmod(script_file.name,
                 os.stat(script_file.name).st_mode |
                 stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

        shebang = parse(script_file.name)
        self.assertEqual(subprocess.check_call(shebang + [script_file.name]),
                         0)
예제 #7
0
def _run_cmd(cmd):
    """Run command specified by :cmd: and return stdout, stderr and code."""
    if not os.path.exists(cmd[0]):
        cmd[0] = shutil.which(cmd[0])
        assert cmd[0] is not None

    shebang_parts = parseshebang.parse(cmd[0])

    proc = subprocess.Popen(shebang_parts + cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    return {
        "stdout": stdout,
        "stderr": stderr,
        "code": proc.returncode
    }
 def test_parse_single_part_shebang(self, mode):
     """Parse a single-part shebang."""
     self.assertEqual(parse(mode("#!python\n", self.addCleanup)),
                      ["python"])
 def test_throw_runtime_error_when_weird_object_passed(self):
     """Raise RuntimeError when weird object is passed in."""
     with ExpectedException(RuntimeError):
         parse(object())
 def test_no_parse_shebang_if_in_pathext(self):
     """Don't parse shebang from file if extension is in PATHEXT."""
     os.environ["PATHEXT"] = ".py"
     self.assertEqual(parse(_from_filename("#!python",
                                           self.addCleanup)),
                      [])
 def test_parse_no_shebang(self, mode):
     """Parse no shebang."""
     self.assertEqual(parse(mode("", self.addCleanup)),
                      [])
    def execute(self,
                argv,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                output_modifier=None,
                live_output=False,
                env=None,
                **kwargs):
        """Execute the process and arguments indicated by argv in container."""
        (argv, prepend_env,
         overwrite_env) = self._subprocess_popen_arguments(argv, **kwargs)

        # Update overwrite_env with any values that the user may
        # have provided in env
        overwrite_env.update(env or {})

        with updated_environ(prepend_env, overwrite_env) as environment:
            if not os.path.exists(argv[0]):
                abs_argv0 = shutil.which(argv[0])
                if abs_argv0 is None:
                    raise RuntimeError(
                        _not_found_binary_error_msg(argv[0],
                                                    os.environ.get("PATH",
                                                                   "")))
                argv[0] = abs_argv0

            # Also use which to find the shebang program - in some cases
            # we may only have the name of a program but not where it
            # actually exists. This is necessary on some platforms like
            # Windows where PATH is read from its state as it existed
            # when this process got created, not at the time Popen was
            # called.
            argv = parseshebang.parse(str(argv[0])) + argv
            if not os.path.exists(argv[0]):
                abs_argv0 = shutil.which(argv[0])
                if abs_argv0 is None:
                    raise RuntimeError(
                        _not_found_binary_error_msg(argv[0],
                                                    os.environ.get("PATH",
                                                                   "")))
                argv[0] = abs_argv0

            executed_cmd = subprocess.Popen(argv,
                                            stdout=stdout,
                                            stderr=stderr,
                                            env=environment,
                                            universal_newlines=True)

            # Monitor stdout and stderr. We allow live output for
            # stdout, but not for stderr (so that it gets printed
            # at the end)
            stdout_monitor = output.monitor(executed_cmd.stdout,
                                            modifier=output_modifier,
                                            live=live_output)
            stderr_monitor = output.monitor(executed_cmd.stderr,
                                            modifier=output_modifier,
                                            live=False)

            try:
                executed_cmd.wait()
            finally:
                stdout_data = stdout_monitor().read()
                stderr_data = stderr_monitor().read()

        return (executed_cmd.returncode, stdout_data, stderr_data)
 def test_parse_multi_part_shebang_extra_spaces(self, mode):
     """Parse a multi-part shebang, keeping non-env."""
     self.assertEqual(parse(mode("#!/usr/bin/nonenv    python\n",
                                 self.addCleanup)),
                      ["/usr/bin/nonenv", "python"])