Reformat multiple files using a ProcessPoolExecutor.
(
sources: set[Path],
fast: bool,
write_back: WriteBack,
mode: Mode,
report: Report,
workers: int | None,
no_cache: bool = False,
)
| 78 | # not ideal, but this shouldn't cause any issues ... hopefully. ~ichard26 |
| 79 | @mypyc_attr(patchable=True) |
| 80 | def reformat_many( |
| 81 | sources: set[Path], |
| 82 | fast: bool, |
| 83 | write_back: WriteBack, |
| 84 | mode: Mode, |
| 85 | report: Report, |
| 86 | workers: int | None, |
| 87 | no_cache: bool = False, |
| 88 | ) -> None: |
| 89 | """Reformat multiple files using a ProcessPoolExecutor.""" |
| 90 | |
| 91 | if workers is None: |
| 92 | workers = int(os.environ.get("BLACK_NUM_WORKERS", 0)) |
| 93 | workers = workers or os.cpu_count() or 1 |
| 94 | if sys.platform == "win32": |
| 95 | # Work around https://bugs.python.org/issue26903 |
| 96 | workers = min(workers, 60) |
| 97 | if getattr(sys, "frozen", False): |
| 98 | # In frozen builds (e.g. PyInstaller), avoid spawning worker processes (i.e. |
| 99 | # avoid using ProcessPoolExecutor) to prevent shutdown errors when workers |
| 100 | # try to import modules after cleanup begins. |
| 101 | # See https://github.com/psf/black/issues/4823 |
| 102 | workers = 1 |
| 103 | |
| 104 | executor: Executor | None = None |
| 105 | if workers > 1: |
| 106 | try: |
| 107 | executor = ProcessPoolExecutor(max_workers=workers) |
| 108 | except (ImportError, NotImplementedError, OSError): |
| 109 | # we arrive here if the underlying system does not support multi-processing |
| 110 | # like in AWS Lambda or Termux, in which case we gracefully fallback to |
| 111 | # a ThreadPoolExecutor with just a single worker (more workers would not do |
| 112 | # us any good due to the Global Interpreter Lock) |
| 113 | pass |
| 114 | |
| 115 | if executor is None: |
| 116 | executor = ThreadPoolExecutor(max_workers=1) |
| 117 | |
| 118 | loop = maybe_use_uvloop() |
| 119 | asyncio.set_event_loop(loop) |
| 120 | try: |
| 121 | loop.run_until_complete( |
| 122 | schedule_formatting( |
| 123 | sources=sources, |
| 124 | fast=fast, |
| 125 | write_back=write_back, |
| 126 | mode=mode, |
| 127 | report=report, |
| 128 | loop=loop, |
| 129 | executor=executor, |
| 130 | no_cache=no_cache, |
| 131 | ) |
| 132 | ) |
| 133 | finally: |
| 134 | try: |
| 135 | shutdown(loop) |
| 136 | finally: |
| 137 | asyncio.set_event_loop(None) |
no test coverage detected