Skip to content

Commit cbb97f4

Browse files
committed
Tutorial: Make samples CPython-compatible (task references).
1 parent 11a3c70 commit cbb97f4

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

v3/docs/TUTORIAL.md

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,9 @@ async def bar(x):
255255
await asyncio.sleep(1) # Pause 1s
256256

257257
async def main():
258+
tasks = [None] * 3 # For CPython compaibility must store a reference see Note
258259
for x in range(3):
259-
asyncio.create_task(bar(x))
260+
tasks[x] = asyncio.create_task(bar(x))
260261
await asyncio.sleep(10)
261262

262263
asyncio.run(main())
@@ -342,21 +343,40 @@ async def bar(x):
342343
await asyncio.sleep(1) # Pause 1s
343344

344345
async def main():
346+
tasks = [None] * 3 # For CPython compaibility must store a reference see Note
345347
for x in range(3):
346-
asyncio.create_task(bar(x))
348+
tasks[x] = asyncio.create_task(bar(x))
347349
print('Tasks are running')
348350
await asyncio.sleep(10)
349351

350352
asyncio.run(main())
351353
```
352-
##### Note
354+
### Note on CPython compatibility
353355

354356
The CPython [docs](https://docs.python.org/3/library/asyncio-task.html#creating-tasks)
355357
have a warning that a reference to the task instance should be saved for the
356358
task's duration. This was raised in
357359
[this issue](https://github.com/micropython/micropython/issues/12299).
358360
MicroPython `asyncio` does not suffer from this bug, but writers of code which
359-
must work in CPython and MicroPython should take note.
361+
must work in CPython and MicroPython should take note. Code samples in this doc
362+
are CPython-compatible, but following version is valid in MicroPython:
363+
```python
364+
import asyncio
365+
async def bar(x):
366+
count = 0
367+
while True:
368+
count += 1
369+
print('Instance: {} count: {}'.format(x, count))
370+
await asyncio.sleep(1) # Pause 1s
371+
372+
async def main():
373+
for x in range(3):
374+
asyncio.create_task(bar(x)) # No reference stored
375+
print('Tasks are running')
376+
await asyncio.sleep(10)
377+
378+
asyncio.run(main())
379+
```
360380

361381
###### [Contents](./TUTORIAL.md#contents)
362382

@@ -491,7 +511,7 @@ def set_global_exception():
491511
async def main():
492512
set_global_exception() # Debug aid
493513
my_class = MyClass() # Constructor might create tasks
494-
asyncio.create_task(my_class.foo()) # Or you might do this
514+
task = asyncio.create_task(my_class.foo()) # Or you might do this
495515
await my_class.run_forever() # Non-terminating method
496516
try:
497517
asyncio.run(main())
@@ -613,8 +633,9 @@ async def task(i, lock):
613633

614634
async def main():
615635
lock = Lock() # The Lock instance
636+
tasks = [None] * 3 # For CPython compaibility must store a reference see Note
616637
for n in range(1, 4):
617-
asyncio.create_task(task(n, lock))
638+
tasks[n - 1] = asyncio.create_task(task(n, lock))
618639
await asyncio.sleep(10)
619640

620641
asyncio.run(main()) # Run for 10s
@@ -642,8 +663,9 @@ async def task(i, lock):
642663

643664
async def main():
644665
lock = Lock() # The Lock instance
666+
tasks = [None] * 3 # For CPython compaibility must store a reference see Note
645667
for n in range(1, 4):
646-
asyncio.create_task(task(n, lock))
668+
tasks[n - 1] = asyncio.create_task(task(n, lock))
647669
await asyncio.sleep(10)
648670

649671
asyncio.run(main()) # Run for 10s
@@ -671,7 +693,7 @@ async def waiter(event):
671693

672694
async def main():
673695
event = Event()
674-
asyncio.create_task(waiter(event))
696+
task = asyncio.create_task(waiter(event))
675697
await asyncio.sleep(2)
676698
print('Setting event')
677699
event.set()
@@ -821,7 +843,7 @@ async def main():
821843
tasks = [asyncio.create_task(bar(70))]
822844
tasks.append(barking(21))
823845
tasks.append(asyncio.wait_for(foo(10), 7))
824-
asyncio.create_task(do_cancel(tasks[0]))
846+
can = asyncio.create_task(do_cancel(tasks[0]))
825847
res = None
826848
try:
827849
res = await asyncio.gather(*tasks, return_exceptions=True)
@@ -939,8 +961,9 @@ async def foo(n, sema):
939961

940962
async def main():
941963
sema = Semaphore()
964+
tasks = [None] * 3 # For CPython compaibility must store a reference see Note
942965
for num in range(3):
943-
asyncio.create_task(foo(num, sema))
966+
tasks[num] = asyncio.create_task(foo(num, sema))
944967
await asyncio.sleep(2)
945968

946969
asyncio.run(main())
@@ -1022,8 +1045,8 @@ async def consume(queue):
10221045

10231046
async def queue_go(delay):
10241047
queue = Queue()
1025-
asyncio.create_task(consume(queue))
1026-
asyncio.create_task(produce(queue))
1048+
t1 = asyncio.create_task(consume(queue))
1049+
t2 = asyncio.create_task(produce(queue))
10271050
await asyncio.sleep(delay)
10281051
print("Done")
10291052

@@ -1188,8 +1211,9 @@ async def main():
11881211
sw1 = asyncio.StreamWriter(UART(1, 9600), {})
11891212
sw2 = asyncio.StreamWriter(UART(2, 1200), {})
11901213
barrier = Barrier(3)
1214+
tasks = [None] * 2 # For CPython compaibility must store a reference see Note
11911215
for n, sw in enumerate((sw1, sw2)):
1192-
asyncio.create_task(sender(barrier, sw, n + 1))
1216+
tasks[n] = asyncio.create_task(sender(barrier, sw, n + 1))
11931217
await provider(barrier)
11941218

11951219
asyncio.run(main())
@@ -1321,8 +1345,9 @@ async def foo(n, d):
13211345

13221346
async def my_app():
13231347
d = Delay_ms()
1348+
tasks = [None] * 4 # For CPython compaibility must store a reference see Note
13241349
for n in range(4):
1325-
asyncio.create_task(foo(n, d))
1350+
tasks[n] = asyncio.create_task(foo(n, d))
13261351
d.trigger(3000)
13271352
print('Waiting on d')
13281353
await d.wait()
@@ -1632,7 +1657,7 @@ async def foo():
16321657
print('Does not print') # Because bar() raised an exception
16331658

16341659
async def main():
1635-
asyncio.create_task(foo())
1660+
task = asyncio.create_task(foo())
16361661
for _ in range(5):
16371662
print('Working') # Carries on after the exception
16381663
await asyncio.sleep(0.5)
@@ -1675,7 +1700,7 @@ async def bar():
16751700
async def main():
16761701
loop = asyncio.get_event_loop()
16771702
loop.set_exception_handler(_handle_exception)
1678-
asyncio.create_task(bar())
1703+
task = asyncio.create_task(bar())
16791704
for _ in range(5):
16801705
print('Working')
16811706
await asyncio.sleep(0.5)
@@ -2270,7 +2295,7 @@ class PinCall(io.IOBase):
22702295
self.cbf_args = cbf_args
22712296
self.pinval = pin.value()
22722297
self.sreader = asyncio.StreamReader(self)
2273-
asyncio.create_task(self.run())
2298+
self.task = asyncio.create_task(self.run())
22742299

22752300
async def run(self):
22762301
while True:
@@ -2680,7 +2705,7 @@ class LED_async():
26802705
def __init__(self, led_no):
26812706
self.led = pyb.LED(led_no)
26822707
self.rate = 0
2683-
asyncio.create_task(self.run())
2708+
self.task = asyncio.create_task(self.run())
26842709

26852710
async def run(self):
26862711
while True:

0 commit comments

Comments
 (0)