fix(tests): use asyncio.run instead of get_event_loop in middleware tests - #1804
Conversation
…ests
Python 3.13 dropped auto-creation of an event loop in
asyncio.get_event_loop() when none is set on the thread, so the pattern
asyncio.get_event_loop().run_until_complete(coro)
now raises RuntimeError("There is no current event loop in thread
'MainThread'") whenever a previous test ran asyncio.run() and closed its
loop (the langchain_framework fixture triggers this on teardown via
_reset_frameworks).
Replaces all eight call sites in test_middleware.py with asyncio.run(),
which creates and owns its own loop. Behavior-equivalent, Python 3.13
compatible, and independent of prior test loop state.
Will be cherry-picked onto develop and merged first; then stack-10
and its descendants rebase.
Greptile SummaryReplaces nine occurrences of
|
| Filename | Overview |
|---|---|
| tests/guardrails/test_iorails.py | Single replacement of asyncio.get_event_loop().run_until_complete() with asyncio.run() inside a pytest.raises(RuntimeError) block; exception propagation is identical. |
| tests/integrations/langchain/test_middleware.py | Eight replacements of asyncio.get_event_loop().run_until_complete() with asyncio.run() across TestSyncMethods and TestGuardrailViolationException; all are sync test methods so no nested-loop issue. |
Sequence Diagram
sequenceDiagram
participant Test as Test (sync)
participant Old as asyncio.get_event_loop().run_until_complete()
participant New as asyncio.run()
participant Coro as Coroutine
Note over Test,Old: Python ≤ 3.12 (old pattern)
Test->>Old: get_event_loop()
Old-->>Test: returns existing/new loop
Test->>Old: run_until_complete(coro)
Old->>Coro: execute
Coro-->>Old: result / exception
Old-->>Test: result / propagated exception
Note over Test,New: Python 3.13+ (new pattern)
Test->>New: asyncio.run(coro)
New->>New: create fresh event loop
New->>Coro: execute
Coro-->>New: result / exception
New->>New: close event loop
New-->>Test: result / propagated exception
Reviews (1): Last reviewed commit: "fix(tests): use asyncio.run instead of g..." | Re-trigger Greptile
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR updates test infrastructure in two test files by replacing deprecated Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Python 3.13 removed auto creation of an event loop in
asyncio.get_event_loop()when none is set on the thread. The patternnow raises
RuntimeError("There is no current event loop in thread 'MainThread'")whenever a previous test ranasyncio.run()and closed its loop. This test-ordering race is flaky across CI runs (for ref: https://github.com/NVIDIA-NeMo/Guardrails/actions/runs/24666672357).Replaces all nine occurrences across
tests/integrations/langchain/test_middleware.py(eight) andtests/guardrails/test_iorails.py(one) withasyncio.run(...), which creates and owns its own loop. Behavior preserving python 313 compatible, independent of prior test loop state.Test plan
tests/integrations/langchain/test_middleware.py:tests/guardrails/test_iorails.py:Summary by CodeRabbit
Note: This release contains no user-facing changes. Updates are limited to internal testing infrastructure.