Skip to content

fix(rtc): avoid deprecated asyncio.iscoroutinefunction in EventEmitter.on - #815

Merged
cloudwebrtc merged 1 commit into
livekit:mainfrom
xbt-a4224j:fix/event-emitter-iscoroutinefunction
Sep 15, 2026
Merged

cloudwebrtc merged 1 commit into
livekit:mainfrom
xbt-a4224j:fix/event-emitter-iscoroutinefunction

Conversation

@xbt-a4224j

@xbt-a4224j xbt-a4224j commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #790

Problem

EventEmitter.on() calls asyncio.iscoroutinefunction() to reject coroutine callbacks. That function is deprecated in Python 3.14 and slated for removal in 3.16 (CPython gh-122858), so on 3.14 every callback registration emits a DeprecationWarning. Room and friends register many handlers, so this is noisy in practice — the existing test suite alone produced 14 of them.

Fix

inspect.iscoroutinefunction() is the documented replacement, but it is not a drop-in: asyncio.iscoroutinefunction additionally treats any callable tagged with the private sentinel asyncio.coroutines._is_coroutine as a coroutine function. On Python 3.9, inspect.iscoroutinefunction(AsyncMock()) returns False — a bare swap would let a mocked async callback past the guard, so emit() would call the mock and silently discard the unawaited coroutine.

The fix keeps the sentinel check alongside inspect.iscoroutinefunction, read with getattr(..., None) so it degrades cleanly if the private attribute is removed in 3.16. Behaviour is identical to asyncio.iscoroutinefunction on every supported version and the deprecated function is never called.

Testing

Four tests added to tests/rtc/test_emitter.py, all running on every version in the matrix:

  • test_on_does_not_warn — promotes DeprecationWarning to an error around registration.
  • test_on_rejects_async_callbackasync def and functools.partial-wrapped.
  • test_on_rejects_sentinel_tagged_callback — exercises the sentinel branch directly.
  • test_on_rejects_async_mock — the real-world case; on 3.9 only the sentinel catches it.

Verified as a real flip against the released livekit wheel on all six supported Pythons (3.9–3.14): unpatched 1 failed / 7 passed / 14 warnings → patched 8 passed / 2 warnings.

@CLAassistant

CLAassistant commented Sep 14, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@xbt-a4224j
xbt-a4224j force-pushed the fix/event-emitter-iscoroutinefunction branch from aa6fba4 to 1e80990 Compare September 14, 2026 16:28
@xbt-a4224j
xbt-a4224j marked this pull request as ready for review September 14, 2026 16:50

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@cloudwebrtc cloudwebrtc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

@cloudwebrtc
cloudwebrtc merged commit ed8c9ce into livekit:main Sep 15, 2026
26 of 27 checks passed
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.

Python 3.14: EventEmitter uses deprecated asyncio.iscoroutinefunction

3 participants