Skip to content

Commit 40b8930

Browse files
authored
Fix environment variable parsing for store_true/store_false actions (#858)
1 parent 948d666 commit 40b8930

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ Fixed
3535
- ``--help`` no longer fails with ``IndexError`` for options without explicit
3636
help text while keeping ``argparse`` compatibility for ``help=None`` (`#854
3737
<https://github.com/omni-us/jsonargparse/pull/854>`__).
38+
- ``store_true`` and ``store_false`` arguments now parse boolean environment
39+
variable values as ``true``/``false`` and raise a clear error for invalid
40+
values (`#858 <https://github.com/omni-us/jsonargparse/pull/858>`__).
3841

3942
Changed
4043
^^^^^^^

jsonargparse/_core.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,16 @@ def _load_env_vars(self, env: Union[dict[str, str], os._Environ], defaults: bool
531531
env_var = get_env_var(self, action)
532532
if env_var in env and not isinstance(action, (ActionConfigFile, _ActionSubCommands)):
533533
env_val = env[env_var]
534-
if _is_action_value_list(action):
534+
if isinstance(action, (argparse._StoreTrueAction, argparse._StoreFalseAction)):
535+
if env_val == "true":
536+
env_val = True
537+
elif env_val == "false":
538+
env_val = False
539+
else:
540+
raise argparse.ArgumentError(
541+
action, f"Invalid boolean value for environment variable {env_var}: {env_val}"
542+
)
543+
elif _is_action_value_list(action):
535544
try:
536545
list_env_val = load_value(env_val)
537546
env_val = list_env_val if isinstance(list_env_val, list) else [env_val]

jsonargparse_tests/test_core.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@ def test_parse_env_positional_nargs_plus(parser):
281281
assert parser.parse_env({"APP_REQ": '[""","""]'}).req == ['[""","""]']
282282

283283

284+
def test_parse_env_store_true_false(parser):
285+
parser.env_prefix = "app"
286+
parser.add_argument("--flag_true", action="store_true")
287+
parser.add_argument("--flag_false", action="store_false")
288+
assert parser.parse_args([]) == Namespace(flag_true=False, flag_false=True)
289+
assert parser.get_defaults() == Namespace(flag_true=False, flag_false=True)
290+
assert parser.parse_env({"APP_FLAG_TRUE": "true"}).flag_true is True
291+
assert parser.parse_env({"APP_FLAG_TRUE": "false"}).flag_true is False
292+
assert parser.parse_env({"APP_FLAG_FALSE": "false"}).flag_false is False
293+
assert parser.parse_env({"APP_FLAG_FALSE": "true"}).flag_false is True
294+
with pytest.raises(ArgumentError, match="Invalid boolean value for environment variable APP_FLAG_TRUE: not_bool"):
295+
parser.parse_env({"APP_FLAG_TRUE": "not_bool"})
296+
with pytest.raises(ArgumentError, match="Invalid boolean value for environment variable APP_FLAG_FALSE: not_bool"):
297+
parser.parse_env({"APP_FLAG_FALSE": "not_bool"})
298+
299+
284300
def test_default_env_property():
285301
parser = ArgumentParser()
286302
assert False is parser.default_env

0 commit comments

Comments
 (0)