From 9ce100ba61b6738298d86818a3d0eee7b18bfed7 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Fri, 6 May 2022 07:06:27 -0700 Subject: [PATCH] Move imports of `ThreadPoolExecutor` into `reformat_many()`, allowing Black-in-the-browser (#3046) This is a slight perf win for use-cases that don't invoke `reformat_many()`, but more importantly to me today it means I can use Black in pyscript. --- src/black/__init__.py | 9 +++++++-- tests/test_black.py | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/black/__init__.py b/src/black/__init__.py index 3a1ce24..75321c3 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -1,7 +1,6 @@ import asyncio from json.decoder import JSONDecodeError import json -from concurrent.futures import Executor, ThreadPoolExecutor, ProcessPoolExecutor from contextlib import contextmanager from datetime import datetime from enum import Enum @@ -17,6 +16,7 @@ import sys import tokenize import traceback from typing import ( + TYPE_CHECKING, Any, Dict, Generator, @@ -77,6 +77,9 @@ from blib2to3.pgen2 import token from _black_version import version as __version__ +if TYPE_CHECKING: + from concurrent.futures import Executor + COMPILED = Path(__file__).suffix in (".pyd", ".so") # types @@ -767,6 +770,8 @@ def reformat_many( workers: Optional[int], ) -> None: """Reformat multiple files using a ProcessPoolExecutor.""" + from concurrent.futures import Executor, ThreadPoolExecutor, ProcessPoolExecutor + executor: Executor loop = asyncio.get_event_loop() worker_count = workers if workers is not None else DEFAULT_WORKERS @@ -808,7 +813,7 @@ async def schedule_formatting( mode: Mode, report: "Report", loop: asyncio.AbstractEventLoop, - executor: Executor, + executor: "Executor", ) -> None: """Run formatting of `sources` in parallel using the provided `executor`. diff --git a/tests/test_black.py b/tests/test_black.py index f6663fa..74334d2 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -922,7 +922,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual("".join(err_lines), "") @event_loop() - @patch("black.ProcessPoolExecutor", MagicMock(side_effect=OSError)) + @patch("concurrent.futures.ProcessPoolExecutor", MagicMock(side_effect=OSError)) def test_works_in_mono_process_only_environment(self) -> None: with cache_dir() as workspace: for f in [ @@ -1683,7 +1683,7 @@ class TestCaching: def test_cache_multiple_files(self) -> None: mode = DEFAULT_MODE with cache_dir() as workspace, patch( - "black.ProcessPoolExecutor", new=ThreadPoolExecutor + "concurrent.futures.ProcessPoolExecutor", new=ThreadPoolExecutor ): one = (workspace / "one.py").resolve() with one.open("w") as fobj: @@ -1792,7 +1792,7 @@ class TestCaching: def test_failed_formatting_does_not_get_cached(self) -> None: mode = DEFAULT_MODE with cache_dir() as workspace, patch( - "black.ProcessPoolExecutor", new=ThreadPoolExecutor + "concurrent.futures.ProcessPoolExecutor", new=ThreadPoolExecutor ): failing = (workspace / "failing.py").resolve() with failing.open("w") as fobj: -- 2.39.2