Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/1573.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a helpful error message if an async function is passed to `trio.to_thread.run_sync`.
12 changes: 11 additions & 1 deletion trio/_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,17 @@ def do_release_then_return_result():
def worker_fn():
TOKEN_LOCAL.token = current_trio_token
try:
return sync_fn(*args)
ret = sync_fn(*args)

if inspect.iscoroutine(ret):
# Manually close coroutine to avoid RuntimeWarnings
ret.close()
raise TypeError(
"Trio expected a sync function, but {!r} appears to be "
"asynchronous".format(getattr(sync_fn, "__qualname__", sync_fn))
)

return ret
finally:
del TOKEN_LOCAL.token

Expand Down
9 changes: 9 additions & 0 deletions trio/tests/test_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,15 @@ def thread_fn():
assert callee_token == caller_token


async def test_trio_to_thread_run_sync_expected_error():
# Test correct error when passed async function
async def async_fn(): # pragma: no cover
pass

with pytest.raises(TypeError, match="expected a sync function"):
await to_thread_run_sync(async_fn)


async def test_trio_from_thread_run_sync():
# Test that to_thread_run_sync correctly "hands off" the trio token to
# trio.from_thread.run_sync()
Expand Down