Skip to content
Closed
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
36 changes: 22 additions & 14 deletions cli/openbb_cli/controllers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1054,20 +1054,28 @@ def request(
def parse_unknown_args_to_dict(unknown_args: list[str] | None) -> dict[str, str]:
"""Parse unknown arguments to a dictionary."""
unknown_args_dict = {}
if unknown_args:
for idx, arg in enumerate(unknown_args):
if arg.startswith("--"):
if idx + 1 < len(unknown_args):
try:
unknown_args_dict[arg.replace("--", "")] = ast.literal_eval(
unknown_args[idx + 1]
)
except (ValueError, SyntaxError):
unknown_args_dict[arg.replace("--", "")] = unknown_args[idx + 1]
else:
session.console.print(
f"Missing value for argument {arg}. Skipping this argument."
)
arguments = iter(unknown_args or [])
pending = None
while True:
arg = pending if pending is not None else next(arguments, None)
pending = None
if arg is None:
break
if not arg.startswith("--"):
continue
name, equals, value = arg[2:].partition("=")
if not equals:
value = next(arguments, None)
if value is None or value.startswith("--"):
session.console.print(
f"Missing value for argument {arg}. Skipping this argument."
)
pending = value
continue
try:
unknown_args_dict[name] = ast.literal_eval(value)
except (ValueError, SyntaxError):
unknown_args_dict[name] = value
return unknown_args_dict


Expand Down
19 changes: 19 additions & 0 deletions cli/tests/test_unknown_option_value_boundaries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""CLI option parsing must preserve distinct flag/value pairs."""

import pytest

from openbb_cli.controllers.utils import parse_unknown_args_to_dict


@pytest.mark.parametrize(
"args,expected",
[
(["--missing", "--symbol", "AAPL"], {"symbol": "AAPL"}),
(["--limit=5", "--symbol=AAPL"], {"limit": 5, "symbol": "AAPL"}),
(["--threshold", "-2.5"], {"threshold": -2.5}),
(["--label=--literal"], {"label": "--literal"}),
(["--some--name", "value"], {"some--name": "value"}),
],
)
def test_unknown_option_value_boundaries(args, expected):
assert parse_unknown_args_to_dict(args) == expected