Fix aiohttp 3.14 compatibility (AsyncStreamReaderMixin removed, ClientResponse requires stream_writer) - #996
Merged
kevin1024 merged 1 commit intoJun 9, 2026
Conversation
aiohttp 3.14.0 broke vcrpy's aiohttp stub in two independent ways: - `aiohttp.streams.AsyncStreamReaderMixin` was removed (internal symbol, never in `__all__`; aio-libs/aiohttp#12357), so importing `vcr.stubs.aiohttp_stubs` raised `AttributeError` at class-definition time. The mixin only added the async-iteration helpers `iter_chunked`/`iter_any`/ `iter_chunks` on top of `asyncio.StreamReader`; reimplement them directly on `MockStream` using aiohttp's `AsyncStreamIterator`/`ChunkTupleAsyncStreamIterator` (present in both old and new aiohttp). - `ClientResponse.__init__` now requires a `stream_writer` argument and, when `writer is None`, reads `stream_writer.output_size`. Pass a zero-sized writer stub when the parameter is present, detected via signature introspection so older aiohttp (which has no such parameter) keeps working. No aiohttp version cap is added; the stub imports and plays back cassettes under both aiohttp < 3.14 and >= 3.14. Adds `test_stream_chunked` to guard the async-iteration surface, which the existing suite did not exercise. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3 tasks
vEpiphyte
added a commit
to vertexproject/synapse
that referenced
this pull request
Jun 2, 2026
Lower the upper bound on the aiohttp library due to a compatibility issue with vcrpy. Related issues / PRs kevin1024/vcrpy#995 kevin1024/vcrpy#996 aio-libs/aiohttp#12357
Mr0grog
added a commit
to edgi-govdata-archiving/web-monitoring-processing
that referenced
this pull request
Jun 3, 2026
Warcio depends on any version of aiohttp, but vcrpy is not yet compatible with v3.14.x, leading to failing tests. This limits the range of aiohttp versions we allow so that we always have a compatible configuration. See also kevin1024/vcrpy#996 for an upcoming fix in vcrpy.
mdrxy
added a commit
to langchain-ai/langchain
that referenced
this pull request
Jun 4, 2026
aiohttp **3.14.0** (released 2026-06-01) removed `aiohttp.streams.AsyncStreamReaderMixin`. The current release of `vcrpy` (8.1.1) still subclasses it in its aiohttp stub: ```python class MockStream(asyncio.StreamReader, streams.AsyncStreamReaderMixin): ``` As a result, the VCR fixture fails to import during test setup, and the scheduled integration tests for the `fireworks` and `xai` partners error out at `test_stream_time`: ``` AttributeError: module 'aiohttp.streams' has no attribute 'AsyncStreamReaderMixin' ``` Only these two partners are affected because their SDKs use `aiohttp`, so VCR loads its aiohttp stub; partners on `httpx` (e.g. `anthropic`, `openai`) are unaffected. This is an upstream incompatibility tracked at kevin1024/vcrpy#995, with a fix in kevin1024/vcrpy#996 that has not yet been released. Until a fixed `vcrpy` ships, this caps `aiohttp<3.14.0` via `[tool.uv] constraint-dependencies` (the same mechanism already used for the `pygments` CVE pin) in both packages. Using a constraint rather than tightening the published `aiohttp>=3.9.1,<4.0.0` range means the change only affects local/CI resolution — the package metadata users install against is untouched. Both lockfiles re-resolve to `aiohttp` 3.13.5, which still provides the removed attribute. A code comment points back to the upstream fix so the pin can be removed once it lands.
|
any update here? |
Merged
|
Hello, is it possible to release this version? It is not avaialbe in pypi. 8.1.2 |
4 tasks
andrew-blake
added a commit
to andrew-blake/melcloudhome
that referenced
this pull request
Jun 16, 2026
vcrpy v8.2.0 (released 2026-06-15) fixes the aiohttp 3.14 compatibility issues that required the <3.15 upper bound (kevin1024/vcrpy#996). - Remove aiohttp upper bound from pyproject.toml - aiohttp 3.13.4 → 3.14.1 (fixes several CVEs) - vcrpy 7.0.0 → 8.2.0 - urllib3 removed (no longer a vcrpy dependency) Closes #124 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
3 tasks
JSv4
added a commit
to Open-Source-Legal/OpenContracts
that referenced
this pull request
Jul 24, 2026
aiohttp 3.14 removed `aiohttp.streams.AsyncStreamReaderMixin`, which vcrpy 8.1.1's `vcr/stubs/aiohttp_stubs.py` subclassed at import time. vcrpy loads that stub lazily when a cassette is entered, so every VCR cassette entry raised AttributeError (issue #1920). The workaround was `ensure_aiohttp_vcr_compat()`, which re-injected the removed name as an empty class. vcrpy 8.2.0 fixed the stub upstream (kevin1024/vcrpy#996): `MockStream` now inherits only from `asyncio.StreamReader` and handles the 3.14 `stream_writer` argument itself. The pin has been at 8.2.1 or later since then, so the shim has been redundant — and not merely inert. Under aiohttp 3.14 the `hasattr` guard fell through, so conftest import was still writing a fake `AsyncStreamReaderMixin` into the real `aiohttp.streams` namespace on every test run. Verified in two environments, in both cases entering a cassette with no shim applied and confirming `MockStream.__bases__ == (asyncio.StreamReader,)`: - the local django image: vcrpy 8.2.1 + aiohttp 3.14.1 (the exact pre-bump pairing the issue asks about) - a clean venv: vcrpy 8.3.0 + aiohttp 3.14.1 (the current pin) Removed: - `ensure_aiohttp_vcr_compat()` in `opencontractserver/utils/vcr_replay.py` and its call in `maybe_vcr_cassette()` - the import and module-level call in `conftest.py` - `EnsureAiohttpVcrCompatTests` in `opencontractserver/tests/test_vcr_replay.py` - the `requirements/local.txt` comment, which still described vcrpy 8.1.1 as the pinned version and #996 as unreleased; replaced with a short note on why the floor is 8.2.0 The `aiohttp>=3.13,<3.14` cap this was paired with (issue #1914) was already lifted on main. `EnsureAiohttpVcrCompatTests` is replaced by `VcrCassetteEntryTests`, which keeps the part of the guard that survives the shim: entering a cassette forces the lazy import of `vcr/stubs/aiohttp_stubs.py`, so the test fails if a future vcrpy/aiohttp pairing reintroduces an import-time incompatibility. 72 tests pass across `test_vcr_replay.py`, `test_structured_response_simple.py`, `test_structured_response_api.py`, and `test_individual_extract_tasks.py`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
Under aiohttp 3.14.0, importing vcrpy's aiohttp stub crashes:
and once that's worked around, cassette playback fails with
TypeError: ClientResponse.__init__() missing 1 required keyword-only argument: 'stream_writer'.Fixes #995.
Root cause
aiohttp 3.14.0 introduced two independent breaking changes to internals that vcrpy's
stub relied on:
aiohttp.streams.AsyncStreamReaderMixinwas removed inaio-libs/aiohttp#12357. The symbol
was internal — never in
aiohttp.streams.__all__, never documented — so its removalisn't treated as a breaking change by aiohttp; the fix belongs here. The mixin only
provided the async-iteration helpers (
iter_chunked,iter_any,iter_chunks) on topof
StreamReader; in 3.14 those were folded directly intoaiohttp.streams.StreamReader.ClientResponse.__init__now requires astream_writerargument and, whenwriter is None, readsstream_writer.output_size.Fix
MockStreamno longer subclasses the removed mixin. It keepsasyncio.StreamReaderandreimplements just the three helpers the mixin added, using aiohttp's own
AsyncStreamIterator/ChunkTupleAsyncStreamIterator(present in both old and new aiohttp).__aiter__/readcontinue to resolve toasyncio.StreamReader, exactly as before.MockClientResponsepasses a zero-sizedstream_writerstub only when the runningaiohttp's
ClientResponseaccepts that parameter (detected via signature introspection).A replayed response has already been "sent", so
output_size = 0is accurate.Backward compatibility
vcrpy declares no aiohttp version bound (it's a lazily-imported test extra), so this must work
on any aiohttp. No version cap is added. The
stream_writerargument is passed only whenpresent, and the iterator helpers exist in both versions, so the stub imports and plays back
cassettes under aiohttp
< 3.14and>= 3.14alike.Verification
tests/integration/test_aiohttp.py: 29 passed under both aiohttp 3.14.0 and 3.13.5.test_stream_chunked, which exercisesresponse.content.iter_chunked(...)— theasync-iteration surface that the existing suite never touched and that would otherwise
silently regress.
ruff check+ruff formatclean.🤖 Generated with Claude Code