Skip to content

Commit ac9e6b4

Browse files
A5rocksoremanj
andcommitted
Address PR review
Co-authored-by: Joshua Oreman <[email protected]>
1 parent 5a40ef6 commit ac9e6b4

File tree

3 files changed

+52
-30
lines changed

3 files changed

+52
-30
lines changed

docs/source/reference-lowlevel.rst

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,48 @@ Global statistics
5858

5959
.. _trio_contexts:
6060

61-
The current Trio context
62-
------------------------
63-
64-
There are two different types of contexts in :mod:`trio`. Here are the
65-
semantics presented as a handy table. Choose the right function for
66-
your needs.
67-
68-
+---------------------------------+-----------------------------------+------------------------------------+
69-
| situation | :func:`trio.lowlevel.in_trio_run` | :func:`trio.lowlevel.in_trio_task` |
70-
+=================================+===================================+====================================+
71-
| inside a running async function | `True` | `True` |
72-
+---------------------------------+-----------------------------------+------------------------------------+
73-
| without a running Trio loop | `False` | `False` |
74-
+---------------------------------+-----------------------------------+------------------------------------+
75-
| in a guest run's host loop | `True` | `False` |
76-
+---------------------------------+-----------------------------------+------------------------------------+
77-
| inside an instrument call | depends | depends |
78-
+---------------------------------+-----------------------------------+------------------------------------+
79-
| :func:`trio.to_thread.run_sync` | `False` | `False` |
80-
+---------------------------------+-----------------------------------+------------------------------------+
81-
| inside an abort function | `True` | `True` |
82-
+---------------------------------+-----------------------------------+------------------------------------+
61+
Checking for Trio
62+
-----------------
63+
64+
If you want to interact with an active Trio run -- perhaps you need to
65+
know the :func:`~trio.current_time` or the
66+
:func:`~trio.lowlevel.current_task` -- then Trio needs to have certain
67+
state available to it or else you will get a
68+
``RuntimeError("must be called from async context")``.
69+
This requires that you either be:
70+
71+
* indirectly inside (and on the same thread as) a call to
72+
:func:`trio.run`, for run-level information such as the
73+
:func:`~trio.current_time` or :func:`~trio.lowlevel.current_clock`.
74+
75+
* indirectly inside a Trio task, for task-level information such as
76+
the :func:`~trio.lowlevel.current_task` or
77+
:func:`~trio.current_effective_deadline`.
78+
79+
Internally, this state is provided by thread-local variables tracking
80+
the current run and the current task. Sometimes, it's useful to know
81+
in advance whether a call will fail or to have dynamic information for
82+
safeguards against running something inside or outside Trio. To do so,
83+
call :func:`trio.lowlevel.in_trio_run` or
84+
:func:`trio.lowlevel.in_trio_task`, which will provide answers
85+
according to the following table.
86+
87+
88+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
89+
| situation | :func:`trio.lowlevel.in_trio_run` | :func:`trio.lowlevel.in_trio_task` |
90+
+========================================================+===================================+====================================+
91+
| inside a Trio-flavored async function | `True` | `True` |
92+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
93+
| in a thread without an active call to :func:`trio.run` | `False` | `False` |
94+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
95+
| in a guest run's host loop | `True` | `False` |
96+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
97+
| inside an instrument call | depends | depends |
98+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
99+
| in a thread created by :func:`trio.to_thread.run_sync` | `False` | `False` |
100+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
101+
| inside an abort function | `True` | `True` |
102+
+--------------------------------------------------------+-----------------------------------+------------------------------------+
83103

84104
.. autofunction:: in_trio_run
85105

src/trio/_core/_run.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,8 +2832,9 @@ def unrolled_run(
28322832
except BaseException as exc:
28332833
raise TrioInternalError("internal error in Trio - please file a bug!") from exc
28342834
finally:
2835-
GLOBAL_RUN_CONTEXT.__dict__.clear()
28362835
runner.close()
2836+
GLOBAL_RUN_CONTEXT.__dict__.clear()
2837+
28372838
# Have to do this after runner.close() has disabled KI protection,
28382839
# because otherwise there's a race where ki_pending could get set
28392840
# after we check it.
@@ -2954,16 +2955,18 @@ async def checkpoint_if_cancelled() -> None:
29542955

29552956
def in_trio_run() -> bool:
29562957
"""Check whether we are in a Trio run.
2958+
This returns `True` if and only if :func:`~trio.current_time` will succeed.
29572959
2958-
See also :ref:`the different types of contexts <trio_contexts>`.
2960+
See also the discussion of differing ways of :ref:`detecting Trio <trio_contexts>`.
29592961
"""
29602962
return hasattr(GLOBAL_RUN_CONTEXT, "runner")
29612963

29622964

29632965
def in_trio_task() -> bool:
29642966
"""Check whether we are in a Trio task.
2967+
This returns `True` if and only if :func:`~trio.lowlevel.current_task` will succeed.
29652968
2966-
See also :ref:`the different types of contexts <trio_contexts>`.
2969+
See also the discussion of differing ways of :ref:`detecting Trio <trio_contexts>`.
29672970
"""
29682971
return hasattr(GLOBAL_RUN_CONTEXT, "task")
29692972

src/trio/_core/_tests/test_instrumentation.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,16 @@ class Instrument(_abc.Instrument):
275275
pass
276276

277277
hooks = {
278-
# category 1
278+
# not run in task context
279279
"after_io_wait": (True, False),
280280
"before_io_wait": (True, False),
281281
"before_run": (True, False),
282-
# category 2
283-
"after_run": (False, False),
284-
# category 3
282+
"after_run": (True, False),
283+
# run in task context
285284
"before_task_step": (True, True),
286285
"after_task_step": (True, True),
287286
"task_exited": (True, True),
288-
# category 4
287+
# depends
289288
"task_scheduled": (True, None),
290289
"task_spawned": (True, None),
291290
}

0 commit comments

Comments
 (0)