Skip to content

fix: re-attach OTel span context in async test functions#1693

Merged
jirikuncar merged 4 commits intomainfrom
fix-pytest-async
Feb 9, 2026
Merged

fix: re-attach OTel span context in async test functions#1693
jirikuncar merged 4 commits intomainfrom
fix-pytest-async

Conversation

@jirikuncar
Copy link
Copy Markdown
Contributor

On Python 3.11+, when a module/session-scoped async fixture keeps anyio's runner task alive across tests, subsequent async tests inherit the first test's contextvars snapshot. This causes logfire.get_context() to return a stale traceparent and child spans to be mis-parented under the wrong test.

Use a pytest_pyfunc_call hookwrapper that wraps async test functions with functools.wraps to call context_api.attach() inside the coroutine body.

…yfunc_call hook

On Python 3.11+, when a module/session-scoped async fixture keeps anyio's
runner task alive across tests, subsequent async tests inherit the first
test's contextvars snapshot. This causes logfire.get_context() to return a
stale traceparent and child spans to be mis-parented under the wrong test.

Use a pytest_pyfunc_call hookwrapper that wraps async test functions with
functools.wraps to call context_api.attach() inside the coroutine body.
This is safer than an async autouse fixture, which breaks sync-only test
suites with PytestRemovedIn9Warning (will become a hard error in pytest 9).
@jirikuncar jirikuncar added the bug Bug related to the Logfire Python SDK label Feb 9, 2026
@jirikuncar jirikuncar self-assigned this Feb 9, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Feb 9, 2026

Deploying logfire-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: cc5731e
Status: ✅  Deploy successful!
Preview URL: https://cd9e95e0.logfire-docs.pages.dev
Branch Preview URL: https://fix-pytest-async.logfire-docs.pages.dev

View logs

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes OpenTelemetry context propagation for async pytest tests by re-attaching the per-test span context inside the coroutine body, preventing stale/empty contextvars snapshots (notably on Python 3.11+ with reused anyio runner tasks) from causing mis-parented spans and missing traceparent.

Changes:

  • Add a pytest_pyfunc_call hookwrapper that wraps async test functions and calls opentelemetry.context.attach() inside the coroutine.
  • Add regression tests ensuring async tests see the correct current span / traceparent and that child spans are parented under the correct per-test span when runner tasks are reused.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
logfire/_internal/integrations/pytest.py Adds a pytest_pyfunc_call hookwrapper to re-attach the per-test OTel span context within async test coroutines.
tests/otel_integrations/test_pytest_plugin.py Adds regression coverage for async context propagation, logfire.get_context() traceparent presence, and correct span parenting across multiple async tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jirikuncar jirikuncar merged commit f652c49 into main Feb 9, 2026
15 checks passed
@jirikuncar jirikuncar deleted the fix-pytest-async branch February 9, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bug related to the Logfire Python SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants