Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ jobs:
- '3.8'
- '3.7'
pyopenssl: [0, 1]
exclude:
- os: ubuntu-latest
python-version: '3.7'
include:
- os: ubuntu-22.04
python-version: '3.7'
pyopenssl: 0
- os: ubuntu-22.04
python-version: '3.7'
pyopenssl: 1
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
Expand All @@ -42,7 +52,7 @@ jobs:
- name: Windows setup
if: matrix.os == 'windows-latest'
run: |
python -m pip install --upgrade pip wheel
python -m pip install --upgrade "pip<25.3; python_version<'3.10'" "pip; python_version>='3.10'" wheel
python -m pip install --upgrade '.[dev]'
python -m pytest --verbose ./httpie ./tests
env:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ install: venv install-reqs

install-reqs:
@echo $(H1)Updating package tools$(H1END)
$(VENV_PIP) install --upgrade pip wheel build
$(VENV_PIP) install --upgrade "pip<25.3; python_version<'3.10'" "pip; python_version>='3.10'" wheel build

@echo $(H1)Installing dev requirements$(H1END)
$(VENV_PIP) install --upgrade '.[dev]' '.[test]'
Expand Down
18 changes: 16 additions & 2 deletions httpie/cli/argparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,22 @@ def _print_message(self, message, file=None):
}.get(file, file)

if not hasattr(file, 'buffer') and isinstance(message, str):
message = message.encode(env.stdout_encoding)
super()._print_message(message, file)
encoding = getattr(env, 'stdout_encoding', None) or sys.getdefaultencoding()
message = message.encode(encoding, errors='backslashreplace')
try:
super()._print_message(message, file)
except UnicodeEncodeError:
if not isinstance(message, str):
raise
encoding = (
getattr(file, 'encoding', None)
or getattr(env, 'stdout_encoding', None)
or sys.getdefaultencoding()
)
message = message.encode(
encoding, errors='backslashreplace'
).decode(encoding)
super()._print_message(message, file)


class HTTPieManagerArgumentParser(BaseHTTPieArgumentParser):
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ dev =
flake8-deprecated
flake8-mutable
flake8-tuple
pyopenssl
pyopenssl<26
pytest-cov
pyyaml
twine
Expand Down
18 changes: 16 additions & 2 deletions tests/test_cli_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
error_msg="argument --pretty: invalid choice: '$invalid' (choose from 'all', 'colors', 'format', 'none')"
)

NAKED_HELP_MESSAGE_PRETTY_WITH_INVALID_ARG_UNQUOTED = NAKED_BASE_TEMPLATE.format(
extra_args="--pretty {all, colors, format, none} ",
error_msg="argument --pretty: invalid choice: '$invalid' (choose from all, colors, format, none)"
)


PREDEFINED_TERMINAL_SIZE = (200, 100)

Expand Down Expand Up @@ -57,9 +62,18 @@ def fake_terminal_size(*args, **kwargs):
([], NAKED_HELP_MESSAGE),
(['--pretty'], NAKED_HELP_MESSAGE_PRETTY_WITH_NO_ARG),
(['pie.dev', '--pretty'], NAKED_HELP_MESSAGE_PRETTY_WITH_NO_ARG),
(['--pretty', '$invalid'], NAKED_HELP_MESSAGE_PRETTY_WITH_INVALID_ARG),
(
['--pretty', '$invalid'],
(
NAKED_HELP_MESSAGE_PRETTY_WITH_INVALID_ARG,
NAKED_HELP_MESSAGE_PRETTY_WITH_INVALID_ARG_UNQUOTED,
)
),
]
)
def test_naked_invocation(ignore_terminal_size, args, expected_msg):
result = http(*args, tolerate_error_exit_status=True)
assert result.stderr == expected_msg
if isinstance(expected_msg, tuple):
assert result.stderr in expected_msg
else:
assert result.stderr == expected_msg
2 changes: 1 addition & 1 deletion tests/test_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


CHARSET_TEXT_PAIRS = [
('big5', '卷首卷首卷首卷首卷卷首卷首卷首卷首卷首卷首卷首卷首卷首卷首卷首卷首卷首'),
('big5', '中文測試內容,這是一段使用繁體中文撰寫的文字,用來確認 Big5 編碼可以被正確偵測。'),
('windows-1250', 'Všichni lidé jsou si rovni. Všichni lidé jsou si rovni.'),
(UTF8, 'Všichni lidé jsou si rovni. Všichni lidé jsou si rovni.'),
]
Expand Down
11 changes: 11 additions & 0 deletions tests/test_httpie.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ def test_help():
assert 'https://github.com/httpie/cli/issues' in r


def test_help_with_ascii_stdout():
stdout = io.TextIOWrapper(io.BytesIO(), encoding='ascii')
env = MockEnvironment(stdout=stdout, stdout_isatty=True)

r = http('--help', env=env, tolerate_error_exit_status=True)

assert r.exit_status == ExitStatus.SUCCESS
r.encode('ascii')
assert 'https://github.com/httpie/cli/issues' in r


def test_version():
r = http('--version', tolerate_error_exit_status=True)
assert r.exit_status == ExitStatus.SUCCESS
Expand Down
Loading