I have noticed that the result()
function of a ThreadPoolExecutor
is not behaving as i expect. It returns an exception that is not raised without the threads.
Here is a reproducible, minimal example:
import concurrent.futures
import time
class cat:
def __init__(self, name=""):
self.name = name
def sayname(self):
return("Miaw, " + self.name)
def main():
names = ["Sprinkles", "Button", "Fluffy", "Semla"]
cats = [cat(name = i) for i in names]
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
cats_results = [executor.submit(i.sayname()) for i in cats]
print([i.result for i in cats_results])
main()
Returns (notice the TypeError):
[<bound method Future.result of <Future at 0x7f227e3259d0 state=finished raised TypeError>>,
<bound method Future.result of <Future at 0x7f227e325c50 state=finished raised TypeError>>,
<bound method Future.result of <Future at 0x7f227e325f50 state=finished raised TypeError>>,
<bound method Future.result of <Future at 0x7f227e330290 state=finished raised TypeError>>,
<bound method Future.result of <Future at 0x7f227e330590 state=finished raised TypeError>>]
This of course is without actually calling results, but if i change print([i.result for i in cats_results])
to print([i.result() for i in cats_results])
it returns:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in main
File "/usr/lib/python2.7/site-packages/concurrent/futures/_base.py", line 422, in result
return self.__get_result()
File "/usr/lib/python2.7/site-packages/concurrent/futures/thread.py", line 62, in run
result = self.fn(*self.args, **self.kwargs)
TypeError: 'str' object is not callable
But if I do:
def main():
names = ["Sprinkles", "Button", "Fluffy", "Semla"]
cats = [cat(name = i) for i in names]
cats_results = [i.sayname() for i in cats]
print([i for i in cats_results])
It returns no problem with:
['Miaw, Sprinkles', 'Miaw, Button', 'Miaw, Fluffy', 'Miaw, Semla']
Any idea on what is happening with executor.submit?
(I'm using python 3.6.6)
It looks like typos, after a few corrections everything works:
import concurrent.futures
import time
class cat:
def __init__(self, name=""):
self.name = name
def sayname(self):
return ("Miaw, " + self.name)
def main():
names = ["Sprinkles", "Button", "Fluffy", "Semla"]
cats = [cat(name=i) for i in names]
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
cats_results = [executor.submit(i.sayname) for i in cats]
print([i.result() for i in cats_results])
main()