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)
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"])