fix: repair the litestar and faststream floors - #220
Merged
Merged
Conversation
litestar 2.15 imports sniffio without declaring it and relied on anyio, which dropped the dependency in 4.14; 2.19 is the first release that declares it. litestar also declares typing-extensions bare while using ReadOnly, so that floor is declared here too. faststream pulls pydantic through fast-depends, which allows it back to 1.7.4. With typing-extensions pinned at the declared floor the chain resolves a pydantic whose pydantic-core has no cp313 or cp314 wheel, so both constraints are declared on the extra.
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.
The two decayed floors found by the composition check in #218. Neither was a simple bump: each
turned out to rest on a dependency the upstream package uses but does not declare.
litestar
litestar/concurrency.py:8doesimport sniffio. Until 2.19 litestar did not declare it and itarrived through
anyio, which dropped the dependency in 4.14.litestar==2.15.0withanyio==4.14.2therefore raisesModuleNotFoundError: No module named 'sniffio'atimport lite_bootstrap. 2.19.0 is the first release declaringsniffio>=1.3.1.Raising the floor exposed a second undeclared dependency underneath it: every litestar from 2.19 to
2.24 declares
typing-extensionsbare, while importingtyping_extensions.ReadOnly(4.9). Withtyping-extensionspinned at this project's own floor, the resolver has no reason to lift it, so thefloor has to be declared here:
AttributeError: attribute '__default__' of 'typing.ParamSpec' objects is not writable4.9 is enough for
ReadOnly, but 4.9 and 4.11 assigntyping.ParamSpec.__default__, which Python3.13 made read-only. Hence
>=4.12rather than>=4.9.faststream
faststream>=0.6pullsfast-depends[pydantic], which allowspydantic>=1.7.4,<3.0.0. pydanticrequires
typing-extensions>=4.12.2on 3.13+, so withtyping-extensionspinned at 4.8 (thisproject's floor, lifted by faststream's own
typing-extensions>=4.8.0) the resolver walks pydanticback to 2.7.4, whose
pydantic-core==2.18.4builds against pyo3 0.21.2 and has no cp313 or cp314wheel. The reported 3.14 failure was the same defect on 3.13, one interpreter earlier than #218 said.
Raising the faststream floor does not help: 0.7.5 still declares only
fast-depends[pydantic]>=3.0.0,and fast-depends 3.0.8 is the newest release. The constraint has to come from here.
typing-extensions>=4.12.2fixes 3.10 through 3.13, landing pydantic 2.11.10. On 3.14 pydantic 2.11still has no wheel, and 2.12 is the first that does, so that one is declared under a marker rather
than as a floor for every interpreter where 2.7.4 is fine.
Why these sit on the extras rather than on core
Both are constraints on packages
lite-bootstrapnever imports, declared because the chain thatreaches them is under-constrained upstream. Putting
typing-extensions>=4.12.2in[project.dependencies]instead would be one line rather than four and would fix both, but it wouldoverstate core: #214 measured bare core at 4.6, and
free-allstill resolves 4.6.0 after this change.Keeping the constraint where its cause is keeps the core claim honest and lets each comment name what
forced it. Worth a second opinion in review, since the alternative is genuinely simpler.
Verification
Every
*-allextra under--resolution lowest-direct, on every supported interpreter, installed andbootstrapped:
free-allfastapi-alllitestar-allfaststream-allfastmcp-all25 of 25, against 8 of 10 before.
litestar-allandfaststream-alladditionally bootstrap and teardown their bootstrapper, not just import.
just lint-ciandjust test-cipass (277 passed, 100% coverage).uv.lockis unchanged.