Skip to content

Fix LazyChoices for Python 3.14+ β€” avoid eager getter call during parser registration#1894

Open
driphtyio wants to merge 1 commit into
httpie:masterfrom
driphtyio:fix/lazy-choices-python-3.14
Open

Fix LazyChoices for Python 3.14+ β€” avoid eager getter call during parser registration#1894
driphtyio wants to merge 1 commit into
httpie:masterfrom
driphtyio:fix/lazy-choices-python-3.14

Conversation

@driphtyio

Copy link
Copy Markdown

Problem

On Python 3.14+, argparse validates that default is in choices at argument registration time (in add_argument()). The LazyChoices class was setting self.choices = self, which caused argparse to call __contains__ β†’ load() β†’ getter() during parser construction β€” triggering the getter prematurely.

This broke the invariant in test_lazy_choices_help that the getter must not be called during parser initialization.

Fixes #1641.

Solution

Two simple changes:

  1. Removed self.choices = self β€” without it, action.choices stays None (argparse default), so Python 3.14's registration-time check is skipped entirely.

  2. Moved validation into __call__ β€” when a user-provided value reaches the action handler, we call self.load() (which triggers the getter) and raise ArgumentError if the value isn't valid.

The lazy-loading contract is preserved: the getter is only called when a value is actually parsed or help is displayed.

Testing

  • test_lazy_choices β€” passes (invalid choice still raises SystemExit)
  • test_lazy_choices_help β€” passes (getter not called during init)
  • test_parser_serialization β€” passes
  • Full test suite: 260 passed, 1 pre-existing failure (unrelated encoding test)

Remove self.choices = self to prevent argparse from eagerly
validating default values at registration time (Python 3.14
behavior change). Move choice validation into __call__ instead.

Fixes httpie#1641
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test_lazy_choices_help fails on Python 3.14

1 participant