pkg.lib.App: Fix event loop for Python 3.14+ #59

Merged
Jan Lindemann merged 1 commit from jan/feature/20260814-pkg-lib-app-fix-event-loop-for-python into master 2026-08-14 23:03:04 +02:00 AGit

View file

@ -84,7 +84,7 @@ class App: # export
description: str = '', description: str = '',
name_filter: str = '^Cmd.*', name_filter: str = '^Cmd.*',
modules: list[str] | None = None, modules: list[str] | None = None,
eloop: None = None, eloop: asyncio.AbstractEventLoop | None = None,
) -> None: ) -> None:
def add_cmd_to_parser(cmd: AbstractCmd, parsers: Any) -> ArgumentParser: def add_cmd_to_parser(cmd: AbstractCmd, parsers: Any) -> ArgumentParser:
@ -171,12 +171,9 @@ class App: # export
set_log_flags(self.__default_log_flags) set_log_flags(self.__default_log_flags)
set_log_level(self.__default_log_level) set_log_level(self.__default_log_level)
self.__async_runner: AsyncRunner | None = None
self.__eloop = eloop self.__eloop = eloop
self.__own_eloop = False self.__own_eloop = False
if eloop is None:
self.__eloop = asyncio.get_event_loop()
self.__own_eloop = True
self.__async_runner: AsyncRunner | None = None
self.__parser = ArgumentParser( self.__parser = ArgumentParser(
formatter_class = ArgumentDefaultsHelpFormatter, formatter_class = ArgumentDefaultsHelpFormatter,
@ -212,12 +209,12 @@ class App: # export
'-h', '--help', action = 'help', help = 'Show this help message and exit' '-h', '--help', action = 'help', help = 'Show this help message and exit'
) )
def __del__(self) -> None: def close(self) -> None:
if self.__own_eloop: if self.__own_eloop:
if self.__eloop is not None: if self.__eloop is not None:
self.__eloop.close() if not self.__eloop.is_closed():
self.__eloop.close()
self.__eloop = None self.__eloop = None
self.__own_eloop = False
async def __aenter__(self) -> None: async def __aenter__(self) -> None:
pass pass
@ -333,12 +330,18 @@ class App: # export
return self.__parser return self.__parser
def run(self, argv: list[str] | None = None) -> None: def run(self, argv: list[str] | None = None) -> None:
if self.__eloop is None:
eloop = asyncio.new_event_loop()
asyncio.set_event_loop(eloop)
self.__eloop = eloop
self.__own_eloop = True
try: try:
ret = self.eloop.run_until_complete(self.__run(argv)) ret = self.eloop.run_until_complete(self.__run(argv))
finally: finally:
if self.__async_runner: if self.__async_runner:
self.__async_runner.close() self.__async_runner.close()
self.__async_runner = None self.__async_runner = None
self.close()
return ret return ret