permits black to run in AWS Lambda: (#1141)

AWS Lambda and some other virtualized environment may not permit access
to /dev/shm on Linux and as such, trying to use ProcessPoolExecutor will
fail.

As using parallelism is only a 'nice to have' feature of black, if it fails
we gracefully fallback to a monoprocess implementation, which permits black
to finish normally.

Co-authored-by: Allan Simon <asimon@yolaw.fr>
This commit is contained in:
Allan Simon 2020-05-08 15:46:07 +02:00 committed by GitHub
parent 26c9465a22
commit c0a7582e3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 3 deletions

View File

@ -618,7 +618,14 @@ def reformat_many(
if sys.platform == "win32":
# Work around https://bugs.python.org/issue26903
worker_count = min(worker_count, 61)
try:
executor = ProcessPoolExecutor(max_workers=worker_count)
except OSError:
# we arrive here if the underlying system does not support multi-processing
# like in AWS Lambda, in which case we gracefully fallback to the default
# mono-process Executor by using None
executor = None
try:
loop.run_until_complete(
schedule_formatting(
@ -633,6 +640,7 @@ def reformat_many(
)
finally:
shutdown(loop)
if executor is not None:
executor.shutdown()
@ -643,7 +651,7 @@ async def schedule_formatting(
mode: Mode,
report: "Report",
loop: asyncio.AbstractEventLoop,
executor: Executor,
executor: Optional[Executor],
) -> None:
"""Run formatting of `sources` in parallel using the provided `executor`.

View File

@ -1273,6 +1273,27 @@ def test_cache_multiple_files(self) -> None:
self.assertIn(one, cache)
self.assertIn(two, cache)
@patch("black.ProcessPoolExecutor", autospec=True)
def test_works_in_mono_process_only_environment(self, mock_executor) -> None:
mock_executor.side_effect = OSError()
mode = black.FileMode()
with cache_dir() as workspace:
one = (workspace / "one.py").resolve()
with one.open("w") as fobj:
fobj.write("print('hello')")
two = (workspace / "two.py").resolve()
with two.open("w") as fobj:
fobj.write("print('hello')")
black.write_cache({}, [one], mode)
self.invokeBlack([str(workspace)])
with one.open("r") as fobj:
self.assertEqual(fobj.read(), "print('hello')")
with two.open("r") as fobj:
self.assertEqual(fobj.read(), 'print("hello")\n')
cache = black.read_cache(mode)
self.assertIn(one, cache)
self.assertIn(two, cache)
def test_no_cache_when_writeback_diff(self) -> None:
mode = black.FileMode()
with cache_dir() as workspace: