Added more tests, improved README, removed simple_example.py
This commit is contained in:
parent
c9456e0837
commit
5ba185c11b
|
@ -63,7 +63,7 @@ async def main():
|
||||||
# with different priorities will be executed in order
|
# with different priorities will be executed in order
|
||||||
print("Firing non-blocking event 'hi'")
|
print("Firing non-blocking event 'hi'")
|
||||||
await emit("hi", block=False) # This one spawns hi() and returns immediately
|
await emit("hi", block=False) # This one spawns hi() and returns immediately
|
||||||
print("Non-blocking event 'hello' fired")
|
print("Non-blocking event 'hi' fired")
|
||||||
await emit("event3") # Does nothing: No handlers registered for event3!
|
await emit("event3") # Does nothing: No handlers registered for event3!
|
||||||
# We wait now for the the handler of the "hi" event to complete
|
# We wait now for the the handler of the "hi" event to complete
|
||||||
t = time.time()
|
t = time.time()
|
||||||
|
@ -76,6 +76,11 @@ if __name__ == "__main__":
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
```
|
```
|
||||||
|
|
||||||
|
__Note__: This example showed that the event names match the functions' names: this is just for explanatory purposes!
|
||||||
|
It's not compulsory for your event and their respective handlers' names to match. You can also register as many
|
||||||
|
functions you want for the same or multiple events and asyncevents will call them all when one of them is fired.
|
||||||
|
For more usage examples (until the documentation is done), check out the tests directory or read the source code:
|
||||||
|
it's pretty straightforward, I promise.
|
||||||
|
|
||||||
## TODOs
|
## TODOs
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ class AsyncEventEmitter:
|
||||||
:type event: str
|
:type event: str
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.handlers.get(event, None) is None:
|
if not self.handlers.get(event):
|
||||||
if self.on_unknown_event == UnknownEventHandling.IGNORE:
|
if self.on_unknown_event == UnknownEventHandling.IGNORE:
|
||||||
return
|
return
|
||||||
elif self.on_unknown_event == UnknownEventHandling.ERROR:
|
elif self.on_unknown_event == UnknownEventHandling.ERROR:
|
||||||
|
@ -83,7 +83,7 @@ class AsyncEventEmitter:
|
||||||
# It's a coroutine! Call it
|
# It's a coroutine! Call it
|
||||||
await self.on_unknown_event(self, event)
|
await self.on_unknown_event(self, event)
|
||||||
|
|
||||||
async def _catch_errors_in_awaitable(self, event: str, obj: Awaitable):
|
async def _handle_errors_in_awaitable(self, event: str, obj: Awaitable):
|
||||||
# Thanks to asyncio's *utterly amazing* (HUGE sarcasm there)
|
# Thanks to asyncio's *utterly amazing* (HUGE sarcasm there)
|
||||||
# exception handling, we have to make this wrapper so we can
|
# exception handling, we have to make this wrapper so we can
|
||||||
# catch errors on a per-handler basis
|
# catch errors on a per-handler basis
|
||||||
|
@ -125,7 +125,7 @@ class AsyncEventEmitter:
|
||||||
temp[-1][-2],
|
temp[-1][-2],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self._tasks.append((event, asyncio.create_task(self._catch_errors_in_awaitable(event, task))))
|
self._tasks.append((event, asyncio.create_task(self._handle_errors_in_awaitable(event, task))))
|
||||||
# We push back the elements
|
# We push back the elements
|
||||||
for t in temp:
|
for t in temp:
|
||||||
heappush(self.handlers[event], t)
|
heappush(self.handlers[event], t)
|
||||||
|
@ -145,7 +145,7 @@ class AsyncEventEmitter:
|
||||||
t = heappop(temp)
|
t = heappop(temp)
|
||||||
if t[-1]:
|
if t[-1]:
|
||||||
self.unregister_handler(event, t[-2])
|
self.unregister_handler(event, t[-2])
|
||||||
await self._catch_errors_in_awaitable(event, t[-2](self, event))
|
await self._handle_errors_in_awaitable(event, t[-2](self, event))
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import asyncio
|
||||||
|
from asyncevents import on_event, emit
|
||||||
|
|
||||||
|
|
||||||
|
@on_event("hello")
|
||||||
|
async def hello(_, event: str):
|
||||||
|
print(f"Hello {event!r}!")
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
print("Firing blocking event 'hello'")
|
||||||
|
await emit("hello")
|
||||||
|
print("Handlers for event 'hello' have exited")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
|
@ -0,0 +1,21 @@
|
||||||
|
import asyncio
|
||||||
|
from asyncevents import on_event, emit
|
||||||
|
|
||||||
|
|
||||||
|
@on_event("test")
|
||||||
|
@on_event("hello")
|
||||||
|
async def hello(_, event: str):
|
||||||
|
print(f"Hello {event!r}!")
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
print("Firing blocking event 'hello'")
|
||||||
|
await emit("hello")
|
||||||
|
print("Handlers for event 'hello' have exited")
|
||||||
|
print("Firing blocking event 'test'")
|
||||||
|
await emit("test")
|
||||||
|
print("Handlers for event 'test' have exited")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
|
@ -0,0 +1,23 @@
|
||||||
|
import time
|
||||||
|
import asyncio
|
||||||
|
from asyncevents import on_event, emit, wait
|
||||||
|
|
||||||
|
|
||||||
|
@on_event("hi")
|
||||||
|
async def hi(_, event: str):
|
||||||
|
print(f"Hi {event!r}! I'm going to sleep for 5 seconds")
|
||||||
|
await asyncio.sleep(5) # Simulates some work
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
print("Emitting event 'hi'")
|
||||||
|
await emit("hi", block=False)
|
||||||
|
print("Event 'hi' fired")
|
||||||
|
t = time.time()
|
||||||
|
print("Waiting on event 'hi'")
|
||||||
|
await wait("hi")
|
||||||
|
print(f"Waited for {time.time() - t:.2f} seconds")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
|
@ -4,10 +4,14 @@ from asyncevents import on_event, emit, get_current_emitter, ExceptionHandling
|
||||||
|
|
||||||
@on_event("error")
|
@on_event("error")
|
||||||
async def oh_no(_, event: str):
|
async def oh_no(_, event: str):
|
||||||
print("Goodbye!")
|
print(f"Goodbye after {event!r}!")
|
||||||
raise ValueError("D:")
|
raise ValueError("D:")
|
||||||
|
|
||||||
|
|
||||||
|
async def handle_error(_, exc: Exception, event: str):
|
||||||
|
print(f"Exception {type(exc).__name__!r} from {event!r} handled!")
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
try:
|
try:
|
||||||
await emit("error") # The error propagates
|
await emit("error") # The error propagates
|
||||||
|
@ -21,6 +25,10 @@ async def main():
|
||||||
get_current_emitter().on_error = ExceptionHandling.IGNORE # Silences the exception
|
get_current_emitter().on_error = ExceptionHandling.IGNORE # Silences the exception
|
||||||
await emit("error") # This won't raise nor log anything to the console. Yay x2!
|
await emit("error") # This won't raise nor log anything to the console. Yay x2!
|
||||||
print("We're safe again!")
|
print("We're safe again!")
|
||||||
|
# Let's try using a coroutine function as an exception handler
|
||||||
|
get_current_emitter().on_error = handle_error
|
||||||
|
await emit("error") # This will call handle_error with the exception object and the event name
|
||||||
|
print("We're safe once again!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import asyncio
|
||||||
|
from asyncevents import on_event, emit, get_current_emitter, UnknownEventHandling
|
||||||
|
from asyncevents.errors import UnknownEvent
|
||||||
|
|
||||||
|
|
||||||
|
@on_event("test")
|
||||||
|
@on_event("test2")
|
||||||
|
async def oh_no(_, event: str):
|
||||||
|
print(f"The event {event!r} definitely exists!")
|
||||||
|
|
||||||
|
|
||||||
|
async def handle_unknown_event(_, event: str):
|
||||||
|
print(f"The event {event!r} definitely does not exist!")
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
await emit("test")
|
||||||
|
await emit("test2")
|
||||||
|
await emit("test3") # Does nothing by default
|
||||||
|
get_current_emitter().on_unknown_event = UnknownEventHandling.LOG
|
||||||
|
await emit("test3") # Logs an error message
|
||||||
|
get_current_emitter().on_unknown_event = UnknownEventHandling.ERROR # Raises an exception
|
||||||
|
try:
|
||||||
|
await emit("test3")
|
||||||
|
except UnknownEvent:
|
||||||
|
print("Bang!")
|
||||||
|
get_current_emitter().on_unknown_event = handle_unknown_event # Calls the function with the event as argument
|
||||||
|
await emit("test3")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
|
@ -0,0 +1,18 @@
|
||||||
|
import asyncio
|
||||||
|
from asyncevents import on_event, emit
|
||||||
|
|
||||||
|
|
||||||
|
@on_event("hello", oneshot=True) # The handler is removed after it fires once
|
||||||
|
async def hello(_, event: str):
|
||||||
|
print(f"Hello {event!r}!")
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
print("Firing blocking event 'hello'")
|
||||||
|
await emit("hello")
|
||||||
|
print("Handlers for event 'hello' have exited")
|
||||||
|
await emit("hello") # Nothing happens
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
|
@ -1,36 +0,0 @@
|
||||||
import time
|
|
||||||
import asyncio
|
|
||||||
from asyncevents import on_event, emit, wait
|
|
||||||
|
|
||||||
|
|
||||||
@on_event("hello")
|
|
||||||
async def hello(_, event: str):
|
|
||||||
print(f"Hello {event!r}!")
|
|
||||||
|
|
||||||
|
|
||||||
@on_event("hi")
|
|
||||||
async def hi(_, event: str):
|
|
||||||
print(f"Hi {event!r}! I'm going to sleep for 5 seconds")
|
|
||||||
await asyncio.sleep(5) # Simulates some work
|
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
print("Firing blocking event 'hello'")
|
|
||||||
await emit("hello") # This call blocks until hello() terminates
|
|
||||||
print("Handlers for event 'hello' have exited")
|
|
||||||
# Notice how, until here, the output is in order: this is on purpose!
|
|
||||||
# When using blocking mode, asyncevents even guarantees that handlers
|
|
||||||
# with different priorities will be executed in order
|
|
||||||
print("Firing non-blocking event 'hi'")
|
|
||||||
await emit("hi", block=False) # This one spawns hi() and returns immediately
|
|
||||||
print("Non-blocking event 'hello' fired")
|
|
||||||
await emit("event3") # Does nothing: No handlers registered for event3!
|
|
||||||
# We wait now for the the handler of the "hi" event to complete
|
|
||||||
t = time.time()
|
|
||||||
print("Waiting on event 'hi'")
|
|
||||||
await wait("hi") # Waits until all the handlers triggered by the "hi" event exit
|
|
||||||
print(f"Waited for {time.time() - t:.2f} seconds") # Should print roughly 5 seconds
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
Loading…
Reference in New Issue