fix: Correctly parse boolean config options set to false

Previously, when parsing config options that were set to 'false',
e.g. `TOPEN_NOTES_QUIET=false` in the env vars,
we would still be setting it to true.

This change fixes any falsy value to be correctly parsed as False.
This commit is contained in:
Marty Oehme 2025-11-29 10:58:34 +01:00
parent 6517eb3971
commit ff0e6cccfb
Signed by: Marty
GPG key ID: 4E535BC19C61886E
2 changed files with 46 additions and 3 deletions

View file

@ -63,6 +63,16 @@ class TestEnv:
assert env["task_rc"] == Path("/a/dir/that/dont/exist/file")
assert env["task_data"] == Path("~/somewhere/tasks")
def test_env_parses_boolean_true(self, isolate_env, monkeypatch):
monkeypatch.setenv("TOPEN_NOTES_QUIET", "true")
env = parse_env()
assert env["notes_quiet"] is True
def test_env_parses_boolean_false(self, isolate_env, monkeypatch):
monkeypatch.setenv("TOPEN_NOTES_QUIET", "false")
env = parse_env()
assert env["notes_quiet"] is False
@pytest.fixture
def fake_rc(tmp_path: Path, monkeypatch):
@ -89,6 +99,20 @@ class TestRcFile:
assert rc_cfg["notes_editor"] == "micro"
assert rc_cfg["notes_quiet"] is True
def test_taskrc_parses_boolean_true(self, fake_rc):
fake_rc.write_text("""
notes.quiet=true
""")
rc_cfg = parse_rc(fake_rc)
assert rc_cfg["notes_quiet"] is True
def test_taskrc_parses_boolean_false(self, fake_rc):
fake_rc.write_text("""
notes.quiet=false
""")
rc_cfg = parse_rc(fake_rc)
assert rc_cfg["notes_quiet"] is False
class TestTConf:
def test_paths_are_expanded(self):

View file

@ -23,7 +23,7 @@ import subprocess
import sys
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any, Self, cast
from typing import Any, Callable, Self, cast
from tasklib import Task, TaskWarrior
@ -130,8 +130,9 @@ class Opt:
rc: str | None
default: Any = None
metavar: str | None = None
cast: type = str
cast: type | Callable = str
help_text: str = ""
flag: bool = False
def _real_path(p: Path | str) -> Path:
@ -146,6 +147,24 @@ def _determine_default_task_rc() -> Path:
return _real_path("~/.config/task/taskrc")
def _strtobool(val: str) -> bool:
"""Convert a string representation of truth.
Coverts either to True or False, raising an error if it does not find a
valid value.
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n',
'no', 'f', 'false', 'off', and '0'.
Raises ValueError if 'val' is anything else.
"""
val = val.lower()
if val in ("y", "yes", "t", "true", "on", "1"):
return True
elif val in ("n", "no", "f", "false", "off", "0"):
return False
else:
raise ValueError(f"Invalid boolean value {val}")
OPTIONS: dict[str, Opt] = {
"task_id": Opt(None, None, None, default=None),
"task_rc": Opt(
@ -204,7 +223,7 @@ OPTIONS: dict[str, Opt] = {
"TOPEN_NOTES_QUIET",
"notes.quiet",
default=False,
cast=bool,
cast=_strtobool,
help_text="Silence any verbose displayed information",
),
}