Skip to content

feat(asyncpg): Add cursor span support via BaseCursor method patching#6252

Open
ericapisani wants to merge 3 commits into
masterfrom
py-2408-asyncpg-cursor-span-support
Open

feat(asyncpg): Add cursor span support via BaseCursor method patching#6252
ericapisani wants to merge 3 commits into
masterfrom
py-2408-asyncpg-cursor-span-support

Conversation

@ericapisani
Copy link
Copy Markdown
Member

@ericapisani ericapisani commented May 11, 2026

Patch BaseCursor._bind_exec, _bind, and _exec instead of wrapping Connection.cursor creation. The old approach only captured cursor creation, not actual query execution. The new approach creates spans for each cursor operation (iteration via _bind_exec, explicit cursor usage via _bind/_exec) and supports both static and streaming span lifecycles.

Builds on #6215 which added streaming span support to the asyncpg integration.

Removes the patch on asyncpg.Connection.cursor because the patches on BaseCursor introduced in this pull request will create the correct span when the cursor is used.

Fixes PY-2408
Fixes #6240

Patch BaseCursor._bind_exec, _bind, and _exec instead of wrapping
Connection.cursor creation. This creates spans for each cursor operation
(iteration via _bind_exec, and explicit cursor usage via _bind/_exec),
and supports both static and streaming span lifecycles.

Fixes PY-2408
Fixes #6240
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 11, 2026

PY-2408

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

Codecov Results 📊

13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 16.55s

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

❌ Patch coverage is 0.00%. Project has 15158 uncovered lines.
❌ Project coverage is 31.27%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
asyncpg.py 10.64% ⚠️ 126 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    31.28%    31.27%    -0.01%
==========================================
  Files          190       190         —
  Lines        22052     22055        +3
  Branches      7408      7410        +2
==========================================
+ Hits          6897      6897         —
- Misses       15155     15158        +3
- Partials       583       583         —

Generated by Codecov Action

@ericapisani
Copy link
Copy Markdown
Member Author

bugbot run

@ericapisani
Copy link
Copy Markdown
Member Author

@sentry review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit b81ac97. Configure here.

asyncpg.Connection._executemany = _wrap_connection_method(
asyncpg.Connection._executemany, executemany=True
)
asyncpg.Connection.cursor = _wrap_cursor_creation(asyncpg.Connection.cursor)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is safe to remove because this patches the function that led to the creation/return of a CursorFactory. When that cursor is awaited, the CursorFactory calls _bind through the underlying cursor's init method, essentially capturing the creation and invocation of the cursor (as opposed to just capturing the creation of the factory which is what was happening previously)



@pytest.mark.asyncio
async def test_cursor__bind_and__exec_methods_create_spans(
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I did my best to create some distinction between this and test_cursor__bind_exec_creates_spans but in case this naming causes confusion:

This test tests the _bind and _exec patches, whereas the other test above checks the _bind_exec patch.

@ericapisani ericapisani marked this pull request as ready for review May 11, 2026 18:46
@ericapisani ericapisani requested a review from a team as a code owner May 11, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Investigate missing span coverage on queries run by an asyncpg Cursor

1 participant