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:
parent
26c9465a22
commit
c0a7582e3d
10
black.py
10
black.py
@ -618,7 +618,14 @@ def reformat_many(
|
|||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
# Work around https://bugs.python.org/issue26903
|
# Work around https://bugs.python.org/issue26903
|
||||||
worker_count = min(worker_count, 61)
|
worker_count = min(worker_count, 61)
|
||||||
|
try:
|
||||||
executor = ProcessPoolExecutor(max_workers=worker_count)
|
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:
|
try:
|
||||||
loop.run_until_complete(
|
loop.run_until_complete(
|
||||||
schedule_formatting(
|
schedule_formatting(
|
||||||
@ -633,6 +640,7 @@ def reformat_many(
|
|||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
shutdown(loop)
|
shutdown(loop)
|
||||||
|
if executor is not None:
|
||||||
executor.shutdown()
|
executor.shutdown()
|
||||||
|
|
||||||
|
|
||||||
@ -643,7 +651,7 @@ async def schedule_formatting(
|
|||||||
mode: Mode,
|
mode: Mode,
|
||||||
report: "Report",
|
report: "Report",
|
||||||
loop: asyncio.AbstractEventLoop,
|
loop: asyncio.AbstractEventLoop,
|
||||||
executor: Executor,
|
executor: Optional[Executor],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Run formatting of `sources` in parallel using the provided `executor`.
|
"""Run formatting of `sources` in parallel using the provided `executor`.
|
||||||
|
|
||||||
|
@ -1273,6 +1273,27 @@ def test_cache_multiple_files(self) -> None:
|
|||||||
self.assertIn(one, cache)
|
self.assertIn(one, cache)
|
||||||
self.assertIn(two, 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:
|
def test_no_cache_when_writeback_diff(self) -> None:
|
||||||
mode = black.FileMode()
|
mode = black.FileMode()
|
||||||
with cache_dir() as workspace:
|
with cache_dir() as workspace:
|
||||||
|
Loading…
Reference in New Issue
Block a user