Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions scripts/nvx_tools/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,7 @@ def configure_parser(


def positive_int(value: str) -> int:
parsed = int(value)
if parsed < 1:
raise argparse.ArgumentTypeError("must be at least 1")
return parsed
return common.positive_int(value, message="must be at least 1")


def apply_benchmark_suite_defaults(args: argparse.Namespace) -> None:
Expand Down
4 changes: 2 additions & 2 deletions scripts/nvx_tools/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ def strict_json_object(pairs: list[tuple[str, object]]) -> dict[str, object]:
return result


def positive_int(value: str) -> int:
def positive_int(value: str, *, message: str = "must be greater than zero") -> int:
parsed = int(value)
if parsed <= 0:
raise argparse.ArgumentTypeError("must be greater than zero")
raise argparse.ArgumentTypeError(message)
return parsed


Expand Down
19 changes: 19 additions & 0 deletions scripts/test_nvx_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,21 @@ def test_benchmark_preserves_canonical_shell_memory_defaults(self):

self.assertEqual(args.shell_memories, [128, 256, 512])

def test_benchmark_positive_integer_diagnostics_are_stable(self):
for value, message in (
("not-an-int", "argument --runs: invalid positive_int value: 'not-an-int'"),
("0", "argument --runs: must be at least 1"),
):
with self.subTest(value=value):
with (
patch("sys.stderr", new_callable=io.StringIO) as errors,
self.assertRaises(SystemExit) as exit_context,
):
nvx.parse_args(["benchmark", "--runs", value])

self.assertEqual(exit_context.exception.code, 2)
self.assertIn(message, errors.getvalue())

def test_release_commands_keep_their_cli_contract(self):
download = nvx.parse_args(
["download", "--repository", "example/nvx", "--hypervisor", "auto"]
Expand Down Expand Up @@ -11858,6 +11873,10 @@ def test_rejects_non_integer_input(self):
with self.assertRaises(ValueError):
common.positive_int("not-an-int")

def test_accepts_custom_error_message(self):
with self.assertRaisesRegex(argparse.ArgumentTypeError, "^must be at least 1$"):
common.positive_int("0", message="must be at least 1")


class PositiveFloatTests(unittest.TestCase):
def test_accepts_positive_finite_float(self):
Expand Down
Loading