Closed
Description
While it is threadsafe, the with
statement gives the false impression that it's always safe. It is not:
import asyncio
import numpy as np
def divide_by_zero():
np.float64(1) / 0
async def foo():
for j in range(3):
with np.errstate(divide='raise'):
for i in range(2):
try:
divide_by_zero()
except FloatingPointError:
pass
else:
print("foo: Failed to raise!")
await asyncio.sleep(0.15)
async def bar():
for j in range(3):
with np.errstate(divide='ignore'):
for i in range(2):
try:
divide_by_zero()
except FloatingPointError:
print("bar: raised anyway!")
await asyncio.sleep(0.11)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(foo(), bar()))
loop.close()
gives:
foo: Failed to raise!
bar: raised anyway!
foo: Failed to raise!
because the error-state is thread-local, but asyncio tasks share a thread.
I don't know if there is any way this can be fixed - it seems like this might be a python bug, and context managers might need an __yield_enter__
and __yield_leave__
mechanism, to be notified when control is leaving the suite via a yield
/await