Skip to content

Commit

Permalink
Add command line option for running 6S binary in subprocess
Browse files Browse the repository at this point in the history
  • Loading branch information
brianschubert committed Sep 10, 2023
1 parent 90bd1b2 commit 1842e63
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/sixs_bin/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import argparse
import pathlib
import subprocess
import sys

import sixs_bin
Expand Down Expand Up @@ -45,6 +46,13 @@ def _make_parser() -> argparse.ArgumentParser:
choices=sixs_bin._SIXS_BINARIES.keys(),
help="Print the path to the specified 6S executable from this package's resources.",
)
command_group.add_argument(
"--exec",
choices=sixs_bin._SIXS_BINARIES.keys(),
help="Execute specified 6S executable in a subprocess, inheriting stdin and stdout. This option is provided"
" as a convenience, but its use is not recommended. Running 6S using this option is about 5%% slower than"
" executing the binary directly, due the overhead of starting the Python interpreter and subprocess.",
)
command_group.add_argument(
"--test-wrapper",
action="store_true",
Expand All @@ -68,6 +76,13 @@ def main(cli_args: list[str]) -> None:
print(_make_version())
return

if args.exec is not None:
proc_args = (sixs_bin.get_path(args.exec),)
ret_code = subprocess.Popen(proc_args).wait()
if ret_code:
raise subprocess.CalledProcessError(ret_code, proc_args)
return

if args.path is not None:
print(sixs_bin.get_path(args.path))
return
Expand Down
44 changes: 44 additions & 0 deletions test/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
import subprocess
import sys
from typing import Any

import pytest

import sixs_bin
import sixs_bin._cli as sixs_cli


def _run_self_subprocess(
cli_args: list[str], **kwargs: Any
) -> subprocess.CompletedProcess:
"""
Run the command line interface in a subprocess.
Needed instead of calling the CLI entrypoint directly when more advanced control
over the process running the command line interface is required.
"""
return subprocess.run(
[sys.executable, "-m", sixs_bin.__name__, *cli_args], **kwargs
)


def test_version(capsys) -> None:
sixs_cli.main(["--version"])

Expand All @@ -29,5 +47,31 @@ def test_bad_path() -> None:
sixs_cli.main(["--path"])


@pytest.mark.parametrize("version", sixs_bin._SIXS_BINARIES.keys())
def test_exec_eof(version) -> None:
with pytest.raises(subprocess.CalledProcessError) as exec_info:
# Run in subprocess to reliably control stdin.
_run_self_subprocess(
["--exec", version],
check=True,
capture_output=True,
text=True,
input="", # Empty stdin
)

assert exec_info.value.stdout == ""
assert (
exec_info.value.stderr.splitlines()[1] == "Fortran runtime error: End of file"
)


def test_exec_bad() -> None:
with pytest.raises(SystemExit):
sixs_cli.main(["--exec", "does-not-exist"])

with pytest.raises(SystemExit):
sixs_cli.main(["--exec"])


def test_test_wrapper() -> None:
sixs_cli.main(["--test-wrapper"])

0 comments on commit 1842e63

Please sign in to comment.