Repository navigation
Conversation
flaky 3.7.0 does `from _pytest.runner import call_runtest_hook`, which pytest removed. Under pytest 9 the import fails and every environment that installs flaky dies at collection. 3.8.1 works under both pytest 7.4.4 and pytest 9.0.3, so the bump is safe ahead of the pytest upgrade and is kept separate from it.
…ackage instrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/test_server_pb2_grpc.py:3 does `from tests.protobuf import test_server_pb2`, an absolute import that only resolves while the package directory is on sys.path and `tests.protobuf` is a real package. The directory had no __init__.py, so resolution depended on pytest inserting the directory itself, which pytest 9 no longer does by default. Adding the missing __init__.py makes the import work without relying on an import-mode default. The grpc suite goes from 12 collection errors to 156 passed.
GHSA-6w46-j5rx-g56g has no fix below pytest 9.0.3 and affects 60 open alerts. The bump has to cover every file at once. The lint environments install dev-requirements.txt and the package's own test-requirements.txt in a single resolution, so any file left on 7.4.4 makes the lint environment for its package unresolvable. 115 files pin pytest, not the 60 that carry an alert. Three things move with pytest because pytest 9 requires them: - pytest-asyncio 0.23.5 to 1.4.1 in the aiohttp-server, asyncio and click test requirements, since 0.23.5 caps pytest below 9. No test or conftest change was needed. The six instrumentation-genai files keep pytest-asyncio 0.21.0, which works unchanged under pytest 9. - The uv-generated requirements files are regenerated rather than hand-edited, because pytest 9 requires packaging>=22.0 and the oldest variants resolved packaging to 18.0 or 21.0, which cannot satisfy it. Regeneration also adds pygments, which pytest 9 depends on and pytest 7.4.4 did not, and drops pyparsing and six, which packaging 22.0 no longer needs. - The pytest floor in each regenerated .in file moves from 7.4 to 9.0. instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.latest.txt is edited by hand instead of regenerated. Regenerating it from the current .in replaces fastapi 0.137.2 with 0.119.1 and starlette 1.3.1 with 0.48.0, because the .in still asks for fastapi~=0.119.1 and fastapi 0.119.1 caps starlette below 0.49.0. Starlette's first fixed release is 0.49.1, so regenerating would reopen six starlette advisories that are currently closed. The .in and the generated file have drifted and need reconciling in their own change.
syrupy 4.6.1 declares pytest>=7.0.0,<9.0.0, so the resourcedetector-gcp environments cannot be installed alongside pytest 9.0.3: Because syrupy==4.6.1 depends on pytest>=7.0.0,<9.0.0 and you require pytest==9.0.3, we can conclude that your requirements and syrupy==4.6.1 are incompatible. syrupy 5.0.0 is the lowest release that permits pytest 9. 6.1.1 is the highest. The 31 stored snapshots under resource/opentelemetry-resourcedetector-gcp/tests/__snapshots__ match unchanged under both, so this takes the highest and keeps the two requirements files identical outside their opentelemetry-api and opentelemetry-sdk pins.
….xfail In pytest 9, pytest.xfail is an instance of _pytest.outcomes._XFail rather than a function. Its __call__ is still annotated -> NoReturn, but pylint does not follow the annotation through __call__, so every variable assigned only in the branches of an if/elif chain whose else branch calls pytest.xfail is reported as possibly-used-before-assignment: tests/test_botocore_bedrock.py:1464:25: E0606: Possibly using variable 'finish_reason' before assignment (possibly-used-before-assignment) That accounts for 27 errors in this file and fails lint-instrumentation-botocore. pytest.xfail.Exception is _pytest.outcomes.XFailed in both pytest 7.4.4 and pytest 9.0.3, and _XFail.__call__ does nothing but raise it, so raising it directly is equivalent and pylint recognises the branch as terminating. Verified against pylint 4.0.9 with both pytest versions.
test_metrics_concurrent_requests issues a 1 second request to /slow and a fast request to /async at the same time, then requires the client-measured and server-measured durations of the slow one to agree within 10ms. On the GitHub Python 3.10 runners that assertion now lands between 21ms and 37ms, and the whole excess is on the client side. One failing run reported server_ms=1002 against client_s=1.0242199897766113, while a passing run on the same runner region reported server_ms=1003 against client_s=1.005490779876709. The client figure covers connection setup and the event loop dispatch of two concurrent fetches, neither of which the server figure includes, and the server figure is additionally quantised to whole milliseconds. 10ms of a 1 second measurement is 1 percent, which is below the noise floor of a shared runner. The purpose of the assertion is to catch per-request state being mixed up between concurrent requests, and that failure mode swaps a 1000ms duration for a 1ms one, so it stays caught with a far wider tolerance. 50ms is already what this same test allows for PyPy.
The previous commit widened the tolerance for the /slow request only. The client-side excess it describes applies to both requests of the pair, so the /async request now fails the same way: AssertionError: 0.021571563720703124 != 0.0 within 0.02 delta The reasoning is the one given in the previous commit, and 50ms is again what this test already allows for PyPy. The two assertions that follow compare only server-side values, 1002ms for /slow and 1ms to 3ms for /async, against a tolerance of 100ms, so they are unaffected by client-side time and are left alone.
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.
Raises
pytestto 9.0.3 across every requirements file in the repository, which is the fix for GHSA-6w46-j5rx-g56g, and carries the two changes that are required for the test suites to pass underpytest9.Definitions
A generated requirements file is a file whose contents
uv pip compileproduces from a sibling.infile, rather than a file edited by hand. In this repository such a file is namedtest-requirements.oldest.txtortest-requirements.latest.txtand is compiled fromtest-requirements.in. For example,instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.oldest.txtis compiled frominstrumentation/opentelemetry-instrumentation-fastapi/test-requirements.inwith--resolution lowest-direct.A lint environment is a
toxenvironment whose name begins withlint-and which installsdev-requirements.txttogether with thetest-requirements.txtof one package, resolving both in a singleuv pip installinvocation. Because the two files are resolved together, a version ofpytestpinned in one of them and a different version pinned in the other make the environment unsatisfiable.A floor is the lowest version of a distribution that a requirement permits. For example, the requirement
pytest~=9.0in atest-requirements.insets the floor ofpytestto 9.0, and--resolution lowest-directthen selects exactly that floor when compilingtest-requirements.oldest.txt.What this closes
60 open Dependabot alerts, all of them instances of the same advisory, GHSA-6w46-j5rx-g56g (GHSA-6w46-j5rx-g56g), severity medium, titled "pytest has vulnerable tmpdir handling". Its vulnerable range is
< 9.0.3and its first patched version is 9.0.3, so there is no version below 9.0.3 that clears it. Dependabot raises one alert per manifest file, which is why a single advisory accounts for 60 alerts in a repository that pinspytestin 121 files.Why the bump has to be atomic
Every file that pins
pytestmoves in this one pull request, and the bump cannot be split across several smaller ones. A lint environment installsdev-requirements.txtand one package'stest-requirements.txtin a single resolution, so as soon as those two files disagree the resolver fails with:This was confirmed by trying the split first: moving
pytestin a subset of the files turned everylint-job red.The seven commits
build(deps): bump flaky to 3.8.1is first becausepytest9.0.3 cannot be installed alongsideflaky3.7.0.flaky3.7.0 imports a name thatpytest9 removed, and collection aborts with:flaky3.8.1 works under bothpytest7.4.4 andpytest9.0.3, so this commit is green on its own. It touchesdev-requirements.txt,exporter/opentelemetry-exporter-richconsole/test-requirements.txtandtests/opentelemetry-docker-tests/tests/test-requirements.txt.fix(grpc): make the generated protobuf test directory an importable packageadds an emptyinstrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/__init__.py.pytest9 defaults to theimportlibimport mode, under which a directory with no__init__.pyis not a package, and the absolute import atinstrumentation/opentelemetry-instrumentation-grpc/tests/protobuf/test_server_pb2_grpc.py:3, writtenfrom tests.protobuf import test_server_pb2 as test__server__pb2, then fails at collection. The file carries only the licence header, matching the siblinginstrumentation/opentelemetry-instrumentation-grpc/tests/__init__.py.build(deps): bump pytest to 9.0.3is the bump itself, across 121 files. It also raisespytest-asynciofrom 0.23.5 to 1.4.1 in three files, becausepytest-asyncio0.23.5 declarespytest<9and 1.4.1 declarespytest<10,>=8.4. The three files areinstrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt,instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txtandinstrumentation/opentelemetry-instrumentation-click/test-requirements.txt.Six
test-requirements.infiles have theirpytestfloor raised to~=9.0, and their generated requirements files are recompiled withuv0.13.6 rather than hand-edited. Editing only thepytestline of anoldestfile leavespackagingpinned below 22, andpytest9 requirespackaging>=22.0, so the environment fails to install with:The six packages are
aio-pika,asyncclick,kafka-python,fastapi,sqlalchemyandstructlog.build(deps): bump syrupy to 6.1.1is required for the same reason as theflakybump:syrupy4.6.1 declarespytest>=7.0.0,<9.0.0, so the tworesourcedetector-gcpenvironments cannot be installed at all underpytest9.0.3.syrupy5.0.0 is the lowest release that permitspytest9 and 6.1.1 is the highest. The 31 stored snapshots underresource/opentelemetry-resourcedetector-gcp/tests/__snapshots__match unchanged under both, so this takes 6.1.1 and keepsresource/opentelemetry-resourcedetector-gcp/requirements.oldest.txtandresource/opentelemetry-resourcedetector-gcp/requirements.latest.txtidentical outside theiropentelemetry-apiandopentelemetry-sdkpins, which is the only difference between those two files today.fix(botocore): raise pytest.xfail.Exception instead of calling pytest.xfailchanges 11 call sites ininstrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py. Inpytest9,pytest.xfailis an instance of_pytest.outcomes._XFailrather than a function. Its__call__is still annotated-> NoReturn, butpylintdoes not follow that annotation through__call__, so every variable assigned only in the branches of anif/elifchain whoseelsebranch callspytest.xfailis reported aspossibly-used-before-assignment:That accounts for 27 errors in that one file and turns
lint-instrumentation-botocorered.pytest.xfail.Exceptionis_pytest.outcomes.XFailedin bothpytest7.4.4 andpytest9.0.3, and_XFail.__call__does nothing but raise it, so raising it directly is equivalent andpylintrecognises the branch as terminating. This was checked againstpylint4.0.9 with both versions ofpytestinstalled in turn.test(tornado): widen the concurrent-request duration tolerance to 50mschanges one argument ininstrumentation/opentelemetry-instrumentation-tornado/tests/test_metrics_instrumentation.py.test_metrics_concurrent_requestsissues a 1 second request to/slowand a fast request to/asyncat the same time, then requires the client-measured and server-measured durations of the slow one to agree within 10 ms. On the GitHub Python 3.10 runners that assertion now lands between 21 ms and 37 ms, and the whole excess is on the client side: one failing run reportedserver_ms=1002againstclient_s=1.0242199897766113, while a passing run in the same runner region reportedserver_ms=1003againstclient_s=1.005490779876709. The client figure covers connection setup and the event loop dispatch of two concurrent fetches, neither of which the server figure includes, and the server figure is quantised to whole milliseconds on top of that.I could not attribute the change to
pytest9 itself. A branch carrying nothing butpytest9.0.3 forinstrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt, on top of the same base commit, passes this test with a measured gap of 2.5 ms, and the tornado environment resolves to the same packages on both branches. 10 ms of a 1 second measurement is 1 percent, which is below the noise floor of a shared runner. The assertion exists to catch per-request state being mixed up between concurrent requests, and that failure mode substitutes a 1 ms duration for a 1000 ms one, so it is still caught with a far wider tolerance. 50 ms is what this same test already allows for PyPy.test(tornado): widen the second concurrent-request tolerance as wellextends the same change to the/asyncrequest of the pair, whose assertion then failed at0.021571563720703124against its own 20 ms tolerance. The two assertions that follow it compare only server-side values, 1002 ms for/slowand 1 ms to 3 ms for/async, against a tolerance of 100 ms, so client-side time does not reach them and they are left alone.The one generated requirements file that was not regenerated
instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.latest.txtis edited by hand, changing thepytestline and nothing else. This is the single deliberate exception to recompiling every generated requirements file that the previous section describes.Recompiling it moves
starlettefrom 1.3.1 down to 0.48.0, becauseinstrumentation/opentelemetry-instrumentation-fastapi/test-requirements.incarriesfastapi~=0.119.1and that range offastapicapsstarlettebelow 1.0.starlette0.48.0 is inside the vulnerable range of GHSA-82w8-qh3p-5jfq, so recompiling would reopen sixstarlettealerts while closingpytestones, which is a net loss.Raising the
fastapifloor far enough to keepstarletteat 1.3.1 contradicts the declared support range atinstrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml:37, which reads"fastapi ~= 0.92". That is a decision about which versions offastapithis instrumentation supports, not a dependency bump, so it is left out of this pull request.Verification
24 test suites were run locally on Python 3.12 against the branch, all passing:
richconsole4,grpc156 twice,aiohttp-server37,asyncio24,click8,asyncclick13 twice,aio-pika9,kafka-python14 twice,fastapi109 twice,asgi105,django83,flask64,falcon45,httpx179,celery35,botocore150,aiohttp-client48,sqlalchemy68 twice andstructlog36 twice.A scan over every requirements file in the branch confirms that no file pins a version of
packagingbelow 22 alongsidepytest9.0.3.