Found during the 2026-09-26 cloud sweep. Not fixed there because it interacts with a dependent (see below) and the sweep's code scope was limited to #13 and #16.
Reproduction (config2py 0.1.54)
import builtins, getpass
from config2py.util import ask_user_for_input
answers = iter(["", "typed"]) # first "" toggles masking, then the value
builtins.input = getpass.getpass = lambda p: next(answers)
ask_user_for_input("q", masking_toggle_str="", egress=str.upper)
# 'typed' <- expected 'TYPED': the recursive call in the toggle branch does not pass egress
ask_user_for_input("")
# IndexError: string index out of range <- `prompt[-1]` on an empty prompt
Dependent interaction to check before fixing
oa/util.py (get_api_key_from_config) calls ask_user_for_input(..., mask_input=True, masking_toggle_str="", egress=lambda v: store.__setitem__(k, v)). Today, toggling skips that egress, so the key is returned but never saved. After the fix it is saved, but the lambda returns None, so oa would get None on the toggle path, exactly as it already does on the direct path. oa's egress should return the value (store.__setitem__(k, v) or v); fix both together.
Proposed fix
- Pass
egress=egress in the recursive call.
- Use
if not prompt.endswith(" "): instead of prompt[-1] != " ".
- Tests: toggle path applies egress; empty prompt works.
Found during the 2026-09-26 cloud sweep. Not fixed there because it interacts with a dependent (see below) and the sweep's code scope was limited to #13 and #16.
Reproduction (config2py 0.1.54)
Dependent interaction to check before fixing
oa/util.py(get_api_key_from_config) callsask_user_for_input(..., mask_input=True, masking_toggle_str="", egress=lambda v: store.__setitem__(k, v)). Today, toggling skips that egress, so the key is returned but never saved. After the fix it is saved, but the lambda returnsNone, sooawould getNoneon the toggle path, exactly as it already does on the direct path.oa's egress should return the value (store.__setitem__(k, v) or v); fix both together.Proposed fix
egress=egressin the recursive call.if not prompt.endswith(" "):instead ofprompt[-1] != " ".