-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
gh-108518: Make concurrent.futures.Executor.map() consistent with built-in map() #109497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good code, but slightly over-engineered. I think that it will be better after simplification.
And there is a regression (removing the close()
method).
Lib/concurrent/futures/_base.py
Outdated
@@ -566,6 +568,46 @@ def set_exception(self, exception): | |||
|
|||
__class_getitem__ = classmethod(types.GenericAlias) | |||
|
|||
|
|||
class _FutureResult(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks over-engineered. Why not simply use a result-exception tuple?
Lib/concurrent/futures/_base.py
Outdated
@classmethod | ||
def from_generator(cls, gen): | ||
return cls(gen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is redundant. You can simply use constructor.
Lib/concurrent/futures/_base.py
Outdated
@@ -648,6 +695,25 @@ def __exit__(self, exc_type, exc_val, exc_tb): | |||
return False | |||
|
|||
|
|||
class _MapResultIterator(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(object)
is redundant.
Current iterator has the close()
method, calling which cancels all futures. It is a useful feature. Please add a close()
method in a new class. I do not think that it is worth to implement send()
and throw()
, they are not so useful and are rather an implementation detail.
) as gen: | ||
with self.assertRaises(TimeoutError): | ||
next(gen) | ||
iterator = pool.map(log_n_wait, ["second"], timeout=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code should continue to work without changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I resolved conflicts, fixed some errors, simplified code, added the close method, added docs and more tests. TimeoutError immediately cancels all calls.
Now this PR LGTM.
@pitrou, @brianquinlan, @vstinner, @gpshead, could anybody of your please take a look at this if you have a time?
The current behavior of
concurrent.futures.Executor.map()
is not consistent with documentation:When a
next
call raises an Exception, you can not get any subsequent Future result, even if the computation has completed and returns a valid result.If it is expected or don't consider to make changes to this behavior, I'd like to make a PR to update the relevant docs.