Skip to content

Instantly share code, notes, and snippets.

@sirkonst
Last active August 11, 2016 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sirkonst/d3dd92ee97083fc9d7e20785606d5dcc to your computer and use it in GitHub Desktop.
Save sirkonst/d3dd92ee97083fc9d7e20785606d5dcc to your computer and use it in GitHub Desktop.
Сlosure with asyncio corrutines isn't async-safe
import asyncio
from functools import partial
async def process(d):
print('process', d)
async def amain(loop):
data = range(2)
fs = []
for d in data:
f = loop.create_task(process(d))
fs.append(f)
# - This callback is closured wrong value for d
def _cb_broken(future):
print('_cb_broken', d)
f.add_done_callback(_cb_broken)
# - Fix 1
def _cb_broken_fix_1(future, d=d):
print('_cb_broken_fix_1', d)
f.add_done_callback(_cb_broken_fix_1)
# - Fix 2
def _cb_broken_fix_2(future, d):
print('_cb_broken_fix_2', d)
f.add_done_callback(
partial(_cb_broken_fix_2, d=d)
)
await asyncio.wait(fs)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(amain(loop))
#
# Run output:
#
# process 0
# process 1
# _cb_broken 1
# _cb_broken_fix_1 0
# _cb_broken_fix_2 0
# _cb_broken 1
# _cb_broken_fix_1 1
# _cb_broken_fix_2 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment