From 3200ff98c1741018703b62cbd33a54f9a1a45b70 Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 01:39:39 +0000 Subject: [PATCH 01/11] Fixes Formatting Exception --- pandas/io/formats/terminal.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pandas/io/formats/terminal.py b/pandas/io/formats/terminal.py index bb34259d710c7..3615b50d933c9 100644 --- a/pandas/io/formats/terminal.py +++ b/pandas/io/formats/terminal.py @@ -99,16 +99,19 @@ def _get_terminal_size_tput(): proc = subprocess.Popen(["tput", "cols"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) - output = proc.communicate(input=None) - cols = int(output[0]) + output_cols = proc.communicate(input=None) proc = subprocess.Popen(["tput", "lines"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) - output = proc.communicate(input=None) - rows = int(output[0]) - return (cols, rows) + output_rows = proc.communicate(input=None) except OSError: return None + try: + cols = int(output_cols[0]) + rows = int(output_rows[0]) + return (cols, rows) + except ValueError: + return None def _get_terminal_size_linux(): From 8acc296640467571ba05309df91f1cac7be1fc60 Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 01:57:11 +0000 Subject: [PATCH 02/11] Fixed try/except block --- pandas/io/formats/terminal.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pandas/io/formats/terminal.py b/pandas/io/formats/terminal.py index 3615b50d933c9..a595a5e7dcfa4 100644 --- a/pandas/io/formats/terminal.py +++ b/pandas/io/formats/terminal.py @@ -104,14 +104,15 @@ def _get_terminal_size_tput(): stdin=subprocess.PIPE, stdout=subprocess.PIPE) output_rows = proc.communicate(input=None) + try: + cols = int(output_cols[0]) + rows = int(output_rows[0]) + return (cols, rows) + except ValueError: + return None except OSError: return None - try: - cols = int(output_cols[0]) - rows = int(output_rows[0]) - return (cols, rows) - except ValueError: - return None + def _get_terminal_size_linux(): From 871b2c24bb19edadba249e68dba8536b5bf2751a Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 01:58:49 +0000 Subject: [PATCH 03/11] Fixed whitespace --- pandas/io/formats/terminal.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/io/formats/terminal.py b/pandas/io/formats/terminal.py index a595a5e7dcfa4..374dcbd4c75cd 100644 --- a/pandas/io/formats/terminal.py +++ b/pandas/io/formats/terminal.py @@ -112,7 +112,6 @@ def _get_terminal_size_tput(): return None except OSError: return None - def _get_terminal_size_linux(): From b5771c78b6d8f0cf1cd349e98f1b70d8fa0905ef Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 16:04:42 +0000 Subject: [PATCH 04/11] Updated variables --- pandas/io/formats/terminal.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pandas/io/formats/terminal.py b/pandas/io/formats/terminal.py index 374dcbd4c75cd..bbc7c62eb38d5 100644 --- a/pandas/io/formats/terminal.py +++ b/pandas/io/formats/terminal.py @@ -94,6 +94,8 @@ def _get_terminal_size_tput(): # get terminal width # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width # -height-of-a-terminal-window + output_cols = None + output_rows = None try: import subprocess proc = subprocess.Popen(["tput", "cols"], @@ -104,14 +106,14 @@ def _get_terminal_size_tput(): stdin=subprocess.PIPE, stdout=subprocess.PIPE) output_rows = proc.communicate(input=None) - try: - cols = int(output_cols[0]) - rows = int(output_rows[0]) - return (cols, rows) - except ValueError: - return None except OSError: return None + try: + cols = int(output_cols[0]) + rows = int(output_rows[0]) + return (cols, rows) + except ValueError: + return None def _get_terminal_size_linux(): From f681c807a286b92a9f2810fc33ffe06fcbd3d377 Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 22:58:27 +0000 Subject: [PATCH 05/11] Updated libraries, variables --- pandas/io/formats/terminal.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pandas/io/formats/terminal.py b/pandas/io/formats/terminal.py index bbc7c62eb38d5..769922b539e69 100644 --- a/pandas/io/formats/terminal.py +++ b/pandas/io/formats/terminal.py @@ -15,7 +15,7 @@ import os import shutil - +import subprocess from pandas.compat import PY3 __all__ = ['get_terminal_size', 'is_terminal'] @@ -94,10 +94,7 @@ def _get_terminal_size_tput(): # get terminal width # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width # -height-of-a-terminal-window - output_cols = None - output_rows = None try: - import subprocess proc = subprocess.Popen(["tput", "cols"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) From 93862bee7c7d1351409612330e961d325769ab64 Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 23:10:19 +0000 Subject: [PATCH 06/11] Updated with the fixing of #25080 --- doc/source/whatsnew/v0.24.2.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v0.24.2.rst b/doc/source/whatsnew/v0.24.2.rst index cba21ce7ee1e6..f687cde6605f1 100644 --- a/doc/source/whatsnew/v0.24.2.rst +++ b/doc/source/whatsnew/v0.24.2.rst @@ -51,7 +51,7 @@ Bug Fixes **I/O** -- +- Fixed an output formatting exception in pandas/io/formats/terminal.py; - - @@ -95,5 +95,5 @@ Bug Fixes Contributors ~~~~~~~~~~~~ - -.. contributors:: v0.24.1..v0.24.2 \ No newline at end of file +EternalLearner42 +.. contributors:: v0.24.1..v0.24.2 From 7c4dea95818f3f55a343623be1e620c8b4504db1 Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 2 Feb 2019 23:30:35 +0000 Subject: [PATCH 07/11] Improved issue description --- doc/source/whatsnew/v0.24.2.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.24.2.rst b/doc/source/whatsnew/v0.24.2.rst index f687cde6605f1..9e29961daa63f 100644 --- a/doc/source/whatsnew/v0.24.2.rst +++ b/doc/source/whatsnew/v0.24.2.rst @@ -51,7 +51,7 @@ Bug Fixes **I/O** -- Fixed an output formatting exception in pandas/io/formats/terminal.py; +- Better handling of terminal printing when the terminal dimensions are not known (#25080); - - @@ -95,5 +95,5 @@ Bug Fixes Contributors ~~~~~~~~~~~~ -EternalLearner42 + .. contributors:: v0.24.1..v0.24.2 From 1eb54ebe0923b55ee4178408178c8e3bda752d6a Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sun, 3 Feb 2019 03:19:51 +0000 Subject: [PATCH 08/11] added test for #25080 --- pandas/tests/io/formats/test_format.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index b0cf5a2f17609..5b95a74cdaba7 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -2792,3 +2792,12 @@ def test_repr_html_ipython_config(ip): """) result = ip.run_cell(code) assert not result.error_in_exec + + +def test_terminal_unknown_dimensions(): + from pandas.io.formats.terminal import _get_terminal_size_tput + monkeypatch.setattr(get_terminal_size_tput, proc, None) + assert OSError + + monkeypatch.setattr(get_terminal_size_tput, output_cols, None) + assert ValueError From b8aa472a435b2c3db7bdb5bcade2b42dfc295c8c Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Sun, 3 Feb 2019 14:27:08 -0600 Subject: [PATCH 09/11] Mock subprocess --- pandas/io/formats/terminal.py | 10 ++++++++-- pandas/tests/io/formats/test_console.py | 17 +++++++++++++++++ pandas/tests/io/formats/test_format.py | 9 --------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/pandas/io/formats/terminal.py b/pandas/io/formats/terminal.py index 769922b539e69..cf2383955d593 100644 --- a/pandas/io/formats/terminal.py +++ b/pandas/io/formats/terminal.py @@ -16,6 +16,7 @@ import os import shutil import subprocess + from pandas.compat import PY3 __all__ = ['get_terminal_size', 'is_terminal'] @@ -94,6 +95,7 @@ def _get_terminal_size_tput(): # get terminal width # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width # -height-of-a-terminal-window + try: proc = subprocess.Popen(["tput", "cols"], stdin=subprocess.PIPE, @@ -105,11 +107,15 @@ def _get_terminal_size_tput(): output_rows = proc.communicate(input=None) except OSError: return None + try: + # Some terminals (e.g. spyder) may report a terminal size of '', + # making the `int` fail. + cols = int(output_cols[0]) rows = int(output_rows[0]) - return (cols, rows) - except ValueError: + return cols, rows + except (ValueError, IndexError): return None diff --git a/pandas/tests/io/formats/test_console.py b/pandas/tests/io/formats/test_console.py index 055763bf62d6e..8738be2c20f99 100644 --- a/pandas/tests/io/formats/test_console.py +++ b/pandas/tests/io/formats/test_console.py @@ -1,6 +1,9 @@ +import subprocess + import pytest from pandas.io.formats.console import detect_console_encoding +from pandas.io.formats.terminal import _get_terminal_size_tput class MockEncoding(object): # TODO(py27): replace with mock @@ -72,3 +75,17 @@ def test_detect_console_encoding_fallback_to_default(monkeypatch, std, locale): context.setattr('sys.stdout', MockEncoding(std)) context.setattr('sys.getdefaultencoding', lambda: 'sysDefaultEncoding') assert detect_console_encoding() == 'sysDefaultEncoding' + + +@pytest.mark.parametrize("size", ['', ['']]) +def test_terminal_unknown_dimensions(size): + mock = pytest.importorskip("unittest.mock") + + def communicate(*args, **kwargs): + return size + + with mock.patch.object(subprocess.Popen, "communicate", + side_effect=communicate): + result = _get_terminal_size_tput() + + assert result is None diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 5b95a74cdaba7..b0cf5a2f17609 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -2792,12 +2792,3 @@ def test_repr_html_ipython_config(ip): """) result = ip.run_cell(code) assert not result.error_in_exec - - -def test_terminal_unknown_dimensions(): - from pandas.io.formats.terminal import _get_terminal_size_tput - monkeypatch.setattr(get_terminal_size_tput, proc, None) - assert OSError - - monkeypatch.setattr(get_terminal_size_tput, output_cols, None) - assert ValueError From 9cacbfacafecdaabb0701ee6dfe36c39915e7cb8 Mon Sep 17 00:00:00 2001 From: EternalLearner42 <46832510+EternalLearner42@users.noreply.github.com> Date: Sat, 9 Feb 2019 00:25:03 +0000 Subject: [PATCH 10/11] Updated the issue --- doc/source/whatsnew/v0.24.2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.2.rst b/doc/source/whatsnew/v0.24.2.rst index 9e29961daa63f..6fc44695bc34d 100644 --- a/doc/source/whatsnew/v0.24.2.rst +++ b/doc/source/whatsnew/v0.24.2.rst @@ -51,7 +51,7 @@ Bug Fixes **I/O** -- Better handling of terminal printing when the terminal dimensions are not known (#25080); +- Better handling of terminal printing when the terminal dimensions are not known (:issue:`25080`); - - From a2b414ccaab83e085d46e8217d5302a5d0f874f4 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Sat, 9 Feb 2019 12:09:22 -0500 Subject: [PATCH 11/11] fix test --- pandas/tests/io/formats/test_console.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pandas/tests/io/formats/test_console.py b/pandas/tests/io/formats/test_console.py index 8738be2c20f99..45c5e982c1c48 100644 --- a/pandas/tests/io/formats/test_console.py +++ b/pandas/tests/io/formats/test_console.py @@ -1,4 +1,4 @@ -import subprocess +import subprocess # noqa: F401 import pytest @@ -78,14 +78,16 @@ def test_detect_console_encoding_fallback_to_default(monkeypatch, std, locale): @pytest.mark.parametrize("size", ['', ['']]) -def test_terminal_unknown_dimensions(size): +def test_terminal_unknown_dimensions(monkeypatch, size): mock = pytest.importorskip("unittest.mock") def communicate(*args, **kwargs): return size - with mock.patch.object(subprocess.Popen, "communicate", - side_effect=communicate): - result = _get_terminal_size_tput() + monkeypatch.setattr('subprocess.Popen', mock.Mock()) + monkeypatch.setattr('subprocess.Popen.return_value.returncode', None) + monkeypatch.setattr( + 'subprocess.Popen.return_value.communicate', communicate) + result = _get_terminal_size_tput() assert result is None