feat: declare floors for the last four bare dependencies - #218
Merged
Merged
Conversation
structlog, sentry-sdk, orjson and pyroscope-io were the remaining bare requirements. Each floor is the lowest release that installs and runs on every supported interpreter, established by bootstrapping rather than by running the suite. structlog splits: the library needs 21.3, the test suite reaches for structlog.typing and needs 22.2, so the suite's floor goes to the dev group where downstream services never see it.
This was referenced Sep 15, 2026
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.
Closes #213. The last four bare requirements, swept in one pass.
How each floor was established
The oracle is the one settled on #213: install the extra, build the bootstrapper,
bootstrap(),exercise the call,
teardown(). No test client, so no probe depends on the dev group. Each boundarybelow is exact: the release named passes and the one before it fails.
structlogstructlog.stdlib.ProcessorFormatter.remove_processors_meta(logging_instrument.py:158)sentry-sdksentry_sdk.set_tags, plural (sentry_instrument.py:112)pyroscope-iopyroscope.shutdown()(pyroscope_instrument.py:52)orjsonTwo of these want a word on the rationale.
sentry-sdkhas two constraints, so the comment names both in thelitestar>=2.15style: 1.0.0 and1.20.0 fail on
TypeError: Unknown option 'max_value_length', and once that clears, 1.45.0 and 2.0.1fail on
AttributeError: module 'sentry_sdk' has no attribute 'set_tags'. 2.1.0 is where both hold.orjsonis the packaging-derived case from the addendum on #213. The library uses onlyorjson.dumps(...).decode()andorjson.loads, both original API, so nothing forces a floor bysymbol. What fails is installation: orjson builds from source only with a Rust toolchain, and 3.10.18
and every release below it has no cp314 wheel, so
maturinis invoked and fails on the newestsupported interpreter. 3.11.0 is the first with one.
pyroscope-iolooked like the same shape (0.3.0ships an sdist with no
project.name) but turned out to have a real API boundary above it, so it isdeclared on
shutdown()instead.All four pass on 3.10, 3.11, 3.12, 3.13 and 3.14.
structlogsplits across the extra and the dev groupMeasured both ways: the library needs 21.3.0, the suite needs 22.2.0. The gap is
structlog.typing,which
logging_instrument.py:19imports only underTYPE_CHECKINGbuttests/conftest.py:11importsfor real, to annotate
LoggingMock.Guarding the test's import would close the gap mechanically, but
[tool.ruff.lint]ignoresTCHrepo-wide on the grounds that "imports stay real; TYPE_CHECKING-only imports break runtime
introspection". Rewriting a test to satisfy a floor the library does not have is the wrong trade, so
the suite's floor goes to
[dependency-groups] dev, which no downstream service installs.Composition check
With every direct requirement now floored,
--resolution lowest-directper*-allextra resolvesand imports, which was not possible before this PR:
free-allfastapi-allfastmcp-alllitestar-allfaststream-allBoth failures are in floors that predate this PR, and neither is fixed by it:
litestar-allon 3.10:litestar==2.15.0doesimport sniffio(litestar/concurrency.py:8)without declaring it, and relied on
anyioto supply it.anyio==4.14.2no longer does, soimport lite_bootstrapraisesModuleNotFoundError: No module named 'sniffio'. The declaredlitestar>=2.15is false against a current transitive set.faststream-allon 3.14:faststream==0.6.0pinsfast-depends[pydantic]==3.0.8, which pinspydantic==2.7.4, whosepydantic-core==2.18.4has no cp314 wheel and fails to build.These are the decay #210 describes, found in declarations that were hand-verified when written. They
want their own change, since raising a floor and constraining a transitive are different fixes with
different costs.
Verification
just lint-ciandjust test-cipass.uv.lockis unchanged: every resolved version already satabove the new floors.