From 3e2416202ae23001561dfb2350a8964cb0535104 Mon Sep 17 00:00:00 2001 From: Ben Cherry Date: Thu, 21 Nov 2024 15:02:05 -0800 Subject: [PATCH 1/5] Raise error if EventEmitter used with async callback --- examples/participant_attributes.py | 2 +- livekit-rtc/livekit/rtc/event_emitter.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/participant_attributes.py b/examples/participant_attributes.py index cf203948..c2230a92 100644 --- a/examples/participant_attributes.py +++ b/examples/participant_attributes.py @@ -24,7 +24,7 @@ async def main(room: rtc.Room) -> None: ) @room.on("participant_attributes_changed") - def on_participant_attributes_changed( + async def on_participant_attributes_changed( changed_attributes: dict[str, str], participant: rtc.Participant ): logging.info( diff --git a/livekit-rtc/livekit/rtc/event_emitter.py b/livekit-rtc/livekit/rtc/event_emitter.py index 53e8c67b..7e62aca0 100644 --- a/livekit-rtc/livekit/rtc/event_emitter.py +++ b/livekit-rtc/livekit/rtc/event_emitter.py @@ -1,4 +1,5 @@ import inspect +import asyncio from typing import Callable, Dict, Set, Optional, Generic, TypeVar from .log import logger @@ -156,6 +157,11 @@ def greet(name): ``` """ if callback is not None: + if asyncio.iscoroutinefunction(callback): + raise ValueError( + "Cannot register an async callback with `.on()`. Use `asyncio.create_task` within your synchronous callback instead." + ) + if event not in self._events: self._events[event] = set() self._events[event].add(callback) From 15e6d8dc7d1dc7034970bbc6f23dd1f3b336cb6b Mon Sep 17 00:00:00 2001 From: Ben Cherry Date: Thu, 21 Nov 2024 15:06:01 -0800 Subject: [PATCH 2/5] ex --- examples/participant_attributes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/participant_attributes.py b/examples/participant_attributes.py index c2230a92..cf203948 100644 --- a/examples/participant_attributes.py +++ b/examples/participant_attributes.py @@ -24,7 +24,7 @@ async def main(room: rtc.Room) -> None: ) @room.on("participant_attributes_changed") - async def on_participant_attributes_changed( + def on_participant_attributes_changed( changed_attributes: dict[str, str], participant: rtc.Participant ): logging.info( From 640a19e5ccc3bf26ed75c06a9f8e44b45e1d7c01 Mon Sep 17 00:00:00 2001 From: Ben Cherry Date: Thu, 21 Nov 2024 16:13:13 -0800 Subject: [PATCH 3/5] fix flaky test --- livekit-rtc/tests/test_emitter.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/livekit-rtc/tests/test_emitter.py b/livekit-rtc/tests/test_emitter.py index f626e8c7..f647baad 100644 --- a/livekit-rtc/tests/test_emitter.py +++ b/livekit-rtc/tests/test_emitter.py @@ -51,35 +51,30 @@ def test_args(): emitter = EventEmitter[EventTypes]() - calls = [] + args_calls = [] - @emitter.on("whatever") + @emitter.on("whatever_args") def on_whatever(first, second, third): - calls.append((first, second, third)) + args_calls.append((first, second, third)) - emitter.emit("whatever", 1, 2, 3) - emitter.emit("whatever", 1, 2, 3, 4, 5) # only 3 arguments will be passed + emitter.emit("whatever_args", 1, 2, 3) + emitter.emit("whatever_args", 1, 2, 3, 4, 5) # only 3 arguments will be passed - assert len(calls) == 2 - assert calls[0] == (1, 2, 3) - assert calls[1] == (1, 2, 3) - - calls = [] + assert args_calls == [(1, 2, 3), (1, 2, 3)] with pytest.raises(TypeError): - emitter.emit("whatever", 1, 2) + emitter.emit("whatever_args", 1, 2) - assert len(calls) == 0 + varargs_calls = [] - @emitter.on("whatever") + @emitter.on("whatever_varargs") def on_whatever_varargs(*args): - calls.append(args) + varargs_calls.append(args) - emitter.emit("whatever", 1, 2, 3, 4, 5) + emitter.emit("whatever_varargs", 1, 2, 3, 4, 5) + emitter.emit("whatever_varargs", 1, 2) - assert len(calls) == 2 - assert calls[0] == (1, 2, 3) - assert calls[1] == (1, 2, 3, 4, 5) + assert varargs_calls == [(1, 2, 3, 4, 5), (1, 2)] def test_throw(): From 9bb921c3ad36c946eb45803cd400ec6dded5704e Mon Sep 17 00:00:00 2001 From: Ben Cherry Date: Thu, 21 Nov 2024 16:15:28 -0800 Subject: [PATCH 4/5] split --- livekit-rtc/tests/test_emitter.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/livekit-rtc/tests/test_emitter.py b/livekit-rtc/tests/test_emitter.py index f647baad..fb2616f3 100644 --- a/livekit-rtc/tests/test_emitter.py +++ b/livekit-rtc/tests/test_emitter.py @@ -53,26 +53,32 @@ def test_args(): args_calls = [] - @emitter.on("whatever_args") + @emitter.on("whatever") def on_whatever(first, second, third): args_calls.append((first, second, third)) - emitter.emit("whatever_args", 1, 2, 3) - emitter.emit("whatever_args", 1, 2, 3, 4, 5) # only 3 arguments will be passed + emitter.emit("whatever", 1, 2, 3) + emitter.emit("whatever", 1, 2, 3, 4, 5) # only 3 arguments will be passed assert args_calls == [(1, 2, 3), (1, 2, 3)] with pytest.raises(TypeError): - emitter.emit("whatever_args", 1, 2) + emitter.emit("whatever", 1, 2) + + +def test_varargs(): + EventTypes = Literal["whatever"] + + emitter = EventEmitter[EventTypes]() varargs_calls = [] - @emitter.on("whatever_varargs") + @emitter.on("whatever") def on_whatever_varargs(*args): varargs_calls.append(args) - emitter.emit("whatever_varargs", 1, 2, 3, 4, 5) - emitter.emit("whatever_varargs", 1, 2) + emitter.emit("whatever", 1, 2, 3, 4, 5) + emitter.emit("whatever", 1, 2) assert varargs_calls == [(1, 2, 3, 4, 5), (1, 2)] From 48f754da8c7092f5d3d67f64419e2ff4ee9e75a8 Mon Sep 17 00:00:00 2001 From: Ben Cherry Date: Thu, 21 Nov 2024 16:16:25 -0800 Subject: [PATCH 5/5] calls --- livekit-rtc/tests/test_emitter.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/livekit-rtc/tests/test_emitter.py b/livekit-rtc/tests/test_emitter.py index fb2616f3..830feb3a 100644 --- a/livekit-rtc/tests/test_emitter.py +++ b/livekit-rtc/tests/test_emitter.py @@ -51,16 +51,16 @@ def test_args(): emitter = EventEmitter[EventTypes]() - args_calls = [] + calls = [] @emitter.on("whatever") def on_whatever(first, second, third): - args_calls.append((first, second, third)) + calls.append((first, second, third)) emitter.emit("whatever", 1, 2, 3) emitter.emit("whatever", 1, 2, 3, 4, 5) # only 3 arguments will be passed - assert args_calls == [(1, 2, 3), (1, 2, 3)] + assert calls == [(1, 2, 3), (1, 2, 3)] with pytest.raises(TypeError): emitter.emit("whatever", 1, 2) @@ -71,16 +71,16 @@ def test_varargs(): emitter = EventEmitter[EventTypes]() - varargs_calls = [] + calls = [] @emitter.on("whatever") def on_whatever_varargs(*args): - varargs_calls.append(args) + calls.append(args) emitter.emit("whatever", 1, 2, 3, 4, 5) emitter.emit("whatever", 1, 2) - assert varargs_calls == [(1, 2, 3, 4, 5), (1, 2)] + assert calls == [(1, 2, 3, 4, 5), (1, 2)] def test_throw():