Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Inconsistent argument parsing behavior across Python versions (< 3.13 vs 3.13+)

オープン
#1,838 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
python
領域
cli

調査の方向性

httpie/cli/argparser.py から始め、特に 97、129、159 行付近の parse_args とその parse_known_args 呼び出しを確認してください。Python 3.11、3.12、3.13 で 2 つのコマンドを再現し、その後、parse_intermixed_args を使う可能性のあるアプローチと parser の動作を比較してください。完了とは、プロジェクトとして解決策(一貫した parsing、または明示的に文書化された制限)が決定され、サポート対象のすべての Python バージョンで検証されていることを意味します。

索引モデルが issue の本文から書いたものです。

説明

bug new

Checklist

  • I've searched for similar issues.
  • I'm using the latest version of HTTPie.

Summary

I discovered that the position of optional flags (like -v) affects argument parsing differently depending on the Python version. This is due to improvements in Python 3.13's argparse module, but it creates an inconsistent user experience for users on Python 3.11/3.12 (which are still officially supported until 2027-2028).

Minimal reproduction code and steps

The position of the -v flag affects argument parsing differently depending on the Python version being used.

Test Case 1: -v flag after URL (fails on Python 3.11-3.12, works on 3.13+)
$ http --offline --ignore-stdin post pie.dev/post -v 'header1:xyz' x=1
Test Case 2: -v flag before URL (fails on all versions tested)
$ http --offline --ignore-stdin post -v pie.dev/post 'header1:xyz' x=1

Current result

Python 3.11 (Version 3.11.15)
$ http --offline --ignore-stdin post pie.dev/post -v 'header1:xyz' x=1
usage:
    http [METHOD] URL [REQUEST_ITEM ...]

error:
    unrecognized arguments: header1:xyz x=1

for more information:
    run 'http --help' or visit https://httpie.io/docs/cli
Python 3.12 (Version 3.12.3)
$ http --offline --ignore-stdin post pie.dev/post -v 'header1:xyz' x=1
usage:
    http [METHOD] URL [REQUEST_ITEM ...]

error:
    unrecognized arguments: header1:xyz x=1

for more information:
    run 'http --help' or visit https://httpie.io/docs/cli
Python 3.13 (Version 3.13.5) or higher
$ http --offline --ignore-stdin post pie.dev/post -v 'header1:xyz' x=1
POST /post HTTP/1.1
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 10
User-Agent: HTTPie/3.2.4
Accept: application/json, */*;q=0.5
Content-Type: application/json
header1: xyz
Host: pie.dev

{"x": "1"}

✅ Works correctly on Python 3.13+

Expected result

Ideally, the command should work consistently across all supported Python versions, regardless of whether optional flags like -v are placed before or after the URL.

While I understand this is caused by Python's argparse improvements in 3.13, I wanted to bring this to your attention because:

  1. Many users are still on Python 3.11/3.12 (officially supported until 2027-2028)
  2. This creates a confusing user experience where the same command works differently
  3. There might be room for improvement through documentation or potential workarounds

Debug output

Python 3.12
$ http --debug --offline --ignore-stdin post pie.dev/post -v 'header1:xyz' x=1
HTTPie 3.2.4
Requests 2.33.1
Pygments 2.20.0
Python 3.12.3 (main, Mar 23 2026, 19:04:32) [GCC 13.3.0]
/home/user/env312/bin/python
Linux 5.15.167.4-microsoft-standard-WSL2

<Environment {...}>

<PluginManager {...}>
usage:
    http [METHOD] URL [REQUEST_ITEM ...]

error:
    unrecognized arguments: header1:xyz x=1

for more information:
    run 'http --help' or visit https://httpie.io/docs/cli
Python 3.13
$ http --debug --offline --ignore-stdin post pie.dev/post -v 'header1:xyz' x=1
HTTPie 3.2.4
Requests 2.33.1
Pygments 2.20.0
Python 3.13.5 (main, Apr 27 2026, 03:43:50) [GCC 9.5.0]
/home/user/env313/bin/python
Linux 5.15.167.4-microsoft-standard-WSL2

<Environment {...}>

<PluginManager {...}>

>>> requests.request(**{'auth': None,
 'data': b'{"x": "1"}',
 'headers': <HTTPHeadersDict(...)>,
 'method': 'post',
 'params': <generator object MultiValueOrderedDict.items at 0x...>,
 'url': 'http://pie.dev/post'})

POST /post HTTP/1.1
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 10
User-Agent: HTTPie/3.2.4
Accept: application/json, */*;q=0.5
Content-Type: application/json
header1: xyz
Host: pie.dev

{"x": "1"}

Additional information

This issue appears to be caused by changes in Python's argparse.ArgumentParser.parse_known_args() behavior between Python 3.12 and 3.13.

HTTPie uses parse_known_args() in httpie/cli/argparser.py (lines 97, 129, 159) to handle the mix of positional and optional arguments. The Python 3.13 release includes improvements to argparse that better handle intermixed optional and positional arguments.

Code Reference

The parsing happens in httpie/cli/argparser.py:

def parse_args(
    self,
    env: Environment,
    args=None,
    namespace=None
) -> argparse.Namespace:
    self.env = env
    self.args, no_options = self.parse_known_args(args, namespace)  # Line 159
    # ... rest of the method
Impact
  • Users on Python 3.11 and 3.12 (which are still widely used) experience inconsistent behavior
  • The position of optional flags shouldn't matter for argument parsing
  • This creates confusion for users who might be used to putting flags anywhere in the command
Possible Approaches (open for discussion)
  1. Documentation: Add a note about this limitation for Python < 3.13 users (recommend placing optional flags before the URL)
  2. Workaround consideration: Evaluate if using argparse.ArgumentParser.parse_intermixed_args() would help (available since Python 3.7)
  3. Informational only: Perhaps this is just something to be aware of as Python 3.11/3.12 approach EOL

I'm happy to contribute documentation updates or help test any potential solutions if you think this is worth addressing. I'm also open to this just being "working as intended" given the Python version constraints.

Related
Environment
  • HTTPie version: 3.2.4
  • Python versions tested: 3.11.15, 3.12.3, 3.13.5, 3.14.4
  • OS: Linux (WSL2)
  • Requests version: 2.33.1
主要言語
Python
スター
38.6k
フォーク
4k
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

httpie/cli のほかの issue

httpie/cli の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。