cengal.parallel_execution.coroutines.integrations.qt.pyside6.versions.v_0.pyside6
1#!/usr/bin/env python 2# coding=utf-8 3 4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space> 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18 19__all__ = [ 20 'WrongQtVersion', 21 'exec_app', 22 'execa', 23 'aemit_signal', 24 'aemit', 25 'by_coro', 26 'aby_coro', 27 'modal_blocking', 28 'amodal_blocking', 29 'block_main_loop', 30 'ablock_main_loop', 31 'modal', 32 'amodal', 33 'CoroSlot', 34 'CSlot', 35 'coro_slot_implicit', 36 'cslot_implicit', 37 'csloti', 38 'csi', 39 'coro_slot_gly_patched', 40 'cslot_gly_patched', 41 'cslotglyp', 42 'cslotgp', 43 'csgp', 44 'coro_slot_agly_patched', 45 'cslot_agly_patched', 46 'cslotaglyp', 47 'cslotagp', 48 'csagp', 49 'coro_slot_explicit', 50 'cslot_explicit', 51 'cslotex', 52 'csex', 53 'qt_exec_in_coro', 54 'aqt_exec_in_coro', 55 'CoroThreadWorker', 56 'CoroThreadWithWorker', 57] 58 59 60""" 61Module Docstring 62Docstrings: http://www.python.org/dev/peps/pep-0257/ 63""" 64 65__author__ = "ButenkoMS <gtalk@butenkoms.space>" 66__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>" 67__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ] 68__license__ = "Apache License, Version 2.0" 69__version__ = "4.4.1" 70__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>" 71__email__ = "gtalk@butenkoms.space" 72# __status__ = "Prototype" 73__status__ = "Development" 74# __status__ = "Production" 75 76 77from cengal.parallel_execution.coroutines.coro_scheduler import CoroScheduler, CoroSchedulerType, Interface, Coro, AnyWorker, current_interface, current_coro_scheduler, cs_coro, cs_acoro 78from cengal.parallel_execution.coroutines.coro_standard_services.loop_yield import gly, CoroPriority, gly_patched, agly_patched 79from cengal.parallel_execution.coroutines.coro_standard_services.run_coro import RunCoro 80from cengal.parallel_execution.coroutines.coro_standard_services.put_coro import PutCoro 81from cengal.parallel_execution.coroutines.coro_standard_services.asyncio_loop import AsyncioLoopRequest 82from cengal.parallel_execution.coroutines.coro_standard_services.async_event_bus import AsyncEventBusRequest, try_send_async_event 83from cengal.parallel_execution.coroutines.coro_standard_services.simple_yield import Yield 84from cengal.parallel_execution.coroutines.coro_standard_services.shutdown_loop import ShutdownLoop 85from cengal.parallel_execution.coroutines.coro_standard_services.instance import InstanceRequest 86from cengal.parallel_execution.coroutines.coro_tools.run_in_loop import run_in_loop 87from cengal.parallel_execution.coroutines.integrations.qt.common.exceptions import WrongQtVersion 88from cengal.code_flow_control.smart_values import ValueHolder 89from cengal.data_generation.id_generator import IDGenerator 90 91from PySide6.QtCore import Slot, QObject, Qt, QTimer, Signal, QThread 92from PySide6.QtWidgets import QApplication 93 94from inspect import signature, Signature 95from contextlib import contextmanager, asynccontextmanager 96from functools import wraps, update_wrapper, partial 97from typing import Optional, Any, Callable, Hashable 98 99 100YIELD_ALLOWED_EVENT = 'QT_yield_allowed_event' 101YIELD_IN_WORK_EVENT = 'QT_yield_in_work_event' 102MODAL_RESULT_EVENT = 'QT_modal_result_event' 103MODAL_COUNTER = IDGenerator() 104 105 106def exec_app(app, default_priority: CoroPriority = CoroPriority.normal) -> int: 107 if not isinstance(app, QApplication): 108 raise WrongQtVersion('Qt version is not PySide6') 109 110 timer = QTimer() 111 ly = gly(default_priority) 112 yield_allowed: ValueHolder[bool] = ValueHolder(True, True) 113 yield_in_work: ValueHolder[bool] = ValueHolder(True, True) 114 def yield_func(): 115 if yield_allowed.value: 116 yield_in_work.value = True 117 ly() 118 else: 119 yield_in_work.value = False 120 121 i: Interface = current_interface() 122 i(InstanceRequest().set(YIELD_ALLOWED_EVENT, yield_allowed)) 123 i(InstanceRequest().set(YIELD_IN_WORK_EVENT, yield_in_work)) 124 timer.timeout.connect(yield_func, Qt.ConnectionType.QueuedConnection) 125 timer.start(0) 126 def cleanup_callback(): 127 timer.stop() 128 129 app.aboutToQuit.connect(cleanup_callback) 130 return app.exec() 131 132 133execa = exec_app 134 135 136async def aemit_signal(signal, *args, **kwargs): 137 i: Interface = current_interface() 138 def coro(i: Interface): 139 signal.emit(*args, **kwargs) 140 141 return await i(RunCoro, coro) 142 143 144aemit = aemit_signal 145 146 147def by_coro(callable: Callable, *args, **kwargs): 148 def coro(i: Interface): 149 callable(*args, **kwargs) 150 151 return current_interface()(RunCoro, coro) 152 153 154async def aby_coro(callable: Callable, *args, **kwargs): 155 def coro(i: Interface): 156 callable(*args, **kwargs) 157 158 return await current_interface()(RunCoro, coro) 159 160 161def stop_yield_to_main_loop(): 162 i: Interface = current_interface() 163 yield_allowed: ValueHolder[bool] = i(InstanceRequest().wait(YIELD_ALLOWED_EVENT)) 164 yield_allowed.value = False 165 yield_in_work: ValueHolder[bool] = i(InstanceRequest().wait(YIELD_IN_WORK_EVENT)) 166 while yield_in_work.value: 167 i(Yield) 168 169 170@contextmanager 171def block_main_loop(): 172 i: Interface = current_interface() 173 yield_allowed: ValueHolder[bool] = i(InstanceRequest().wait(YIELD_ALLOWED_EVENT)) 174 yield_allowed.value = False 175 yield_in_work: ValueHolder[bool] = i(InstanceRequest().wait(YIELD_IN_WORK_EVENT)) 176 while yield_in_work.value: 177 i(Yield) 178 179 try: 180 yield 181 finally: 182 yield_allowed.value = True 183 184 185@asynccontextmanager 186async def ablock_main_loop(): 187 i: Interface = current_interface() 188 yield_allowed: ValueHolder[bool] = await i(InstanceRequest().wait(YIELD_ALLOWED_EVENT)) 189 yield_allowed.value = False 190 yield_in_work: ValueHolder[bool] = await i(InstanceRequest().wait(YIELD_IN_WORK_EVENT)) 191 while yield_in_work.value: 192 await i(Yield) 193 194 try: 195 yield 196 finally: 197 yield_allowed.value = True 198 199 200def modal_blocking(modal_obj, *args, **kwargs): 201 with block_main_loop(): 202 return modal_obj(*args, **kwargs) 203 204 205async def amodal_blocking(modal_obj, *args, **kwargs): 206 async with ablock_main_loop(): 207 return modal_obj(*args, **kwargs) 208 209 210def modal(callable_with_modal, *args, **kwargs): 211 class ShowModal(QObject): 212 signal = Signal() 213 214 def __init__(self, cs: CoroSchedulerType, result_event: Hashable): 215 super().__init__() 216 self.cs: CoroSchedulerType = cs 217 self.result_event: Hashable = result_event 218 self.signal.connect(self.show_modal, Qt.ConnectionType.QueuedConnection) 219 220 def show_modal(self): 221 result = callable_with_modal(*args, **kwargs) 222 try_send_async_event(self.cs, self.result_event, result) 223 224 event = (MODAL_RESULT_EVENT, MODAL_COUNTER()) 225 sm: ShowModal = ShowModal(current_coro_scheduler(), event) 226 sm.signal.emit() 227 i: Interface = current_interface() 228 return i(AsyncEventBusRequest().wait(event)) 229 230 231async def amodal(callable_with_modal, *args, **kwargs): 232 class ShowModal(QObject): 233 signal = Signal() 234 235 def __init__(self, cs: CoroSchedulerType, result_event: Hashable): 236 super().__init__() 237 self.cs: CoroSchedulerType = cs 238 self.result_event: Hashable = result_event 239 self.signal.connect(self.show_modal, Qt.ConnectionType.QueuedConnection) 240 241 def show_modal(self): 242 result = callable_with_modal(*args, **kwargs) 243 try_send_async_event(self.cs, self.result_event, result) 244 245 event = (MODAL_RESULT_EVENT, MODAL_COUNTER()) 246 sm: ShowModal = ShowModal(current_coro_scheduler(), event) 247 sm.signal.emit() 248 i: Interface = current_interface() 249 return await i(AsyncEventBusRequest().wait(event)) 250 251 252# class CoroSlot(QObject): 253class CoroSlot: 254 def __init__(self, *types: type, name: Optional[str] = None, result: Optional[str] = None) -> None: 255 self._types = types 256 self._name = name 257 self._result = result 258 self._coro = None 259 260 def __call__(self, coro: Coro, method = None) -> Any: 261 method = method or self.implicit_coro_impl 262 return method(coro) 263 264 def implicit_coro_impl(self, coro: Coro) -> Any: 265 self._coro = coro 266 267 def func_wrapper(*args, **kwargs): 268 cs: CoroSchedulerType = current_coro_scheduler() 269 service: PutCoro = cs.get_service_instance(PutCoro) 270 return service._add_direct_request(cs_coro(coro), *args, **kwargs) 271 272 coro_worker_sign: Signature = signature(coro) 273 update_wrapper(func_wrapper, coro) 274 func_wrapper.__signature__ = coro_worker_sign.replace(parameters=tuple(coro_worker_sign.parameters.values()), return_annotation=coro_worker_sign.return_annotation) 275 return Slot(*self._types, self._name, self._result)(func_wrapper) 276 277 def implicit_coro(self): 278 return partial(self, method=self.implicit_coro_impl) 279 280 ic = implicit_coro 281 282 def gly_patched_function_impl(self, func: Callable) -> Any: 283 return self.__call__(gly_patched(func)) 284 285 def gly_patched_function(self) -> Any: 286 return partial(self, method=self.gly_patched_function_impl) 287 288 glypf = gly_patched_function 289 gpf = gly_patched_function 290 gp = gly_patched_function 291 292 def agly_patched_function_impl(self, afunc: Callable) -> Any: 293 return self.__call__(agly_patched(afunc)) 294 295 def agly_patched_function(self) -> Any: 296 return partial(self, method=self.agly_patched_function_impl) 297 298 aglypf = agly_patched_function 299 agpf = agly_patched_function 300 agp = agly_patched_function 301 302 def explicit_coro_impl(self, coro: Coro) -> Any: 303 self._coro = coro 304 305 def func_wrapper(*args, **kwargs): 306 cs: CoroSchedulerType = current_coro_scheduler() 307 service: PutCoro = cs.get_service_instance(PutCoro) 308 return service._add_direct_request(coro, *args, **kwargs) 309 310 coro_worker_sign: Signature = signature(coro) 311 update_wrapper(func_wrapper, coro) 312 func_wrapper.__signature__ = coro_worker_sign.replace(parameters=tuple(coro_worker_sign.parameters.values())[1:], return_annotation=coro_worker_sign.return_annotation) 313 return Slot(*self._types, self._name, self._result)(func_wrapper) 314 315 def explicit_coro(self) -> Any: 316 return partial(self, method=self.explicit_coro_impl) 317 318 ec = explicit_coro 319 interface = explicit_coro 320 i = interface 321 322 323CSlot = CoroSlot 324 325 326def coro_slot_implicit(*types: type, name: Optional[str] = None, result: Optional[str] = None): 327 def decorator(coro: Coro) -> Any: 328 return CoroSlot(*types, name=name, result=result).implicit_coro()(coro) 329 330 return decorator 331 332cslot_implicit = coro_slot_implicit 333csloti = coro_slot_implicit 334csi = coro_slot_implicit 335 336 337def coro_slot_gly_patched(*types: type, name: Optional[str] = None, result: Optional[str] = None): 338 def decorator(func: Callable) -> Any: 339 return CoroSlot(*types, name=name, result=result).gly_patched_function()(func) 340 341 return decorator 342 343cslot_gly_patched = coro_slot_gly_patched 344cslotglyp = coro_slot_gly_patched 345cslotgp = coro_slot_gly_patched 346csgp = coro_slot_gly_patched 347 348 349def coro_slot_agly_patched(*types: type, name: Optional[str] = None, result: Optional[str] = None): 350 def decorator(afunc: Callable) -> Any: 351 return CoroSlot(*types, name=name, result=result).agly_patched_function()(afunc) 352 353 return decorator 354 355cslot_agly_patched = coro_slot_agly_patched 356cslotaglyp = coro_slot_agly_patched 357cslotagp = coro_slot_agly_patched 358csagp = coro_slot_gly_patched 359 360 361def coro_slot_explicit(*types: type, name: Optional[str] = None, result: Optional[str] = None): 362 def decorator(coro: Coro) -> Any: 363 return CoroSlot(*types, name=name, result=result).explicit_coro()(coro) 364 365 return decorator 366 367cslot_explicit = coro_slot_explicit 368cslotex = coro_slot_explicit 369csex = coro_slot_explicit 370 371 372def qt_exec_in_coro(func: Callable, default_priority: CoroPriority = CoroPriority.normal) -> Callable: 373 @wraps(func) 374 def wrapper(*args, **kwargs): 375 cs: CoroSchedulerType = current_coro_scheduler() 376 cs.high_cpu_utilisation_mode = False 377 cs.use_internal_sleep = False 378 i: Interface = current_interface() 379 i(AsyncioLoopRequest().use_higher_level_sleep_manager()) 380 i(AsyncioLoopRequest().ensure_loop(interrupt_when_no_requests=True)) 381 i(AsyncioLoopRequest().turn_on_loops_intercommunication()) 382 383 app_or_tuple = func(*args, **kwargs) 384 on_exit = lambda ret: ret 385 if isinstance(app_or_tuple, QApplication): 386 app = app_or_tuple 387 elif isinstance(app_or_tuple, tuple): 388 app, on_exit = app_or_tuple 389 else: 390 raise RuntimeError("qt_exec_in_coro must return either QApplication or (QApplication, on_exit) tuple") 391 392 # Run the event loop 393 ret = i(RunCoro, cs_coro(execa), app, default_priority) 394 ret = i(RunCoro, cs_coro(on_exit), ret) 395 i(ShutdownLoop) 396 return ret 397 398 return cs_coro(wrapper) 399 400 401async def aqt_exec_in_coro(func: Callable, default_priority: CoroPriority = CoroPriority.normal) -> Callable: 402 @wraps(func) 403 async def wrapper(*args, **kwargs): 404 i: Interface = current_interface() 405 await i(AsyncioLoopRequest().ensure_loop(interrupt_when_no_requests=True)) 406 await i(AsyncioLoopRequest().turn_on_loops_intercommunication()) 407 408 app_or_tuple = func(*args, **kwargs) 409 on_exit = lambda ret: ret 410 if isinstance(app_or_tuple, QApplication): 411 app = app_or_tuple 412 else: 413 app, on_exit = app_or_tuple 414 415 ret = await i(RunCoro, cs_coro(execa), app, default_priority) 416 ret = await i(RunCoro, cs_coro(on_exit), ret) 417 await i(ShutdownLoop) 418 return ret 419 420 return cs_acoro(wrapper) 421 422 423class CoroThreadWorker(QObject): 424 def __init__(self, worker: AnyWorker) -> None: 425 super().__init__() 426 self._worker: AnyWorker = worker 427 self._cs: CoroSchedulerType = None 428 self.allowed_to_run = False 429 430 def run(self): 431 self.allowed_to_run = True 432 async def my_worker_wrapper(i: Interface, worker): 433 self._cs = current_coro_scheduler() 434 await i(RunCoro, self.setup) 435 await i(RunCoro, worker) 436 437 run_in_loop(my_worker_wrapper, self._worker) 438 439 async def setup(self, i: Interface): 440 await i(AsyncioLoopRequest().ensure_loop(interrupt_when_no_requests=True)) 441 await i(AsyncioLoopRequest().turn_on_loops_intercommunication()) 442 443 def stop(self): 444 if not self.allowed_to_run: 445 return 446 447 self.allowed_to_run = False 448 async def coro(i: Interface): 449 await i(ShutdownLoop) 450 451 if self._cs is not None: 452 service: PutCoro = self._cs.get_service_instance(PutCoro) 453 return service._add_direct_request(coro) 454 455 456class CoroThread(QThread): 457 def __init__(self, parent, worker: CoroThreadWorker) -> None: 458 super().__init__(parent) 459 self._worker: CoroThreadWorker = worker 460 self._worker.moveToThread(self) 461 self.started.connect(self._worker.run) 462 463 def stop(self): 464 self.quit() 465 self.wait() 466 467 468class CoroThreadWithWorker(CoroThreadWorker): 469 def __init__(self, parent, worker: AnyWorker) -> None: 470 super().__init__(worker) 471 self._thread: CoroThread = CoroThread(parent, self) 472 473 def start(self): 474 self._thread.start() 475 476 def stop(self): 477 super().stop() 478 self._thread.stop()
class
WrongQtVersion(builtins.Exception):
Common base class for all non-exit exceptions.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
- args
def
exec_app( app, default_priority: cengal.parallel_execution.coroutines.coro_standard_services.loop_yield.versions.v_0.loop_yield.CoroPriority = <CoroPriority.normal: 1>) -> int:
107def exec_app(app, default_priority: CoroPriority = CoroPriority.normal) -> int: 108 if not isinstance(app, QApplication): 109 raise WrongQtVersion('Qt version is not PySide6') 110 111 timer = QTimer() 112 ly = gly(default_priority) 113 yield_allowed: ValueHolder[bool] = ValueHolder(True, True) 114 yield_in_work: ValueHolder[bool] = ValueHolder(True, True) 115 def yield_func(): 116 if yield_allowed.value: 117 yield_in_work.value = True 118 ly() 119 else: 120 yield_in_work.value = False 121 122 i: Interface = current_interface() 123 i(InstanceRequest().set(YIELD_ALLOWED_EVENT, yield_allowed)) 124 i(InstanceRequest().set(YIELD_IN_WORK_EVENT, yield_in_work)) 125 timer.timeout.connect(yield_func, Qt.ConnectionType.QueuedConnection) 126 timer.start(0) 127 def cleanup_callback(): 128 timer.stop() 129 130 app.aboutToQuit.connect(cleanup_callback) 131 return app.exec()
def
execa( app, default_priority: cengal.parallel_execution.coroutines.coro_standard_services.loop_yield.versions.v_0.loop_yield.CoroPriority = <CoroPriority.normal: 1>) -> int:
107def exec_app(app, default_priority: CoroPriority = CoroPriority.normal) -> int: 108 if not isinstance(app, QApplication): 109 raise WrongQtVersion('Qt version is not PySide6') 110 111 timer = QTimer() 112 ly = gly(default_priority) 113 yield_allowed: ValueHolder[bool] = ValueHolder(True, True) 114 yield_in_work: ValueHolder[bool] = ValueHolder(True, True) 115 def yield_func(): 116 if yield_allowed.value: 117 yield_in_work.value = True 118 ly() 119 else: 120 yield_in_work.value = False 121 122 i: Interface = current_interface() 123 i(InstanceRequest().set(YIELD_ALLOWED_EVENT, yield_allowed)) 124 i(InstanceRequest().set(YIELD_IN_WORK_EVENT, yield_in_work)) 125 timer.timeout.connect(yield_func, Qt.ConnectionType.QueuedConnection) 126 timer.start(0) 127 def cleanup_callback(): 128 timer.stop() 129 130 app.aboutToQuit.connect(cleanup_callback) 131 return app.exec()
async def
aemit_signal(signal, *args, **kwargs):
async def
aemit(signal, *args, **kwargs):
def
by_coro(callable: Callable, *args, **kwargs):
async def
aby_coro(callable: Callable, *args, **kwargs):
def
modal_blocking(modal_obj, *args, **kwargs):
async def
amodal_blocking(modal_obj, *args, **kwargs):
@contextmanager
def
block_main_loop():
171@contextmanager 172def block_main_loop(): 173 i: Interface = current_interface() 174 yield_allowed: ValueHolder[bool] = i(InstanceRequest().wait(YIELD_ALLOWED_EVENT)) 175 yield_allowed.value = False 176 yield_in_work: ValueHolder[bool] = i(InstanceRequest().wait(YIELD_IN_WORK_EVENT)) 177 while yield_in_work.value: 178 i(Yield) 179 180 try: 181 yield 182 finally: 183 yield_allowed.value = True
@asynccontextmanager
async def
ablock_main_loop():
186@asynccontextmanager 187async def ablock_main_loop(): 188 i: Interface = current_interface() 189 yield_allowed: ValueHolder[bool] = await i(InstanceRequest().wait(YIELD_ALLOWED_EVENT)) 190 yield_allowed.value = False 191 yield_in_work: ValueHolder[bool] = await i(InstanceRequest().wait(YIELD_IN_WORK_EVENT)) 192 while yield_in_work.value: 193 await i(Yield) 194 195 try: 196 yield 197 finally: 198 yield_allowed.value = True
def
modal(callable_with_modal, *args, **kwargs):
211def modal(callable_with_modal, *args, **kwargs): 212 class ShowModal(QObject): 213 signal = Signal() 214 215 def __init__(self, cs: CoroSchedulerType, result_event: Hashable): 216 super().__init__() 217 self.cs: CoroSchedulerType = cs 218 self.result_event: Hashable = result_event 219 self.signal.connect(self.show_modal, Qt.ConnectionType.QueuedConnection) 220 221 def show_modal(self): 222 result = callable_with_modal(*args, **kwargs) 223 try_send_async_event(self.cs, self.result_event, result) 224 225 event = (MODAL_RESULT_EVENT, MODAL_COUNTER()) 226 sm: ShowModal = ShowModal(current_coro_scheduler(), event) 227 sm.signal.emit() 228 i: Interface = current_interface() 229 return i(AsyncEventBusRequest().wait(event))
async def
amodal(callable_with_modal, *args, **kwargs):
232async def amodal(callable_with_modal, *args, **kwargs): 233 class ShowModal(QObject): 234 signal = Signal() 235 236 def __init__(self, cs: CoroSchedulerType, result_event: Hashable): 237 super().__init__() 238 self.cs: CoroSchedulerType = cs 239 self.result_event: Hashable = result_event 240 self.signal.connect(self.show_modal, Qt.ConnectionType.QueuedConnection) 241 242 def show_modal(self): 243 result = callable_with_modal(*args, **kwargs) 244 try_send_async_event(self.cs, self.result_event, result) 245 246 event = (MODAL_RESULT_EVENT, MODAL_COUNTER()) 247 sm: ShowModal = ShowModal(current_coro_scheduler(), event) 248 sm.signal.emit() 249 i: Interface = current_interface() 250 return await i(AsyncEventBusRequest().wait(event))
class
CoroSlot:
254class CoroSlot: 255 def __init__(self, *types: type, name: Optional[str] = None, result: Optional[str] = None) -> None: 256 self._types = types 257 self._name = name 258 self._result = result 259 self._coro = None 260 261 def __call__(self, coro: Coro, method = None) -> Any: 262 method = method or self.implicit_coro_impl 263 return method(coro) 264 265 def implicit_coro_impl(self, coro: Coro) -> Any: 266 self._coro = coro 267 268 def func_wrapper(*args, **kwargs): 269 cs: CoroSchedulerType = current_coro_scheduler() 270 service: PutCoro = cs.get_service_instance(PutCoro) 271 return service._add_direct_request(cs_coro(coro), *args, **kwargs) 272 273 coro_worker_sign: Signature = signature(coro) 274 update_wrapper(func_wrapper, coro) 275 func_wrapper.__signature__ = coro_worker_sign.replace(parameters=tuple(coro_worker_sign.parameters.values()), return_annotation=coro_worker_sign.return_annotation) 276 return Slot(*self._types, self._name, self._result)(func_wrapper) 277 278 def implicit_coro(self): 279 return partial(self, method=self.implicit_coro_impl) 280 281 ic = implicit_coro 282 283 def gly_patched_function_impl(self, func: Callable) -> Any: 284 return self.__call__(gly_patched(func)) 285 286 def gly_patched_function(self) -> Any: 287 return partial(self, method=self.gly_patched_function_impl) 288 289 glypf = gly_patched_function 290 gpf = gly_patched_function 291 gp = gly_patched_function 292 293 def agly_patched_function_impl(self, afunc: Callable) -> Any: 294 return self.__call__(agly_patched(afunc)) 295 296 def agly_patched_function(self) -> Any: 297 return partial(self, method=self.agly_patched_function_impl) 298 299 aglypf = agly_patched_function 300 agpf = agly_patched_function 301 agp = agly_patched_function 302 303 def explicit_coro_impl(self, coro: Coro) -> Any: 304 self._coro = coro 305 306 def func_wrapper(*args, **kwargs): 307 cs: CoroSchedulerType = current_coro_scheduler() 308 service: PutCoro = cs.get_service_instance(PutCoro) 309 return service._add_direct_request(coro, *args, **kwargs) 310 311 coro_worker_sign: Signature = signature(coro) 312 update_wrapper(func_wrapper, coro) 313 func_wrapper.__signature__ = coro_worker_sign.replace(parameters=tuple(coro_worker_sign.parameters.values())[1:], return_annotation=coro_worker_sign.return_annotation) 314 return Slot(*self._types, self._name, self._result)(func_wrapper) 315 316 def explicit_coro(self) -> Any: 317 return partial(self, method=self.explicit_coro_impl) 318 319 ec = explicit_coro 320 interface = explicit_coro 321 i = interface
def
implicit_coro_impl( self, coro: Union[greenlet.greenlet, Awaitable, Coroutine, Generator, AsyncGenerator, Callable]) -> Any:
265 def implicit_coro_impl(self, coro: Coro) -> Any: 266 self._coro = coro 267 268 def func_wrapper(*args, **kwargs): 269 cs: CoroSchedulerType = current_coro_scheduler() 270 service: PutCoro = cs.get_service_instance(PutCoro) 271 return service._add_direct_request(cs_coro(coro), *args, **kwargs) 272 273 coro_worker_sign: Signature = signature(coro) 274 update_wrapper(func_wrapper, coro) 275 func_wrapper.__signature__ = coro_worker_sign.replace(parameters=tuple(coro_worker_sign.parameters.values()), return_annotation=coro_worker_sign.return_annotation) 276 return Slot(*self._types, self._name, self._result)(func_wrapper)
def
explicit_coro_impl( self, coro: Union[greenlet.greenlet, Awaitable, Coroutine, Generator, AsyncGenerator, Callable]) -> Any:
303 def explicit_coro_impl(self, coro: Coro) -> Any: 304 self._coro = coro 305 306 def func_wrapper(*args, **kwargs): 307 cs: CoroSchedulerType = current_coro_scheduler() 308 service: PutCoro = cs.get_service_instance(PutCoro) 309 return service._add_direct_request(coro, *args, **kwargs) 310 311 coro_worker_sign: Signature = signature(coro) 312 update_wrapper(func_wrapper, coro) 313 func_wrapper.__signature__ = coro_worker_sign.replace(parameters=tuple(coro_worker_sign.parameters.values())[1:], return_annotation=coro_worker_sign.return_annotation) 314 return Slot(*self._types, self._name, self._result)(func_wrapper)
CSlot =
<class 'CoroSlot'>
def
coro_slot_implicit( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslot_implicit( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
csloti( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
csi( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
coro_slot_gly_patched( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslot_gly_patched( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslotglyp( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslotgp( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
csgp( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
coro_slot_agly_patched( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslot_agly_patched( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslotaglyp( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslotagp( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
csagp( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
coro_slot_explicit( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslot_explicit( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
cslotex( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
csex( *types: type, name: Union[str, NoneType] = None, result: Union[str, NoneType] = None):
def
qt_exec_in_coro( func: Callable, default_priority: cengal.parallel_execution.coroutines.coro_standard_services.loop_yield.versions.v_0.loop_yield.CoroPriority = <CoroPriority.normal: 1>) -> Callable:
373def qt_exec_in_coro(func: Callable, default_priority: CoroPriority = CoroPriority.normal) -> Callable: 374 @wraps(func) 375 def wrapper(*args, **kwargs): 376 cs: CoroSchedulerType = current_coro_scheduler() 377 cs.high_cpu_utilisation_mode = False 378 cs.use_internal_sleep = False 379 i: Interface = current_interface() 380 i(AsyncioLoopRequest().use_higher_level_sleep_manager()) 381 i(AsyncioLoopRequest().ensure_loop(interrupt_when_no_requests=True)) 382 i(AsyncioLoopRequest().turn_on_loops_intercommunication()) 383 384 app_or_tuple = func(*args, **kwargs) 385 on_exit = lambda ret: ret 386 if isinstance(app_or_tuple, QApplication): 387 app = app_or_tuple 388 elif isinstance(app_or_tuple, tuple): 389 app, on_exit = app_or_tuple 390 else: 391 raise RuntimeError("qt_exec_in_coro must return either QApplication or (QApplication, on_exit) tuple") 392 393 # Run the event loop 394 ret = i(RunCoro, cs_coro(execa), app, default_priority) 395 ret = i(RunCoro, cs_coro(on_exit), ret) 396 i(ShutdownLoop) 397 return ret 398 399 return cs_coro(wrapper)
async def
aqt_exec_in_coro( func: Callable, default_priority: cengal.parallel_execution.coroutines.coro_standard_services.loop_yield.versions.v_0.loop_yield.CoroPriority = <CoroPriority.normal: 1>) -> Callable:
402async def aqt_exec_in_coro(func: Callable, default_priority: CoroPriority = CoroPriority.normal) -> Callable: 403 @wraps(func) 404 async def wrapper(*args, **kwargs): 405 i: Interface = current_interface() 406 await i(AsyncioLoopRequest().ensure_loop(interrupt_when_no_requests=True)) 407 await i(AsyncioLoopRequest().turn_on_loops_intercommunication()) 408 409 app_or_tuple = func(*args, **kwargs) 410 on_exit = lambda ret: ret 411 if isinstance(app_or_tuple, QApplication): 412 app = app_or_tuple 413 else: 414 app, on_exit = app_or_tuple 415 416 ret = await i(RunCoro, cs_coro(execa), app, default_priority) 417 ret = await i(RunCoro, cs_coro(on_exit), ret) 418 await i(ShutdownLoop) 419 return ret 420 421 return cs_acoro(wrapper)
class
CoroThreadWorker(PySide6.QtCore.QObject):
424class CoroThreadWorker(QObject): 425 def __init__(self, worker: AnyWorker) -> None: 426 super().__init__() 427 self._worker: AnyWorker = worker 428 self._cs: CoroSchedulerType = None 429 self.allowed_to_run = False 430 431 def run(self): 432 self.allowed_to_run = True 433 async def my_worker_wrapper(i: Interface, worker): 434 self._cs = current_coro_scheduler() 435 await i(RunCoro, self.setup) 436 await i(RunCoro, worker) 437 438 run_in_loop(my_worker_wrapper, self._worker) 439 440 async def setup(self, i: Interface): 441 await i(AsyncioLoopRequest().ensure_loop(interrupt_when_no_requests=True)) 442 await i(AsyncioLoopRequest().turn_on_loops_intercommunication()) 443 444 def stop(self): 445 if not self.allowed_to_run: 446 return 447 448 self.allowed_to_run = False 449 async def coro(i: Interface): 450 await i(ShutdownLoop) 451 452 if self._cs is not None: 453 service: PutCoro = self._cs.get_service_instance(PutCoro) 454 return service._add_direct_request(coro)
QObject(self, parent: Union[PySide6.QtCore.QObject, NoneType] = None) -> None
CoroThreadWorker( worker: Union[cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.ExplicitWorker, collections.abc.Callable[cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.Interface, Any], collections.abc.Callable[cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.Interface, Awaitable[Any]]])
425 def __init__(self, worker: AnyWorker) -> None: 426 super().__init__() 427 self._worker: AnyWorker = worker 428 self._cs: CoroSchedulerType = None 429 self.allowed_to_run = False
__init__(self, parent: Union[PySide6.QtCore.QObject, NoneType] = None) -> None
Initialize self. See help(type(self)) for accurate signature.
async def
setup( self, i: cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.Interface):
Inherited Members
- PySide6.QtCore.QObject
- blockSignals
- childEvent
- children
- connect
- connectNotify
- customEvent
- deleteLater
- disconnect
- disconnectNotify
- dumpObjectInfo
- dumpObjectTree
- dynamicPropertyNames
- emit
- event
- eventFilter
- findChild
- findChildren
- inherits
- installEventFilter
- isQuickItemType
- isSignalConnected
- isWidgetType
- isWindowType
- killTimer
- metaObject
- moveToThread
- objectName
- parent
- property
- receivers
- removeEventFilter
- sender
- senderSignalIndex
- setObjectName
- setParent
- setProperty
- signalsBlocked
- startTimer
- thread
- timerEvent
- tr
- destroyed
- objectNameChanged
469class CoroThreadWithWorker(CoroThreadWorker): 470 def __init__(self, parent, worker: AnyWorker) -> None: 471 super().__init__(worker) 472 self._thread: CoroThread = CoroThread(parent, self) 473 474 def start(self): 475 self._thread.start() 476 477 def stop(self): 478 super().stop() 479 self._thread.stop()
QObject(self, parent: Union[PySide6.QtCore.QObject, NoneType] = None) -> None
CoroThreadWithWorker( parent, worker: Union[cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.ExplicitWorker, collections.abc.Callable[cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.Interface, Any], collections.abc.Callable[cengal.parallel_execution.coroutines.coro_scheduler.versions.v_0.coro_scheduler.Interface, Awaitable[Any]]])
470 def __init__(self, parent, worker: AnyWorker) -> None: 471 super().__init__(worker) 472 self._thread: CoroThread = CoroThread(parent, self)
__init__(self, parent: Union[PySide6.QtCore.QObject, NoneType] = None) -> None
Initialize self. See help(type(self)) for accurate signature.
Inherited Members
- PySide6.QtCore.QObject
- blockSignals
- childEvent
- children
- connect
- connectNotify
- customEvent
- deleteLater
- disconnect
- disconnectNotify
- dumpObjectInfo
- dumpObjectTree
- dynamicPropertyNames
- emit
- event
- eventFilter
- findChild
- findChildren
- inherits
- installEventFilter
- isQuickItemType
- isSignalConnected
- isWidgetType
- isWindowType
- killTimer
- metaObject
- moveToThread
- objectName
- parent
- property
- receivers
- removeEventFilter
- sender
- senderSignalIndex
- setObjectName
- setParent
- setProperty
- signalsBlocked
- startTimer
- thread
- timerEvent
- tr
- destroyed
- objectNameChanged