Skip to content

Commit 4cc231f

Browse files
スレッド系のモジュールの無い環境でも使えるようにする
1 parent 6f35c36 commit 4cc231f

File tree

1 file changed

+69
-47
lines changed

1 file changed

+69
-47
lines changed

src/asyncgui_ext/clock.py

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
from functools import partial
99
from dataclasses import dataclass
1010
from contextlib import AbstractAsyncContextManager
11-
from threading import Thread
12-
from concurrent.futures import ThreadPoolExecutor
1311

1412
from 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

Comments
 (0)