Apr-26-2024, 07:38 AM
(This post was last modified: Apr-26-2024, 08:49 AM by Larz60+.
Edit Reason: fixed error tag
)
This is from Dave Beazly's Generators: The Final Frontier here. Part 3, the example inline_recursive.py
When I run inline_recursive.py in Idle, by copying and pasting the parts into Idle, it works and prints lots of:
When I run inline_recursive.py in Idle, by copying and pasting the parts into Idle, it works and prints lots of:
print('Tick:', n)But I get this error when I run inline_recursive.py in bash, right after the first tick is printed:pedro@pedro-HP:~/myPython/yield/tutorial2014$ ./inline_recursive.py Tick: 0
Error:exception calling callback for <Future at 0x75e01f9e0be0 state=finished returned NoneType>
Traceback (most recent call last):
File "/usr/lib/python3.10/concurrent/futures/_base.py", line 342, in _invoke_callbacks
callback(self)
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 26, in _wakeup
self.step(None, exc)
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 14, in step
fut = self._gen.throw(exc)
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 24, in _wakeup
self.step(result, None)
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 16, in step
fut = self._gen.send(value)
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 44, in recursive
Task(recursive(n+1)).step()
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 16, in step
fut = self._gen.send(value)
File "/home/pedro/myPython/yield/tutorial2014/./inline_recursive.py", line 42, in recursive
yield pool.submit(time.sleep, 0.001)
File "/usr/lib/python3.10/concurrent/futures/thread.py", line 169, in submit
raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdownLike I said, it works in the Idle shell.#! /usr/bin/python3
# inline_recursive.py
#
# Bizarre inline recursive example
class Task:
def __init__(self, gen):
self._gen = gen
def step(self, value=None, exc=None):
try:
if exc:
fut = self._gen.throw(exc)
else:
fut = self._gen.send(value)
fut.add_done_callback(self._wakeup)
except StopIteration as exc:
pass
def _wakeup(self, fut):
try:
result = fut.result()
self.step(result, None)
except Exception as exc:
self.step(None, exc)
# Example
if __name__ == '__main__':
from concurrent.futures import ThreadPoolExecutor
import time
pool = ThreadPoolExecutor(max_workers=8)
""" Error
File "/usr/lib/python3.10/concurrent/futures/thread.py", line 169, in submit
raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown
"""
def recursive(n):
# this submit causes a problem
yield pool.submit(time.sleep, 0.001)
print('Tick:', n)
Task(recursive(n+1)).step()
Task(recursive(0)).step()I found, on the other hand, examples that work with .ProcessPoolExecutor(), like below, will not work in Idle, but work in bash!#! /usr/bin/python3
import concurrent.futures
def worker(task):
result = task * 2
print(f"Task {task}: Result = {result}\n")
return result
if __name__ == "__main__":
tasks = [1, 2, 3, 4, 5]
# will not work in the shell
with concurrent.futures.ProcessPoolExecutor() as executor:
results = executor.map(worker, tasks)
print("Results:", list(results))Any tips please?
