88from functools import partial
99from dataclasses import dataclass
1010from contextlib import AbstractAsyncContextManager
11- from threading import Thread
12- from concurrent .futures import ThreadPoolExecutor
1311
1412from asyncgui import Cancelled , Task , move_on_when , _sleep_forever , _current_task
1513
@@ -393,28 +391,9 @@ async def run_in_thread(self, func, *, daemon=None, polling_interval) -> Awaitab
393391
394392 return_value = await clock.run_in_thread(func, polling_interval=...)
395393 '''
396- return_value = None
397- exception = None
398- done = False
399-
400- def wrapper ():
401- nonlocal return_value , done , exception
402- try :
403- return_value = func ()
404- except Exception as e :
405- exception = e
406- finally :
407- done = True
394+ raise NotImplementedError (r"'Clock.run_in_thread()' is not available because 'threading.Thread' is unavailable." )
408395
409- Thread (target = wrapper , daemon = daemon , name = "asyncgui_ext.clock.Clock.run_in_thread" ).start ()
410- async with _repeat_sleeping (self , polling_interval ) as sleep :
411- while not done :
412- await sleep ()
413- if exception is not None :
414- raise exception
415- return return_value
416-
417- async def run_in_executor (self , executer : ThreadPoolExecutor , func , * , polling_interval ) -> Awaitable :
396+ async def run_in_executor (self , executer , func , * , polling_interval ) -> Awaitable :
418397 '''
419398 Runs a function within a :class:`concurrent.futures.ThreadPoolExecutor`, and waits for the completion of the
420399 function.
@@ -424,30 +403,7 @@ async def run_in_executor(self, executer: ThreadPoolExecutor, func, *, polling_i
424403 executor = ThreadPoolExecutor()
425404 return_value = await clock.run_in_executor(executor, func, polling_interval=...)
426405 '''
427- return_value = None
428- exception = None
429- done = False
430-
431- def wrapper ():
432- nonlocal return_value , done , exception
433- try :
434- return_value = func ()
435- except Exception as e :
436- exception = e
437- finally :
438- done = True
439-
440- future = executer .submit (wrapper )
441- try :
442- async with _repeat_sleeping (self , polling_interval ) as sleep :
443- while not done :
444- await sleep ()
445- except Cancelled :
446- future .cancel ()
447- raise
448- if exception is not None :
449- raise exception
450- return return_value
406+ raise NotImplementedError (r"'Clock.run_executor()' is not available because 'concurrent.futures.ThreadPoolExecutor' is unavailable." )
451407
452408 def _update (setattr , zip , min , obj , duration , transition , output_seq_type , anim_params , task , p_time , dt ):
453409 time = p_time [0 ] + dt
@@ -553,3 +509,69 @@ def __aenter__(self, _current_task=_current_task) -> Awaitable[Callable[[], Awai
553509
554510 async def __aexit__ (self , exc_type , exc_val , exc_tb ):
555511 self ._event .cancel ()
512+
513+
514+ try :
515+ from threading import Thread
516+ except ImportError :
517+ pass
518+ else :
519+ async def run_in_thread (clock : Clock , func , * , daemon = None , polling_interval ) -> Awaitable :
520+ return_value = None
521+ exception = None
522+ done = False
523+
524+ def wrapper ():
525+ nonlocal return_value , done , exception
526+ try :
527+ return_value = func ()
528+ except Exception as e :
529+ exception = e
530+ finally :
531+ done = True
532+
533+ Thread (target = wrapper , daemon = daemon , name = "asyncgui_ext.clock.Clock.run_in_thread" ).start ()
534+ async with _repeat_sleeping (clock , polling_interval ) as sleep :
535+ while not done :
536+ await sleep ()
537+ if exception is not None :
538+ raise exception
539+ return return_value
540+
541+ run_in_thread .__doc__ = Clock .run_in_thread .__doc__
542+ Clock .run_in_thread = run_in_thread
543+
544+
545+ try :
546+ from concurrent .futures import ThreadPoolExecutor
547+ except ImportError :
548+ pass
549+ else :
550+ async def run_in_executor (clock : Clock , executer : ThreadPoolExecutor , func , * , polling_interval ) -> Awaitable :
551+ return_value = None
552+ exception = None
553+ done = False
554+
555+ def wrapper ():
556+ nonlocal return_value , done , exception
557+ try :
558+ return_value = func ()
559+ except Exception as e :
560+ exception = e
561+ finally :
562+ done = True
563+
564+ future = executer .submit (wrapper )
565+ try :
566+ async with _repeat_sleeping (clock , polling_interval ) as sleep :
567+ while not done :
568+ await sleep ()
569+ except Cancelled :
570+ future .cancel ()
571+ raise
572+ if exception is not None :
573+ raise exception
574+ return return_value
575+
576+ run_in_executor .__doc__ = Clock .run_in_executor .__doc__
577+ Clock .run_in_executor = run_in_executor
0 commit comments