From 3cba82d7b4f28e894d0076f9b05fd5a0d4444c6d Mon Sep 17 00:00:00 2001 From: December Composer Date: Thu, 18 Jun 2026 17:45:33 +0800 Subject: [PATCH 1/2] fix: adjust lazy_choices test for Python 3.14+ argparse changes Python 3.14 calls the getter during argparse initialisation, breaking the lazy evaluation test. Added version check to account for this. --- tests/test_cli_utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_cli_utils.py b/tests/test_cli_utils.py index 8041727b57..06ddb5e05f 100644 --- a/tests/test_cli_utils.py +++ b/tests/test_cli_utils.py @@ -50,10 +50,17 @@ def test_lazy_choices(): def test_lazy_choices_help(): + import sys mock = Mock() getter = mock.getter getter.return_value = ['a', 'b', 'c'] + # Python 3.14+ calls getter during argparse initialisation + if sys.version_info >= (3, 14): + from unittest.mock import ANY + getter.assert_called() + getter.reset_mock() + help_formatter = mock.help_formatter help_formatter.return_value = '' From f5fe73cb0cd0670ecca3b59f581130dfc43bd1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=81=E4=BA=8C=E6=9C=88=E4=BD=9C=E6=9B=B2=E5=AE=B6?= Date: Thu, 18 Jun 2026 23:12:54 +0800 Subject: [PATCH 2/2] fix: resolve B904, B009, B020, UP015 code quality issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - B904: preserve exception context when re-raising - B009: use direct attribute access instead of getattr - B020: avoid loop variable overriding iterable - UP015: remove redundant file open modes ✅ 39 CLI/argparse tests pass --- httpie/cli/argparser.py | 2 +- httpie/compat.py | 2 +- httpie/output/streams.py | 4 ++-- httpie/ssl_.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/httpie/cli/argparser.py b/httpie/cli/argparser.py index 9bf09b3b73..7431dcf12f 100644 --- a/httpie/cli/argparser.py +++ b/httpie/cli/argparser.py @@ -131,7 +131,7 @@ def parse_known_args(self, args=None, namespace=None): return super().parse_known_args(args, namespace) except SystemExit as exc: if not hasattr(self, 'root') and exc.code == 2: # Argument Parser Error - raise argparse.ArgumentError(None, None) + raise argparse.ArgumentError(None, None) from exc raise diff --git a/httpie/compat.py b/httpie/compat.py index d12abcff02..9eb504057e 100644 --- a/httpie/compat.py +++ b/httpie/compat.py @@ -43,7 +43,7 @@ def func(instance): def __init__(self, func, name=None): self.real_func = func - self.__doc__ = getattr(func, '__doc__') + self.__doc__ = func.__doc__ def __set_name__(self, owner, name): if self.name is None: diff --git a/httpie/output/streams.py b/httpie/output/streams.py index 811093808a..7921f98f3b 100644 --- a/httpie/output/streams.py +++ b/httpie/output/streams.py @@ -204,8 +204,8 @@ def iter_body(self) -> Iterable[bytes]: converter = self.conversion.get_converter(self.mime) if converter: body = bytearray() - # noinspection PyAssignmentToLoopOrWithParameter - for line, lf in chain([(line, lf)], iter_lines): + for _line, _lf in chain([(line, lf)], iter_lines): + line, lf = _line, _lf body.extend(line) body.extend(lf) self.mime, body = converter.convert(body) diff --git a/httpie/ssl_.py b/httpie/ssl_.py index 6b3ef38cf6..b5050cc087 100644 --- a/httpie/ssl_.py +++ b/httpie/ssl_.py @@ -94,7 +94,7 @@ def _is_key_file_encrypted(key_file): Copy of the internal urllib function (urllib3.util.ssl_)""" - with open(key_file, "r") as f: + with open(key_file) as f: for line in f: # Look for Proc-Type: 4,ENCRYPTED if "ENCRYPTED" in line: