cli icon indicating copy to clipboard operation
cli copied to clipboard

test_lazy_choices_help fails on Python 3.14

Open hroncok opened this issue 5 months ago • 2 comments

Checklist

  • [x] I've searched for similar issues.
  • [x] I'm using the latest version of HTTPie (from git HEAD)

Minimal reproduction code and steps

This is with Python 3.14.0b3 and b4 alike.

uv venv --python=python3.14 venv
. venv/bin/activate
uv pip install '.[dev]'
uv pip install -U httpbin flask werkzeug  # to support Python 3.14
python -m pytest --verbose -k test_lazy_choices_help

Current result

============================= test session starts ==============================
platform linux -- Python 3.14.0b3, pytest-8.4.1, pluggy-1.6.0 -- .../httpie/venv/bin/python
cachedir: .pytest_cache
rootdir: .../httpie
configfile: pytest.ini
plugins: mock-3.14.1, httpbin-2.1.0, cov-6.2.1
collecting ... collected 1028 items / 1027 deselected / 1 selected

tests/test_cli_utils.py::test_lazy_choices_help FAILED                   [100%]

=================================== FAILURES ===================================
____________________________ test_lazy_choices_help ____________________________

self = <Mock name='mock.getter' id='140611738470112'>

    def assert_not_called(self):
        """assert that the mock was never called.
        """
        if self.call_count != 0:
            msg = ("Expected '%s' to not have been called. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
>           raise AssertionError(msg)
E           AssertionError: Expected 'getter' to not have been called. Called 1 times.
E           Calls: [call()].

/usr/lib64/python3.14/unittest/mock.py:946: AssertionError

During handling of the above exception, another exception occurred:

    def test_lazy_choices_help():
        mock = Mock()
        getter = mock.getter
        getter.return_value = ['a', 'b', 'c']
    
        help_formatter = mock.help_formatter
        help_formatter.return_value = '<my help>'
    
        parser = ArgumentParser()
        parser.register('action', 'lazy_choices', LazyChoices)
        parser.add_argument(
            '--lazy-option',
            default='a',
            metavar='SYMBOL',
            action='lazy_choices',
            getter=getter,
            help_formatter=help_formatter,
            cache=False  # for test purposes
        )
    
        # Parser initialization doesn't call it.
>       getter.assert_not_called()
E       AssertionError: Expected 'getter' to not have been called. Called 1 times.
E       Calls: [call()].

tests/test_cli_utils.py:73: AssertionError
=============================== warnings summary ===============================
httpie/cli/definition.py:526
  .../httpie/httpie/cli/definition.py:526: PendingDeprecationWarning: FileType is deprecated. Simply open files after parsing arguments.
    type=FileType('a+b'),

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_cli_utils.py::test_lazy_choices_help - AssertionError: Expe...
================ 1 failed, 1027 deselected, 1 warning in 0.20s =================

Expected result

Tests pass.

hroncok avatar Jul 10 '25 11:07 hroncok

If I make getter raise, this is the traceback:

 File ".../httpie/tests/test_cli_utils.py", line 62, in test_lazy_choices_help
    parser.add_argument(
    ~~~~~~~~~~~~~~~~~~~^
        '--lazy-option',
        ^^^^^^^^^^^^^^^^
    ...<5 lines>...
        cache=False  # for test purposes
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/lib64/python3.14/argparse.py", line 1561, in add_argument
    self._check_help(action)
    ~~~~~~~~~~~~~~~~^^^^^^^^
  File "/usr/lib64/python3.14/argparse.py", line 1744, in _check_help
    if action.help and hasattr(self, "_get_formatter"):
       ^^^^^^^^^^^
  File ".../httpie/httpie/cli/utils.py", line 60, in help
    self.load(),
    ~~~~~~~~~^^
  File ".../httpie/httpie/cli/utils.py", line 51, in load
    self._obj = self.getter()
                ~~~~~~~~~~~^^
  File ".../httpie/tests/test_cli_utils.py", line 55, in getter
    raise RuntimeError('xxx')
RuntimeError: xxx

hroncok avatar Jul 10 '25 15:07 hroncok

gh-65865: Raise early errors for invalid help strings in argparse

https://github.com/python/cpython/pull/124899

hroncok avatar Jul 10 '25 15:07 hroncok