Show More
@@ -42,49 +42,9 b' def _curio_runner(coroutine):' | |||||
42 | return curio.run(coroutine) |
|
42 | return curio.run(coroutine) | |
43 |
|
43 | |||
44 |
|
44 | |||
45 | _TRIO_TOKEN = None |
|
|||
46 |
|
||||
47 |
|
||||
48 | def _init_trio(trio): |
|
|||
49 | global _TRIO_TOKEN |
|
|||
50 | import traceback |
|
|||
51 | import builtins |
|
|||
52 | import threading |
|
|||
53 | # We use an Event to avoid a race condition between starting the Trio thread |
|
|||
54 | # and running Trio code. |
|
|||
55 | thread_start = threading.Event() |
|
|||
56 |
|
||||
57 | def log_nursery_exc(exc): |
|
|||
58 | import logging |
|
|||
59 | import traceback |
|
|||
60 | exc = '\n'.join(traceback.format_exception(type(exc), exc, |
|
|||
61 | exc.__traceback__)) |
|
|||
62 | logging.error('An exception occurred in a global nursery task.\n%s', |
|
|||
63 | exc) |
|
|||
64 |
|
||||
65 | async def trio_entry(): |
|
|||
66 | global _TRIO_TOKEN, _TRIO_NURSERY |
|
|||
67 | _TRIO_TOKEN = trio.hazmat.current_trio_token() |
|
|||
68 | async with trio.open_nursery() as nursery: |
|
|||
69 | # TODO This hack prevents the nursery from cancelling all child |
|
|||
70 | # tasks when but it's ugly. |
|
|||
71 | nursery._add_exc = log_nursery_exc |
|
|||
72 | builtins.GLOBAL_NURSERY = nursery |
|
|||
73 | thread_start.set() |
|
|||
74 | await trio.sleep_forever() |
|
|||
75 |
|
||||
76 | threading.Thread(target=trio.run, args=(trio_entry,)).start() |
|
|||
77 | thread_start.wait() |
|
|||
78 |
|
||||
79 |
|
||||
80 | def _trio_runner(async_fn): |
|
45 | def _trio_runner(async_fn): | |
81 | global _TRIO_TOKEN |
|
|||
82 | import logging |
|
|||
83 | import trio |
|
46 | import trio | |
84 |
|
47 | |||
85 | if not _TRIO_TOKEN: |
|
|||
86 | _init_trio(trio) |
|
|||
87 |
|
||||
88 | async def loc(coro): |
|
48 | async def loc(coro): | |
89 | """ |
|
49 | """ | |
90 | We need the dummy no-op async def to protect from |
|
50 | We need the dummy no-op async def to protect from | |
@@ -92,7 +52,7 b' def _trio_runner(async_fn):' | |||||
92 | """ |
|
52 | """ | |
93 | return await coro |
|
53 | return await coro | |
94 |
|
54 | |||
95 |
return trio |
|
55 | return trio.run(loc, async_fn) | |
96 |
|
56 | |||
97 |
|
57 | |||
98 | def _pseudo_sync_runner(coro): |
|
58 | def _pseudo_sync_runner(coro): |
@@ -695,6 +695,13 b' class InteractiveShell(SingletonConfigurable):' | |||||
695 | self.events.trigger('shell_initialized', self) |
|
695 | self.events.trigger('shell_initialized', self) | |
696 | atexit.register(self.atexit_operations) |
|
696 | atexit.register(self.atexit_operations) | |
697 |
|
697 | |||
|
698 | # The trio runner is used for running Trio in the foreground thread. It | |||
|
699 | # is different from `_trio_runner(async_fn)` in `async_helpers.py` | |||
|
700 | # which calls `trio.run()` for every cell. This runner runs all cells | |||
|
701 | # inside a single Trio event loop. If used, it is set from | |||
|
702 | # `ipykernel.kernelapp`. | |||
|
703 | self.trio_runner = None | |||
|
704 | ||||
698 | def get_ipython(self): |
|
705 | def get_ipython(self): | |
699 | """Return the currently running IPython instance.""" |
|
706 | """Return the currently running IPython instance.""" | |
700 | return self |
|
707 | return self | |
@@ -715,6 +722,9 b' class InteractiveShell(SingletonConfigurable):' | |||||
715 | else: |
|
722 | else: | |
716 | self.autoindent = value |
|
723 | self.autoindent = value | |
717 |
|
724 | |||
|
725 | def set_trio_runner(self, tr): | |||
|
726 | self.trio_runner = tr | |||
|
727 | ||||
718 | #------------------------------------------------------------------------- |
|
728 | #------------------------------------------------------------------------- | |
719 | # init_* methods called by __init__ |
|
729 | # init_* methods called by __init__ | |
720 | #------------------------------------------------------------------------- |
|
730 | #------------------------------------------------------------------------- | |
@@ -2865,7 +2875,9 b' class InteractiveShell(SingletonConfigurable):' | |||||
2865 | # when this is the case, we want to run it using the pseudo_sync_runner |
|
2875 | # when this is the case, we want to run it using the pseudo_sync_runner | |
2866 | # so that code can invoke eventloops (for example via the %run , and |
|
2876 | # so that code can invoke eventloops (for example via the %run , and | |
2867 | # `%paste` magic. |
|
2877 | # `%paste` magic. | |
2868 | if self.should_run_async(raw_cell) or self.loop_runner is _trio_runner: |
|
2878 | if self.trio_runner: | |
|
2879 | runner = self.trio_runner | |||
|
2880 | elif self.should_run_async(raw_cell): | |||
2869 | runner = self.loop_runner |
|
2881 | runner = self.loop_runner | |
2870 | else: |
|
2882 | else: | |
2871 | runner = _pseudo_sync_runner |
|
2883 | runner = _pseudo_sync_runner |
General Comments 0
You need to be logged in to leave comments.
Login now