diff --git a/changelog.d/3091.misc.rst b/changelog.d/3091.misc.rst new file mode 100644 index 0000000000..d66641253a --- /dev/null +++ b/changelog.d/3091.misc.rst @@ -0,0 +1,4 @@ +Make ``concurrent.futures`` import lazy in vendored ``more_itertools`` +package to a avoid importing threading as a side effect (which caused +`gevent/gevent#1865 `__). +-- by :user:`maciejp-ro` diff --git a/pkg_resources/_vendor/more_itertools/more.py b/pkg_resources/_vendor/more_itertools/more.py index 630af973f2..6b6a5cab25 100644 --- a/pkg_resources/_vendor/more_itertools/more.py +++ b/pkg_resources/_vendor/more_itertools/more.py @@ -2,7 +2,6 @@ from collections import Counter, defaultdict, deque, abc from collections.abc import Sequence -from concurrent.futures import ThreadPoolExecutor from functools import partial, reduce, wraps from heapq import merge, heapify, heapreplace, heappop from itertools import ( @@ -3656,7 +3655,7 @@ def __init__(self, func, callback_kwd='callback', wait_seconds=0.1): self._aborted = False self._future = None self._wait_seconds = wait_seconds - self._executor = ThreadPoolExecutor(max_workers=1) + self._executor = __import__("concurrent.futures").futures.ThreadPoolExecutor(max_workers=1) self._iterator = self._reader() def __enter__(self): diff --git a/setuptools/_vendor/more_itertools/more.py b/setuptools/_vendor/more_itertools/more.py index 0f7d282aa5..e6fca4d47f 100644 --- a/setuptools/_vendor/more_itertools/more.py +++ b/setuptools/_vendor/more_itertools/more.py @@ -2,7 +2,6 @@ from collections import Counter, defaultdict, deque, abc from collections.abc import Sequence -from concurrent.futures import ThreadPoolExecutor from functools import partial, reduce, wraps from heapq import merge, heapify, heapreplace, heappop from itertools import ( @@ -3454,7 +3453,7 @@ def __init__(self, func, callback_kwd='callback', wait_seconds=0.1): self._aborted = False self._future = None self._wait_seconds = wait_seconds - self._executor = ThreadPoolExecutor(max_workers=1) + self._executor = __import__("concurrent.futures").futures.ThreadPoolExecutor(max_workers=1) self._iterator = self._reader() def __enter__(self): diff --git a/tools/vendored.py b/tools/vendored.py index 57e28d53c4..ee978e5c82 100644 --- a/tools/vendored.py +++ b/tools/vendored.py @@ -64,6 +64,21 @@ def rewrite_importlib_resources(pkg_files, new_root): file.write_text(text) +def rewrite_more_itertools(pkg_files: Path): + """ + Defer import of concurrent.futures. Workaround for #3090. + """ + more_file = pkg_files.joinpath('more.py') + text = more_file.read_text() + text = re.sub(r'^.*concurrent.futures.*?\n', '', text, flags=re.MULTILINE) + text = re.sub( + 'ThreadPoolExecutor', + '__import__("concurrent.futures").futures.ThreadPoolExecutor', + text, + ) + more_file.write_text(text) + + def clean(vendor): """ Remove all files out of the vendor directory except the meta @@ -96,6 +111,7 @@ def update_pkg_resources(): rewrite_jaraco_text(vendor / 'jaraco/text', 'pkg_resources.extern') rewrite_jaraco(vendor / 'jaraco', 'pkg_resources.extern') rewrite_importlib_resources(vendor / 'importlib_resources', 'pkg_resources.extern') + rewrite_more_itertools(vendor / "more_itertools") def update_setuptools(): @@ -105,6 +121,7 @@ def update_setuptools(): rewrite_jaraco_text(vendor / 'jaraco/text', 'setuptools.extern') rewrite_jaraco(vendor / 'jaraco', 'setuptools.extern') rewrite_importlib_resources(vendor / 'importlib_resources', 'setuptools.extern') + rewrite_more_itertools(vendor / "more_itertools") __name__ == '__main__' and update_vendored()