geventhttpclient 2.5.1__tar.gz → 2.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. geventhttpclient-2.6.1/.github/workflows/publish.yml +110 -0
  2. geventhttpclient-2.6.1/.github/workflows/test.yml +76 -0
  3. geventhttpclient-2.6.1/.gitignore +20 -0
  4. geventhttpclient-2.6.1/.gitmodules +3 -0
  5. geventhttpclient-2.6.1/.pre-commit-config.yaml +48 -0
  6. geventhttpclient-2.6.1/CHANGELOG.md +161 -0
  7. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/MANIFEST.in +3 -2
  8. geventhttpclient-2.6.1/PKG-INFO +373 -0
  9. geventhttpclient-2.6.1/README.md +336 -0
  10. geventhttpclient-2.6.1/RELEASING.md +65 -0
  11. geventhttpclient-2.6.1/SECURITY.md +18 -0
  12. geventhttpclient-2.6.1/benchmarks/README.md +79 -0
  13. geventhttpclient-2.6.1/benchmarks/benchmark.py +162 -0
  14. geventhttpclient-2.6.1/benchmarks/geventhttpclient_bench.py +36 -0
  15. geventhttpclient-2.6.1/benchmarks/httplib2_patched_bench.py +40 -0
  16. geventhttpclient-2.6.1/benchmarks/httpx_async_bench.py +44 -0
  17. geventhttpclient-2.6.1/benchmarks/httpx_bench.py +36 -0
  18. geventhttpclient-2.6.1/benchmarks/requests_bench.py +29 -0
  19. geventhttpclient-2.6.1/benchmarks/urllib3_bench.py +29 -0
  20. geventhttpclient-2.6.1/examples/download.py +23 -0
  21. geventhttpclient-2.6.1/examples/download_raw.py +27 -0
  22. geventhttpclient-2.6.1/examples/facebook.py +50 -0
  23. geventhttpclient-2.6.1/examples/httplib2_patched.py +26 -0
  24. geventhttpclient-2.6.1/examples/oauth2.py +54 -0
  25. geventhttpclient-2.6.1/examples/urllib_patched.py +12 -0
  26. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/ext/_parser.c +3 -31
  27. geventhttpclient-2.6.1/llhttp/.gitignore +1 -0
  28. geventhttpclient-2.6.1/llhttp/CMakeLists.txt +135 -0
  29. geventhttpclient-2.6.1/llhttp/LICENSE +22 -0
  30. geventhttpclient-2.6.1/llhttp/README.md +518 -0
  31. geventhttpclient-2.6.1/llhttp/cmake/llhttpConfig.cmake.in +19 -0
  32. geventhttpclient-2.6.1/llhttp/common.gypi +46 -0
  33. geventhttpclient-2.6.1/llhttp/libllhttp.pc.in +10 -0
  34. geventhttpclient-2.6.1/llhttp/llhttp.gyp +22 -0
  35. geventhttpclient-2.6.1/pyproject.toml +144 -0
  36. geventhttpclient-2.6.1/src/geventhttpclient/__init__.py +33 -0
  37. geventhttpclient-2.6.1/src/geventhttpclient/_parser.pyi +12 -0
  38. geventhttpclient-2.6.1/src/geventhttpclient/_version.py +24 -0
  39. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/api.py +13 -8
  40. geventhttpclient-2.6.1/src/geventhttpclient/auth.py +92 -0
  41. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/client.py +97 -33
  42. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/connectionpool.py +37 -20
  43. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/header.py +143 -65
  44. geventhttpclient-2.6.1/src/geventhttpclient/httplib.py +358 -0
  45. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/httplib2.py +19 -8
  46. geventhttpclient-2.6.1/src/geventhttpclient/httpx.py +539 -0
  47. geventhttpclient-2.6.1/src/geventhttpclient/py.typed +0 -0
  48. geventhttpclient-2.6.1/src/geventhttpclient/requests.py +521 -0
  49. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/response.py +52 -10
  50. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/url.py +160 -24
  51. geventhttpclient-2.6.1/src/geventhttpclient/useragent.py +1000 -0
  52. geventhttpclient-2.6.1/src/geventhttpclient.egg-info/PKG-INFO +373 -0
  53. geventhttpclient-2.6.1/src/geventhttpclient.egg-info/SOURCES.txt +91 -0
  54. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient.egg-info/requires.txt +1 -10
  55. geventhttpclient-2.6.1/src/geventhttpclient.egg-info/scm_file_list.json +87 -0
  56. geventhttpclient-2.6.1/src/geventhttpclient.egg-info/scm_version.json +8 -0
  57. geventhttpclient-2.6.1/tests/__init__.py +2 -0
  58. geventhttpclient-2.6.1/tests/common.py +86 -0
  59. geventhttpclient-2.6.1/tests/conftest.py +17 -0
  60. geventhttpclient-2.6.1/tests/gevent_only/__init__.py +0 -0
  61. geventhttpclient-2.6.1/tests/gevent_only/conftest.py +7 -0
  62. geventhttpclient-2.6.1/tests/gevent_only/test_httplib2.py +31 -0
  63. geventhttpclient-2.6.1/tests/gevent_only/test_httplib2_compat.py +133 -0
  64. geventhttpclient-2.6.1/tests/gevent_only/test_proxy.py +75 -0
  65. geventhttpclient-2.6.1/tests/gevent_only/test_ssl.py +43 -0
  66. geventhttpclient-2.6.1/tests/oncert.pem +20 -0
  67. geventhttpclient-2.6.1/tests/server.crt +22 -0
  68. geventhttpclient-2.6.1/tests/server.key +28 -0
  69. geventhttpclient-2.6.1/tests/test_auth.py +93 -0
  70. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_client.py +178 -1
  71. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_headers.py +83 -0
  72. geventhttpclient-2.6.1/tests/test_httplib.py +141 -0
  73. geventhttpclient-2.6.1/tests/test_httpx.py +176 -0
  74. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_keep_alive.py +2 -6
  75. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_parser.py +17 -0
  76. geventhttpclient-2.6.1/tests/test_requests.py +536 -0
  77. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_ssl.py +170 -1
  78. geventhttpclient-2.6.1/tests/test_url.py +361 -0
  79. geventhttpclient-2.6.1/tests/test_useragent.py +798 -0
  80. geventhttpclient-2.6.1/uv.lock +950 -0
  81. geventhttpclient-2.5.1/PKG-INFO +0 -296
  82. geventhttpclient-2.5.1/README.md +0 -255
  83. geventhttpclient-2.5.1/ext/Python_compat.h +0 -5
  84. geventhttpclient-2.5.1/pyproject.toml +0 -108
  85. geventhttpclient-2.5.1/src/geventhttpclient/__init__.py +0 -9
  86. geventhttpclient-2.5.1/src/geventhttpclient/httplib.py +0 -244
  87. geventhttpclient-2.5.1/src/geventhttpclient/requests.py +0 -250
  88. geventhttpclient-2.5.1/src/geventhttpclient/useragent.py +0 -699
  89. geventhttpclient-2.5.1/src/geventhttpclient.egg-info/PKG-INFO +0 -296
  90. geventhttpclient-2.5.1/src/geventhttpclient.egg-info/SOURCES.txt +0 -40
  91. geventhttpclient-2.5.1/tests/test_httplib.py +0 -73
  92. geventhttpclient-2.5.1/tests/test_requests.py +0 -14
  93. geventhttpclient-2.5.1/tests/test_url.py +0 -173
  94. geventhttpclient-2.5.1/tests/test_useragent.py +0 -364
  95. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/LICENSE-MIT +0 -0
  96. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/LICENSE-MIT +0 -0
  97. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/include/llhttp.h +0 -0
  98. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/src/api.c +0 -0
  99. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/src/http.c +0 -0
  100. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/src/llhttp.c +0 -0
  101. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/setup.cfg +0 -0
  102. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/setup.py +0 -0
  103. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient.egg-info/dependency_links.txt +0 -0
  104. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient.egg-info/top_level.txt +0 -0
  105. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_continue.py +0 -0
  106. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_network_failures.py +0 -0
  107. {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_proxy.py +0 -0
@@ -0,0 +1,110 @@
1
+ name: Publish
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types:
7
+ - published
8
+
9
+ jobs:
10
+ build-wheels:
11
+ name: Build wheels (${{ matrix.label }})
12
+ runs-on: ${{ matrix.os }}
13
+ timeout-minutes: ${{ matrix.timeout || 45 }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ include:
18
+ - {label: linux-x86_64, os: ubuntu-24.04, archs: x86_64}
19
+ - {label: linux-aarch64, os: ubuntu-24.04-arm, archs: aarch64}
20
+ - {label: linux-ppc64le, os: ubuntu-24.04, archs: ppc64le, skip: "cp3*-musllinux_*", qemu: true, timeout: 60}
21
+ - {label: macos, os: macos-latest}
22
+ - {label: windows-x86, os: windows-latest}
23
+ - {label: windows-arm64, os: windows-11-arm}
24
+ steps:
25
+ - uses: actions/checkout@v6
26
+ with:
27
+ fetch-depth: 0
28
+ submodules: recursive
29
+ - uses: actions/setup-python@v6
30
+ # Host interpreter only: cibuildwheel downloads its own CPython
31
+ # 3.11-3.15 builds for the wheels. setup-python lags brand-new
32
+ # CPython releases, so this stays on the newest available image.
33
+ with:
34
+ python-version: '3.14'
35
+ - uses: docker/setup-qemu-action@v3
36
+ if: ${{ matrix.qemu }}
37
+ name: Set up QEMU
38
+ - name: Install uv
39
+ uses: astral-sh/setup-uv@v10.2.0
40
+ - run: |
41
+ args=(--output-dir wheelhouse)
42
+ if [ -n "${{ matrix.archs }}" ]; then
43
+ args+=(--archs "${{ matrix.archs }}")
44
+ fi
45
+ if [ -n "${{ matrix.skip }}" ]; then
46
+ export CIBW_SKIP="${{ matrix.skip }}"
47
+ fi
48
+ uvx cibuildwheel==4.2.1 "${args[@]}"
49
+ shell: bash
50
+ name: Run build wheel
51
+ - uses: actions/upload-artifact@v4
52
+ with:
53
+ name: dist-wheels-${{ matrix.label }}
54
+ path: ./wheelhouse/*.whl
55
+ if-no-files-found: error
56
+
57
+ build-sdist:
58
+ name: Build source distribution
59
+ runs-on: ubuntu-latest
60
+ steps:
61
+ - uses: actions/checkout@v6
62
+ with:
63
+ fetch-depth: 0
64
+ submodules: recursive
65
+ - name: Install uv
66
+ uses: astral-sh/setup-uv@v10.2.0
67
+ - run: uv build --sdist
68
+ name: Build source tarball
69
+ - name: Refuse to publish unless the sdist version matches the ref name
70
+ run: |
71
+ test "$(ls dist/*.tar.gz | wc -l)" = 1
72
+ test "geventhttpclient-${GITHUB_REF_NAME}.tar.gz" = "$(basename dist/*.tar.gz)"
73
+ - uses: actions/upload-artifact@v4
74
+ with:
75
+ name: dist-source
76
+ path: dist/*.tar.gz
77
+ if-no-files-found: error
78
+
79
+ test-publish:
80
+ if: github.repository == 'geventhttpclient/geventhttpclient'
81
+ runs-on: ubuntu-latest
82
+ needs: [build-wheels, build-sdist]
83
+ steps:
84
+ - uses: actions/download-artifact@v4
85
+ with:
86
+ pattern: dist-*
87
+ path: dist
88
+ merge-multiple: true
89
+ - uses: pypa/gh-action-pypi-publish@release/v1
90
+ name: Publish package to TestPyPI
91
+ with:
92
+ password: ${{ secrets.TEST_PYPI_API_TOKEN }}
93
+ repository-url: https://test.pypi.org/legacy/
94
+ skip-existing: true
95
+
96
+ publish:
97
+ if: github.repository == 'geventhttpclient/geventhttpclient'
98
+ runs-on: ubuntu-latest
99
+ needs: test-publish
100
+ steps:
101
+ - uses: actions/download-artifact@v4
102
+ with:
103
+ pattern: dist-*
104
+ path: dist
105
+ merge-multiple: true
106
+ - uses: pypa/gh-action-pypi-publish@release/v1
107
+ name: Publish package to PyPI
108
+ with:
109
+ password: ${{ secrets.PYPI_API_TOKEN }}
110
+ skip-existing: true
@@ -0,0 +1,76 @@
1
+ name: Tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ mypy:
7
+ name: mypy
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v6
11
+ with:
12
+ fetch-depth: 0
13
+ submodules: recursive
14
+ - name: Install uv
15
+ uses: astral-sh/setup-uv@v10.2.0
16
+ with:
17
+ python-version: '3.12'
18
+ enable-cache: true
19
+ - name: Install project and dependencies
20
+ run: uv sync
21
+ - name: Run mypy
22
+ run: uv run mypy
23
+
24
+ tests:
25
+ name: ${{ matrix.name }}
26
+ runs-on: ${{ matrix.os }}
27
+
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ include:
32
+ - {name: Windows, python: '3.15', os: windows-latest}
33
+ # Windows ARM64 disabled: the windows-11-arm runner is chronically
34
+ # flaky (spurious test timeouts and socket permission errors on
35
+ # otherwise green runs). Re-enable once the runner is stable.
36
+ - {name: Mac, python: '3.15', os: macos-latest}
37
+ - {name: '3.15', python: '3.15', os: ubuntu-latest}
38
+ - {name: '3.14', python: '3.14', os: ubuntu-latest}
39
+ - {name: '3.13', python: '3.13', os: ubuntu-latest}
40
+ - {name: '3.12', python: '3.12', os: ubuntu-latest}
41
+ - {name: '3.11', python: '3.11', os: ubuntu-latest}
42
+
43
+ steps:
44
+ - uses: actions/checkout@v6
45
+ with:
46
+ fetch-depth: 0
47
+ submodules: recursive
48
+ - name: Install uv
49
+ uses: astral-sh/setup-uv@v10.2.0
50
+ with:
51
+ python-version: ${{ matrix.python }}
52
+ enable-cache: true
53
+ - name: Install project and dependencies
54
+ run: uv sync
55
+ - name: Run tests
56
+ run: uv run pytest
57
+
58
+ tests-nongevent:
59
+ name: non-gevent (3.15)
60
+ runs-on: ubuntu-latest
61
+ steps:
62
+ - uses: actions/checkout@v6
63
+ with:
64
+ fetch-depth: 0
65
+ submodules: recursive
66
+ - name: Install uv
67
+ uses: astral-sh/setup-uv@v10.2.0
68
+ with:
69
+ python-version: '3.15'
70
+ enable-cache: true
71
+ - name: Install project and dependencies
72
+ run: uv sync
73
+ - name: Run tests without monkey patching
74
+ env:
75
+ NON_GEVENT: '1'
76
+ run: uv run pytest
@@ -0,0 +1,20 @@
1
+ *.o
2
+ *.so
3
+ *.pyc
4
+ *.egg-info
5
+ src/geventhttpclient/_version.py
6
+
7
+ .Python
8
+ build/
9
+ lib/
10
+ include/
11
+ bin/
12
+ .project
13
+ .pydevproject
14
+ .idea
15
+ .settings/
16
+ dist/
17
+ .tox
18
+ .cache
19
+ .venv
20
+ wheelhouse
@@ -0,0 +1,3 @@
1
+ [submodule "llhttp"]
2
+ path = llhttp
3
+ url = https://github.com/nodejs/llhttp
@@ -0,0 +1,48 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: end-of-file-fixer
6
+ - id: trailing-whitespace
7
+ - id: debug-statements
8
+ - id: detect-private-key
9
+ exclude: ^tests/(server\.key|oncert\.pem)$
10
+ - id: check-builtin-literals
11
+ - id: check-case-conflict
12
+ - id: check-executables-have-shebangs
13
+ - id: check-json
14
+ - id: check-merge-conflict
15
+ - id: check-symlinks
16
+ - id: check-toml
17
+ - id: check-xml
18
+ - id: check-yaml
19
+ exclude: (.pre-commit-config\.yaml)
20
+
21
+ - repo: https://github.com/astral-sh/ruff-pre-commit
22
+ rev: v0.16.10
23
+ hooks:
24
+ - id: ruff
25
+ - id: ruff-format
26
+
27
+ - repo: local
28
+ hooks:
29
+ - id: mypy
30
+ name: mypy (via uv)
31
+ entry: uv run mypy
32
+ language: system
33
+ types: [python]
34
+ pass_filenames: false
35
+ files: ^src/
36
+
37
+ - repo: https://github.com/codespell-project/codespell
38
+ rev: v2.4.3
39
+ hooks:
40
+ - id: codespell
41
+
42
+ - repo: https://github.com/rvben/rumdl-pre-commit
43
+ rev: v0.2.78
44
+ hooks:
45
+ - id: rumdl-check
46
+ # llhttp is a git submodule (upstream files). pre-commit never traverses
47
+ # submodules, so this is belt-and-braces for hand-run configs.
48
+ exclude: ^llhttp/
@@ -0,0 +1,161 @@
1
+ # Changelog
2
+
3
+ API changes, deprecations and notable fixes. CI and packaging noise is
4
+ left out unless it affects users of the package.
5
+
6
+ ## 2.6.1 (2026-10-09)
7
+
8
+ ### Added
9
+
10
+ - Python 3.15 is supported explicitly
11
+
12
+ ## 2.6.0 (2026-10-05)
13
+
14
+ ### Added
15
+
16
+ - Type annotations across the package, with a `py.typed` marker
17
+ - Basic auth added: `BasicAuth("user", "pass")`, or the `requests`-style
18
+ `("user", "pass")` tuple, on a `Session` or a single request
19
+ - `geventhttpclient.httpx`, an httpx-compatible client on the same engine
20
+ - Requests compatibility improved: `history`, `elapsed`, `cookies`,
21
+ `links`, `encoding`, `iter_content()`, `iter_lines()`, `json()`,
22
+ `bool()`, `close()` and `raise_for_status` with the response attached
23
+ - `insecure` on `UserAgent`, for TLS targets without a verified chain
24
+ - `CompatRequest` derives from `urllib.request.Request`, so cookie jars
25
+ work without workarounds
26
+
27
+ ### Changed
28
+
29
+ - Header field names and values are `str` instead of `bytes`
30
+ - Multi-value headers send one field line per element (RFC 9110)
31
+ - Redirect resolution follows RFC 3986; other schemes raise
32
+ `UnsupportedRedirectSchemeError`
33
+ - Retries after a transmission error are limited to idempotent methods
34
+ - Empty bodies on POST, PUT and PATCH send `Content-Length: 0`
35
+ - `check_hostname`, `cert_file` and `key_file` are deprecated in favour of
36
+ a custom SSL context; `check_hostname` now defaults to `True`
37
+ - Require `gevent>=25.9`
38
+
39
+ ### Fixed
40
+
41
+ - The request head is validated and encoded as latin-1, like
42
+ `http.client`, instead of allowing header smuggling
43
+ - `requests` and `urllib3` work again through the `httplib` shim
44
+ - Error statuses and redirects come through the httplib2 wrapper
45
+ - 307/308 redirects resend the body, and `Authorization` is dropped when
46
+ a redirect leaves the origin
47
+ - `URL.redirect` keeps the base path and query
48
+ - Requests retain semicolon path parameters, including after redirects
49
+ - `follow_redirects=False` is honoured by the `httpx.Client` shortcuts
50
+
51
+ ### Removed
52
+
53
+ - `Headers.iteroriginal()` and `Headers.iget()`; use `items()` and
54
+ `getlist()`
55
+ - The unmaintained `oauth2` extra
56
+
57
+ ## 2.5.1 (2026-09-30)
58
+
59
+ ### Fixed
60
+
61
+ - Requests with `body=None` sent an empty chunked body
62
+
63
+ ## 2.5.0 (2026-09-28)
64
+
65
+ ### Added
66
+
67
+ - Type annotations for the core modules, checked by `mypy` in CI
68
+
69
+ ### Changed
70
+
71
+ - Require Python 3.11 or newer and a working `ssl` module; `urllib3` is
72
+ no longer a dependency
73
+ - `read()` and `readline()` return `bytes` instead of `bytearray`,
74
+ `readline()` on a released response raises `HTTPConnectionClosed`
75
+ - Header fragments decode as latin-1; the previous UTF-8 decoding
76
+ crashed the interpreter on non-UTF-8 header bytes
77
+
78
+ ### Fixed
79
+
80
+ - The body parameter of `delete()` and `trace()` works again
81
+
82
+ ## 2.4.0 (2026-09-28)
83
+
84
+ ### Added
85
+
86
+ - `Expect: 100-continue` handling and interim 1xx responses
87
+ - CONNECT tunneling with Basic proxy authentication via `proxy_user` and
88
+ `proxy_password`
89
+ - Chunked transfer encoding for request bodies, used automatically for
90
+ bodies of unknown length
91
+ - 308 redirects
92
+
93
+ ### Changed
94
+
95
+ - The llhttp parser moved to v9.4.3, including the CVE-2024-27982 fix
96
+
97
+ ## 2.3.9 (2026-03-03)
98
+
99
+ ### Fixed
100
+
101
+ - Stale-connection validation works with the stdlib SSL implementation
102
+
103
+ ## 2.3.8 (2026-02-22)
104
+
105
+ ### Added
106
+
107
+ - Connection validation before reuse, so pooled connections closed by
108
+ the server are no longer handed out
109
+
110
+ ## 2.3.6 (2025-12-07)
111
+
112
+ ### Changed
113
+
114
+ - Python 3.13 and 3.14 are supported explicitly
115
+
116
+ ## 2.3.5 (2025-10-26)
117
+
118
+ ### Fixed
119
+
120
+ - `Headers.extend()` overwrote values of duplicate fields instead of
121
+ appending them
122
+
123
+ ## 2.3.4 (2025-06-11)
124
+
125
+ ### Fixed
126
+
127
+ - URL quoting for path and query components
128
+
129
+ ## 2.3.3 (2024-11-24)
130
+
131
+ ### Fixed
132
+
133
+ - `ssl_options` handling in the connection pool
134
+
135
+ ## 2.3.1 (2024-04-18)
136
+
137
+ ### Fixed
138
+
139
+ - Backwards compatibility with locust after the 2.3.0 restructuring
140
+
141
+ ## 2.3.0 (2024-04-18)
142
+
143
+ ### Added
144
+
145
+ - A thin `requests` compatibility layer (`geventhttpclient.requests`)
146
+ with a `Session` speaking the requests-style API subset
147
+
148
+ ## 2.2.1 (2024-04-16)
149
+
150
+ ### Changed
151
+
152
+ - URL parsing is delegated to the standard library
153
+ - `max_retries` and `max_redirects` no longer count the initial attempt
154
+
155
+ ## 2.2.0 (2024-04-12)
156
+
157
+ ### Fixed
158
+
159
+ - `Headers` preserves the original case even for headers with duplicate
160
+ field names
161
+ - Patching `http.client` worked only partially
@@ -1,7 +1,8 @@
1
1
  include src/geventhttpclient/*.py
2
+ include src/geventhttpclient/py.typed
2
3
  include ext/*.c
3
- include ext/*.h
4
- recursive-include llhttp *.h *.c LICENSE-MIT
4
+ recursive-include llhttp *.h *.c LICENSE LICENSE-MIT
5
+ graft tests
5
6
  global-exclude __pycache__
6
7
  global-exclude *.py[co]
7
8
  include pyproject.toml