8
8
from functools import partial
9
9
from dataclasses import dataclass
10
10
from contextlib import AbstractAsyncContextManager
11
- from threading import Thread
12
- from concurrent .futures import ThreadPoolExecutor
13
11
14
12
from asyncgui import Cancelled , Task , move_on_when , _sleep_forever , _current_task
15
13
@@ -393,28 +391,9 @@ async def run_in_thread(self, func, *, daemon=None, polling_interval) -> Awaitab
393
391
394
392
return_value = await clock.run_in_thread(func, polling_interval=...)
395
393
'''
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." )
408
395
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 :
418
397
'''
419
398
Runs a function within a :class:`concurrent.futures.ThreadPoolExecutor`, and waits for the completion of the
420
399
function.
@@ -424,30 +403,7 @@ async def run_in_executor(self, executer: ThreadPoolExecutor, func, *, polling_i
424
403
executor = ThreadPoolExecutor()
425
404
return_value = await clock.run_in_executor(executor, func, polling_interval=...)
426
405
'''
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." )
451
407
452
408
def _update (setattr , zip , min , obj , duration , transition , output_seq_type , anim_params , task , p_time , dt ):
453
409
time = p_time [0 ] + dt
@@ -553,3 +509,69 @@ def __aenter__(self, _current_task=_current_task) -> Awaitable[Callable[[], Awai
553
509
554
510
async def __aexit__ (self , exc_type , exc_val , exc_tb ):
555
511
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