76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
import inspect
|
|
import functools
|
|
from threading import local
|
|
from structio.abc import BaseKernel, BaseDebugger, BaseClock, SignalManager, BaseIOManager
|
|
from structio.exceptions import StructIOException
|
|
from structio.core.task import Task
|
|
from typing import Callable, Any, Coroutine
|
|
|
|
_RUN = local()
|
|
|
|
|
|
def current_loop() -> BaseKernel:
|
|
"""
|
|
Returns the current event loop in the calling
|
|
thread. Raises a StructIOException if no async
|
|
context exists
|
|
"""
|
|
try:
|
|
return _RUN.kernel
|
|
except AttributeError:
|
|
raise StructIOException("must be called from async context") from None
|
|
|
|
|
|
def current_task() -> Task:
|
|
"""
|
|
Shorthand for current_loop().current_task
|
|
"""
|
|
|
|
return current_loop().current_task
|
|
|
|
|
|
def new_event_loop(kernel: BaseKernel):
|
|
"""
|
|
Initializes a new event loop using the
|
|
given kernel implementation. Cannot be
|
|
called from an asynchronous context
|
|
"""
|
|
|
|
try:
|
|
current_loop()
|
|
except StructIOException:
|
|
_RUN.kernel = kernel
|
|
else:
|
|
if not _RUN.kernel.done():
|
|
raise StructIOException("cannot be called from running async context") from None
|
|
|
|
|
|
def run(func: Callable[[Any, Any], Coroutine[Any, Any, Any]],
|
|
kernel: type, io_manager: BaseIOManager, signal_managers: list[SignalManager],
|
|
clock: BaseClock, tools: list[BaseDebugger] | None = None,
|
|
restrict_ki_to_checkpoints: bool = False,
|
|
*args):
|
|
"""
|
|
Starts the event loop from a synchronous entry point. All
|
|
positional arguments are passed to the given coroutine
|
|
function. If you want to pass keyword arguments, consider
|
|
using functools.partial()
|
|
"""
|
|
|
|
if not issubclass(kernel, BaseKernel):
|
|
raise TypeError(f"kernel must be a subclass of {BaseKernel.__module__}.{BaseKernel.__qualname__}!")
|
|
check = func
|
|
if isinstance(func, functools.partial):
|
|
check = func.func
|
|
if inspect.iscoroutine(check):
|
|
raise StructIOException(
|
|
"Looks like you tried to call structio.run(your_func(arg1, arg2, ...)), that is wrong!"
|
|
"\nWhat you wanna do, instead, is this: structio.run(your_func, arg1, arg2, ...)"
|
|
)
|
|
elif not inspect.iscoroutinefunction(check):
|
|
raise StructIOException("structio.run() requires an async function as its first argument!")
|
|
new_event_loop(kernel(clock=clock, restrict_ki_to_checkpoints=restrict_ki_to_checkpoints,
|
|
io_manager=io_manager, signal_managers=signal_managers,
|
|
tools=tools))
|
|
return current_loop().start(func, *args)
|