mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-24 17:23:36 +02:00
lib.App.call_async(): Add method
Use the AsyncRunner class introduced in the previous commit to add a call_async() method, allowing to run async functions from sync functions by spawning an extra event loop. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
67e51cf07c
commit
df40af9fc3
1 changed files with 26 additions and 2 deletions
|
|
@ -1,12 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Any
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
import os, sys, argparse, re, asyncio, cProfile
|
||||
|
||||
from .AsyncRunner import AsyncRunner
|
||||
from .log import *
|
||||
from .Types import LoadTypes
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import TypeVar
|
||||
from collections.abc import Awaitable
|
||||
T = TypeVar("T")
|
||||
|
||||
class App: # export
|
||||
|
||||
def _add_arguments(self, parser):
|
||||
|
|
@ -66,6 +74,7 @@ class App: # export
|
|||
if eloop is None:
|
||||
self.__eloop = asyncio.get_event_loop()
|
||||
self.__own_eloop = True
|
||||
self.__async_runner: AsyncRunner|None = None
|
||||
|
||||
self.__parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
description=description, add_help=False)
|
||||
|
|
@ -138,10 +147,19 @@ class App: # export
|
|||
async def _run(self, args: argparse.Namespace) -> None:
|
||||
return await self.args.func(args)
|
||||
|
||||
def call_async(self, awaitable: Awaitable[T], timeout: float | None = None) -> T:
|
||||
return self.async_runner.call(awaitable, timeout)
|
||||
|
||||
@property
|
||||
def eloop(self) -> asyncio.AbstractEventLoop:
|
||||
return self.__eloop
|
||||
|
||||
@property
|
||||
def async_runner(self) -> AsyncRunner:
|
||||
if self.__async_runner is None:
|
||||
self.__async_runner = AsyncRunner()
|
||||
return self.__async_runner
|
||||
|
||||
@property
|
||||
def cmdline(self) -> str:
|
||||
if self.__cmdline is None:
|
||||
|
|
@ -159,7 +177,13 @@ class App: # export
|
|||
return self.__parser
|
||||
|
||||
def run(self, argv=None) -> None:
|
||||
return self.__eloop.run_until_complete(self.__run(argv)) # type: ignore
|
||||
try:
|
||||
ret = self.__eloop.run_until_complete(self.__run(argv)) # type: ignore
|
||||
finally:
|
||||
if self.__async_runner:
|
||||
self.__async_runner.close()
|
||||
self.__async_runner = None
|
||||
return ret
|
||||
|
||||
def run_sub_commands(description = '', name_filter = '^Cmd.*', modules=None, argv=None): # export
|
||||
app = App(description, name_filter, modules)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue