From 4f35ee03f8a3169acf6351837cd6e6c2d6f34199 Mon Sep 17 00:00:00 2001 From: Shota Imaki Date: Tue, 22 Jun 2021 20:34:03 +0900 Subject: [PATCH 1/5] Accept empty stdin (close #2337) --- src/black/__init__.py | 3 ++- tests/test_black.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/black/__init__.py b/src/black/__init__.py index a985926afa5..8e2123d50cc 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -803,7 +803,8 @@ def format_stdin_to_stdout( ) if write_back == WriteBack.YES: # Make sure there's a newline after the content - dst += "" if dst[-1] == "\n" else "\n" + if dst and dst[-1] != "\n": + dst += "\n" f.write(dst) elif write_back in (WriteBack.DIFF, WriteBack.COLOR_DIFF): now = datetime.utcnow() diff --git a/tests/test_black.py b/tests/test_black.py index 455cb33e827..519714fbd25 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1679,6 +1679,19 @@ def test_reformat_one_with_stdin_and_existing_path(self) -> None: # __BLACK_STDIN_FILENAME__ should have been stripped report.done.assert_called_with(expected, black.Changed.YES) + def test_reformat_one_with_stdin_empty(self) -> None: + """Check that black doesn't fail for empty stdin (issue/#2337)""" + with patch("sys.stdout", open(os.devnull, "w")): + # Patch `sys.stdout` to null device lest + # `format_stdin_to_stdout` detaches stdout at the end and causes + # "ValueError: I/O operation on closed file" in subsequent tests + black.format_stdin_to_stdout( + fast=True, + content="", + write_back=black.WriteBack.YES, + mode=DEFAULT_MODE, + ) + def test_gitignore_exclude(self) -> None: path = THIS_DIR / "data" / "include_exclude_tests" include = re.compile(r"\.pyi?$") From 2457a48eada8ecf77d346a9c5191187db1a28de0 Mon Sep 17 00:00:00 2001 From: simaki Date: Tue, 22 Jun 2021 21:06:47 +0900 Subject: [PATCH 2/5] Update tests/test_black.py --- tests/test_black.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_black.py b/tests/test_black.py index 519714fbd25..952c25f012d 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1680,7 +1680,6 @@ def test_reformat_one_with_stdin_and_existing_path(self) -> None: report.done.assert_called_with(expected, black.Changed.YES) def test_reformat_one_with_stdin_empty(self) -> None: - """Check that black doesn't fail for empty stdin (issue/#2337)""" with patch("sys.stdout", open(os.devnull, "w")): # Patch `sys.stdout` to null device lest # `format_stdin_to_stdout` detaches stdout at the end and causes From 5cdc36a6673d667b947b5a5b0bf11924f869ca11 Mon Sep 17 00:00:00 2001 From: Shota Imaki Date: Tue, 22 Jun 2021 21:08:18 +0900 Subject: [PATCH 3/5] Add changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 12e8fccbe4e..ea5196e07a0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - Add primer support and test for code piped into black via STDIN (#2315) - Fix internal error when `FORCE_OPTIONAL_PARENTHESES` feature is enabled (#2332) +- Accept empty stdin (#2346) ## 21.6b0 From ed01564d7ecc192f7b75c704dceafcf88cbf6f77 Mon Sep 17 00:00:00 2001 From: Shota Imaki Date: Wed, 23 Jun 2021 12:46:37 +0900 Subject: [PATCH 4/5] Assert Black reformats an empty string to an empty string (#2337) (#2346) --- tests/test_black.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/test_black.py b/tests/test_black.py index 952c25f012d..01b6acd0c17 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -6,6 +6,7 @@ from contextlib import contextmanager from dataclasses import replace import inspect +import io from io import BytesIO import os from pathlib import Path @@ -1680,16 +1681,18 @@ def test_reformat_one_with_stdin_and_existing_path(self) -> None: report.done.assert_called_with(expected, black.Changed.YES) def test_reformat_one_with_stdin_empty(self) -> None: - with patch("sys.stdout", open(os.devnull, "w")): - # Patch `sys.stdout` to null device lest - # `format_stdin_to_stdout` detaches stdout at the end and causes - # "ValueError: I/O operation on closed file" in subsequent tests - black.format_stdin_to_stdout( - fast=True, - content="", - write_back=black.WriteBack.YES, - mode=DEFAULT_MODE, - ) + output = io.StringIO() + with patch("io.TextIOWrapper", lambda *args, **kwargs: output): + try: + black.format_stdin_to_stdout( + fast=True, + content="", + write_back=black.WriteBack.YES, + mode=DEFAULT_MODE, + ) + assert output.getvalue() == "" + except io.UnsupportedOperation: + pass # StringIO does not support detach def test_gitignore_exclude(self) -> None: path = THIS_DIR / "data" / "include_exclude_tests" From cee8fcfc400bca95357aa671e198202455b9c017 Mon Sep 17 00:00:00 2001 From: Shota Imaki Date: Wed, 23 Jun 2021 13:24:12 +0900 Subject: [PATCH 5/5] fix --- tests/test_black.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_black.py b/tests/test_black.py index 01b6acd0c17..c6caa7dfe5e 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1690,9 +1690,9 @@ def test_reformat_one_with_stdin_empty(self) -> None: write_back=black.WriteBack.YES, mode=DEFAULT_MODE, ) - assert output.getvalue() == "" except io.UnsupportedOperation: pass # StringIO does not support detach + assert output.getvalue() == "" def test_gitignore_exclude(self) -> None: path = THIS_DIR / "data" / "include_exclude_tests"