fix: replace deprecated asyncio event loop patterns for Python 3.14 compatibility - #876
fix: replace deprecated asyncio event loop patterns for Python 3.14 compatibility#876mangelajo wants to merge 10 commits into
Conversation
Upgrade project Python version from 3.11/3.12 to 3.14. Changes: - Update .py-version to 3.14 - Update all requires-python fields to >=3.14 across all packages - Update ruff target-version to py314 - Update CI to test with Python 3.14 - Update uv.lock with Python 3.14 compatible dependencies This required upgrading pydantic-core to 2.46.4 which has Python 3.14 support via prebuilt wheels. Note: Building with Python 3.14 requires: - PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 for Rust extensions - OpenBLAS (macOS: brew install openblas) - gfortran (macOS: brew install gcc) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add missing Apache-2.0 license to jumpstarter-driver-iscsi - Remove duplicate pytest-asyncio dependency in jumpstarter-driver-http - Fix jumpstarter-driver-opendal entry point group from adapters to drivers Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Revert jumpstarter-driver-opendal entry point back to jumpstarter.adapters - Update driver template to use Python 3.12+ (was 3.11) - Remove PR_DESCRIPTION.md file Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The .py-version file was updated to 3.14, so e2e tests also need build dependencies for Pillow and scipy since they don't have pre-built wheels for Python 3.14 yet. Added the same dependency installation steps to all e2e jobs that use .py-version: - e2e-tests - e2e-compat-old-controller - e2e-compat-old-client Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This empty commit triggers CI to test the Python 3.14 build dependencies. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Pillow, scipy, and cffi need system libraries when building from source for Python 3.14. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add build dependencies to type-check-python workflow - Fix .py-version to use full version 3.14.6 (e2e scripts require X.Y.Z format) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Python 3.14 requires explicit event loop management and doesn't allow creating asyncio.Event() or calling get_event_loop() in sync contexts. Changes: - Made on() and off() methods async - Simplified _snmp_set() to be async and use get_running_loop() - Removed manual event loop creation/management code - Updated all tests to use pytest.mark.asyncio - Removed redundant event loop mocking in tests This is a breaking API change - callers must now await on()/off(). However, many other Jumpstarter drivers already use async methods (http, mitmproxy, ble, etc.), so this pattern is established. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove unused Tuple import - Remove unused loop variable assignment Fixes ruff linting errors. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ompatibility - TFTP driver: replace new_event_loop()/set_event_loop()/run_until_complete() with asyncio.run(), and move TftpServer construction into async context so asyncio.Event() objects are created with a running loop (required by 3.14) - Shell driver: replace get_event_loop() with get_running_loop() (called from async context, but get_event_loop() is deprecated since 3.10) - mitmproxy example: replace ensure_future() with create_task()
|
Warning Review limit reached
Next review available in: 13 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (74)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Built on top of #775 (Python 3.14 upgrade). After the SNMP driver was fixed in 769be00, we audited the entire codebase for the same deprecated asyncio event loop patterns. Found three more locations that need fixing.
Audit findings
We searched all Python packages for these deprecated patterns:
asyncio.get_event_loop()— deprecated since 3.10, emitsDeprecationWarningin 3.12/3.13,RuntimeErrorin 3.14 (when no running loop)asyncio.new_event_loop()+set_event_loop()+run_until_complete()—set_event_loop()is deprecated since 3.10 and becomes a no-op in 3.14asyncio.Event()created outside async context — requiresget_running_loop()in 3.14,RuntimeErrorotherwiseasyncio.ensure_future()— deprecated since 3.10Compatibility matrix
get_event_loop()(no running loop)set_event_loop()asyncio.Event()(no running loop)ensure_future()get_running_loop()asyncio.run()asyncio.create_task()Changes
1. TFTP driver — HIGH RISK (will crash on 3.14)
jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.pyThe
_start_server()method used the exact same anti-pattern that was fixed in the SNMP driver:Three problems:
set_event_loop()is deprecated and becomes ineffective in 3.14TftpServer.__init__createsasyncio.Event()objects (server.py lines 52, 61) before the loop is running —RuntimeErrorin 3.14run_until_complete()+shutdown_asyncgens()+close()lifecycleFix: Replace with
asyncio.run()and moveTftpServerconstruction into an async method soasyncio.Event()objects are created with a running loop:2. Shell driver — MEDIUM RISK (deprecation warnings on 3.12/3.13)
jumpstarter-driver-shell/jumpstarter_driver_shell/driver.pylines 201, 208Called from
async def _run_inline_shell_script()so a loop IS running and it works today, butget_event_loop()emitsDeprecationWarningin 3.12+. Trivial swap to the correct API.3. mitmproxy example — LOW RISK (deprecated, still works)
jumpstarter-driver-mitmproxy/examples/addons/data_stream_websocket.pylines 134, 172Replaced
asyncio.ensure_future()(deprecated since 3.10) withasyncio.create_task().What was already clean
The rest of the codebase (including core jumpstarter, network driver, qemu driver, pyserial driver, etc.) already uses the correct modern APIs (
get_running_loop(),asyncio.run(),create_task()). The SNMP driver was fixed in 769be00.