Skip to content

gh-108518: Make concurrent.futures.Executor.map() consistent with built-in map() - #109497

Merged
serhiy-storchaka merged 11 commits into
python:mainfrom
xzmeng:futures-map-108518
Aug 11, 2026
Merged

gh-108518: Make concurrent.futures.Executor.map() consistent with built-in map()#109497
serhiy-storchaka merged 11 commits into
python:mainfrom
xzmeng:futures-map-108518

Conversation

@xzmeng

@xzmeng xzmeng commented Sep 16, 2023

Copy link
Copy Markdown
Contributor

The current behavior of concurrent.futures.Executor.map() is not consistent with documentation:

Similar to map(func, *iterables) except:

  • the iterables are collected immediately rather than lazily;
  • func is executed asynchronously and several calls to func may be made concurrently.

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.

@serhiy-storchaka serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

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).

Comment thread Lib/concurrent/futures/_base.py Outdated
__class_getitem__ = classmethod(types.GenericAlias)


class _FutureResult(object):

Copy link
Copy Markdown
Member

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?

Comment thread Lib/concurrent/futures/_base.py Outdated
Comment on lines +703 to +705
@classmethod
def from_generator(cls, gen):
return cls(gen)

Copy link
Copy Markdown
Member

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.

Comment thread Lib/concurrent/futures/_base.py Outdated
return False


class _MapResultIterator(object):

Copy link
Copy Markdown
Member

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)

Copy link
Copy Markdown
Member

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.

@serhiy-storchaka serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

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?

@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Apr 13, 2026
# Conflicts:
#	Lib/concurrent/futures/_base.py
#	Lib/concurrent/futures/process.py
#	Lib/test/test_concurrent_futures/executor.py
@serhiy-storchaka serhiy-storchaka removed the stale Stale PR or inactive for long period of time. label Aug 10, 2026
@read-the-docs-community

read-the-docs-community Bot commented Aug 10, 2026

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #34013628 | 📁 Comparing 17b229a against main (7c906a1)

  🔍 Preview build  

3 files changed
± library/concurrent.futures.html
± whatsnew/3.16.html
± whatsnew/changelog.html

@serhiy-storchaka
serhiy-storchaka merged commit 837627d into python:main Aug 11, 2026
93 of 95 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants