Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭
#1,838 4 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
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 下复现这两个命令,然后将 parser 的行为与可能采用的 parse_intermixed_args 方案进行比较。完成的标准是:项目已经确定解决方案——一致的解析,或明确记录的限制——并且已在所有受支持的 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. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

httpie/cli 的其他 Issue

查看 httpie/cli 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。