fix(config-ini): strip inline # and ; comments from values
The module docstring teaches inline comments — `mode = master # or
"agent"` is the canonical example for the [decnet] section. Python's
configparser ignores those by default unless inline_comment_prefixes
is set explicitly, so the comment became part of the value and
downstream validators rejected it ("mode must be 'agent' or 'master',
got 'master # or \"agent\"'").
Hit live on first VPS deploy: every CLI invocation crashed at import
time with a stack trace that didn't make it obvious the docstring's
example was the trigger. Now the parser does what the docs promise.
This commit is contained in:
@@ -158,7 +158,14 @@ def load_ini_config(path: Optional[Path] = None) -> Optional[Path]:
|
|||||||
if not path.is_file():
|
if not path.is_file():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
parser = configparser.ConfigParser()
|
# The docstring at the top of this module advertises inline ``#`` and
|
||||||
|
# ``;`` comments (e.g. ``mode = master # or "agent"``). Python's
|
||||||
|
# ``configparser`` only recognises those when ``inline_comment_prefixes``
|
||||||
|
# is set explicitly — without it, the comment becomes part of the value
|
||||||
|
# and downstream validators reject it ("mode must be 'agent' or 'master',
|
||||||
|
# got 'master # or \"agent\"'"). Match what the docs
|
||||||
|
# promise.
|
||||||
|
parser = configparser.ConfigParser(inline_comment_prefixes=("#", ";"))
|
||||||
parser.read(path)
|
parser.read(path)
|
||||||
|
|
||||||
# [decnet] first — mode/disallow-master/log-directory. These seed the
|
# [decnet] first — mode/disallow-master/log-directory. These seed the
|
||||||
|
|||||||
@@ -27,6 +27,24 @@ def test_missing_file_is_noop(monkeypatch, tmp_path):
|
|||||||
assert "DECNET_AGENT_PORT" not in os.environ
|
assert "DECNET_AGENT_PORT" not in os.environ
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_comments_stripped_from_values(monkeypatch, tmp_path):
|
||||||
|
"""The module docstring teaches inline ``#`` comments — the parser
|
||||||
|
must accept them. Hit live on the first VPS deploy 2026-04-28: a
|
||||||
|
``mode = master # or "agent"`` line caused the value to be parsed
|
||||||
|
as ``master # or "agent"`` and downstream
|
||||||
|
validators rejected it."""
|
||||||
|
_scrub(monkeypatch, "DECNET_MODE", "DECNET_API_PORT")
|
||||||
|
ini = _write_ini(tmp_path, """
|
||||||
|
[decnet]
|
||||||
|
mode = master # inline hash comment
|
||||||
|
[master]
|
||||||
|
api-port = 8000 ; inline semi comment
|
||||||
|
""")
|
||||||
|
load_ini_config(ini)
|
||||||
|
assert os.environ["DECNET_MODE"] == "master"
|
||||||
|
assert os.environ["DECNET_API_PORT"] == "8000"
|
||||||
|
|
||||||
|
|
||||||
def test_agent_section_only_loaded_when_mode_agent(monkeypatch, tmp_path):
|
def test_agent_section_only_loaded_when_mode_agent(monkeypatch, tmp_path):
|
||||||
_scrub(
|
_scrub(
|
||||||
monkeypatch,
|
monkeypatch,
|
||||||
|
|||||||
Reference in New Issue
Block a user