From 3607d94422b02c8c97d3540aa70829cd789adb82 Mon Sep 17 00:00:00 2001 From: ReinerBRO <593493640@qq.com> Date: Thu, 19 Mar 2026 02:33:18 +0800 Subject: [PATCH] Fix LazyChoices eager loading during default validation --- httpie/cli/utils.py | 5 +++++ tests/test_cli_utils.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/httpie/cli/utils.py b/httpie/cli/utils.py index ad27da37f7..2c3cadaf9c 100644 --- a/httpie/cli/utils.py +++ b/httpie/cli/utils.py @@ -67,6 +67,11 @@ def help(self, value: Any) -> None: self._help = value def __contains__(self, item: Any) -> bool: + # Python 3.14 may validate option defaults against `choices` + # during parser setup. Avoid loading dynamic choices for + # validating this action's own default value. + if self._obj is None and item == self.default: + return True return item in self.load() def __iter__(self) -> Iterator[T]: diff --git a/tests/test_cli_utils.py b/tests/test_cli_utils.py index 8041727b57..cf1c203563 100644 --- a/tests/test_cli_utils.py +++ b/tests/test_cli_utils.py @@ -84,3 +84,33 @@ def test_lazy_choices_help(): with pytest.raises(SystemExit): parser.parse_args(['--help']) help_formatter.assert_called_once_with(['a', 'b', 'c'], isolation_mode=False) + + +def test_lazy_choices_default_validation_does_not_load_choices(): + mock = Mock() + getter = mock.getter + getter.return_value = ['a', 'b', 'c'] + + parser = ArgumentParser() + parser.register('action', 'lazy_choices', LazyChoices) + parser.add_argument( + '--lazy-option', + default='a', + metavar='SYMBOL', + action='lazy_choices', + getter=getter, + cache=False, # for test purposes + ) + + action = next( + action for action in parser._actions + if action.dest == 'lazy_option' + ) + + # Simulate default validation (as in Python 3.14 parser setup) + # and ensure it does not trigger eager loading. + parser._check_value(action, 'a') + getter.assert_not_called() + + parser._check_value(action, 'b') + getter.assert_called_once()