From 05a48404caaa1de33601cb6032ee38904713bf82 Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Mon, 30 Sep 2019 16:25:25 +0300 Subject: [PATCH 1/8] fix crash when sys.stdin is None --- src/pip/_internal/vcs/subversion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index 7a2cd9f6def..859b1a8fffa 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -188,7 +188,7 @@ def is_commit_id_equal(cls, dest, name): def __init__(self, use_interactive=None): # type: (bool) -> None if use_interactive is None: - use_interactive = sys.stdin.isatty() + use_interactive = sys.stdin and sys.stdin.isatty() self.use_interactive = use_interactive # This member is used to cache the fetched version of the current From be084e0fde322071a6f581db8f0fc927d2f23fca Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Tue, 1 Oct 2019 09:28:58 +0300 Subject: [PATCH 2/8] add news entries --- news/7118.bugfix | 1 + news/7119.bugfix | 1 + 2 files changed, 2 insertions(+) create mode 100644 news/7118.bugfix create mode 100644 news/7119.bugfix diff --git a/news/7118.bugfix b/news/7118.bugfix new file mode 100644 index 00000000000..602b9b578d4 --- /dev/null +++ b/news/7118.bugfix @@ -0,0 +1 @@ +Fix a crash when ``sys.stdin`` is set to ``None``, such as on AWS Lambda. \ No newline at end of file diff --git a/news/7119.bugfix b/news/7119.bugfix new file mode 100644 index 00000000000..602b9b578d4 --- /dev/null +++ b/news/7119.bugfix @@ -0,0 +1 @@ +Fix a crash when ``sys.stdin`` is set to ``None``, such as on AWS Lambda. \ No newline at end of file From 7e50674393a5c8f00bc79f7995675332f15bfed1 Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Tue, 1 Oct 2019 18:55:13 +0300 Subject: [PATCH 3/8] extract function to misc --- src/pip/_internal/utils/misc.py | 7 +++++++ src/pip/_internal/vcs/subversion.py | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index 67729649590..56339951048 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -864,3 +864,10 @@ def protect_pip_from_modification_on_windows(modifying_pip): 'To modify pip, please run the following command:\n{}' .format(" ".join(new_command)) ) + + +def is_console_interactive(): + # type: () -> bool + """Is this console interactive? + """ + return sys.stdin is not None and sys.stdin.isatty() diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index 859b1a8fffa..be49f6b70dd 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -13,6 +13,7 @@ display_path, rmtree, split_auth_from_netloc, + is_console_interactive ) from pip._internal.utils.subprocess import make_command from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -188,7 +189,7 @@ def is_commit_id_equal(cls, dest, name): def __init__(self, use_interactive=None): # type: (bool) -> None if use_interactive is None: - use_interactive = sys.stdin and sys.stdin.isatty() + use_interactive = is_console_interactive() self.use_interactive = use_interactive # This member is used to cache the fetched version of the current From 60d2ade74c6c64f89f94cd96ca8455a77c7c967d Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Tue, 1 Oct 2019 19:00:03 +0300 Subject: [PATCH 4/8] remove no longer used import --- src/pip/_internal/vcs/subversion.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index be49f6b70dd..4c2a281831a 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -6,7 +6,6 @@ import logging import os import re -import sys from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( From 6f7c3041671ccc3ba8bfb53e265fa14acc22d782 Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Wed, 2 Oct 2019 08:25:56 +0300 Subject: [PATCH 5/8] add tests --- tests/unit/test_utils.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index a383f153141..f401c122354 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -50,7 +50,7 @@ rmtree_errorhandler, split_auth_from_netloc, split_auth_netloc_from_url, -) + is_console_interactive) from pip._internal.utils.setuptools_build import make_setuptools_shim_args @@ -971,3 +971,29 @@ def test_make_setuptools_shim_args__unbuffered_output(unbuffered_output): unbuffered_output=unbuffered_output ) assert ('-u' in args) == unbuffered_output + + +def mock_stdin_isatty(monkeypatch, return_value): + monkeypatch.setattr(sys.stdin, 'isatty', Mock(return_value=return_value)) + + +def test_is_console_interactive_when_stdin_is_none_and_isatty_true(monkeypatch): + mock_stdin_isatty(monkeypatch, True) + monkeypatch.setattr(sys, 'stdin', None) + assert is_console_interactive() is False + + +def test_is_console_interactive_when_stdin_is_none_and_isatty_false(monkeypatch): + mock_stdin_isatty(monkeypatch, False) + monkeypatch.setattr(sys, 'stdin', None) + assert is_console_interactive() is False + + +def test_is_console_interactive_when_stdin_is_not_none_and_isatty_true(monkeypatch): + mock_stdin_isatty(monkeypatch, True) + assert is_console_interactive() is True + + +def test_is_console_interactive_when_stdin_is_not_none_and_isatty_false(monkeypatch): + mock_stdin_isatty(monkeypatch, False) + assert is_console_interactive() is False From 004103c0f5e66ca0534b59ee024217e5258bd640 Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Wed, 2 Oct 2019 08:33:41 +0300 Subject: [PATCH 6/8] fix code quality issues --- news/7118.bugfix | 2 +- news/7119.bugfix | 2 +- src/pip/_internal/vcs/subversion.py | 4 ++-- tests/unit/test_utils.py | 13 +++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/news/7118.bugfix b/news/7118.bugfix index 602b9b578d4..8cca2e1bf46 100644 --- a/news/7118.bugfix +++ b/news/7118.bugfix @@ -1 +1 @@ -Fix a crash when ``sys.stdin`` is set to ``None``, such as on AWS Lambda. \ No newline at end of file +Fix a crash when ``sys.stdin`` is set to ``None``, such as on AWS Lambda. diff --git a/news/7119.bugfix b/news/7119.bugfix index 602b9b578d4..8cca2e1bf46 100644 --- a/news/7119.bugfix +++ b/news/7119.bugfix @@ -1 +1 @@ -Fix a crash when ``sys.stdin`` is set to ``None``, such as on AWS Lambda. \ No newline at end of file +Fix a crash when ``sys.stdin`` is set to ``None``, such as on AWS Lambda. diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index 4c2a281831a..16b0be855b8 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -10,9 +10,9 @@ from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( display_path, + is_console_interactive, rmtree, - split_auth_from_netloc, - is_console_interactive + split_auth_from_netloc ) from pip._internal.utils.subprocess import make_command from pip._internal.utils.typing import MYPY_CHECK_RUNNING diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index f401c122354..bcf0841165f 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -39,6 +39,7 @@ get_prog, hide_url, hide_value, + is_console_interactive, normalize_path, normalize_version_info, parse_netloc, @@ -49,8 +50,8 @@ rmtree, rmtree_errorhandler, split_auth_from_netloc, - split_auth_netloc_from_url, - is_console_interactive) + split_auth_netloc_from_url +) from pip._internal.utils.setuptools_build import make_setuptools_shim_args @@ -977,23 +978,23 @@ def mock_stdin_isatty(monkeypatch, return_value): monkeypatch.setattr(sys.stdin, 'isatty', Mock(return_value=return_value)) -def test_is_console_interactive_when_stdin_is_none_and_isatty_true(monkeypatch): +def test_is_console_interactive_when_stdin_none_and_isatty(monkeypatch): mock_stdin_isatty(monkeypatch, True) monkeypatch.setattr(sys, 'stdin', None) assert is_console_interactive() is False -def test_is_console_interactive_when_stdin_is_none_and_isatty_false(monkeypatch): +def test_is_console_interactive_when_stdin_none_and_not_isatty(monkeypatch): mock_stdin_isatty(monkeypatch, False) monkeypatch.setattr(sys, 'stdin', None) assert is_console_interactive() is False -def test_is_console_interactive_when_stdin_is_not_none_and_isatty_true(monkeypatch): +def test_is_console_interactive_when_stdin_isatty(monkeypatch): mock_stdin_isatty(monkeypatch, True) assert is_console_interactive() is True -def test_is_console_interactive_when_stdin_is_not_none_and_isatty_false(monkeypatch): +def test_is_console_interactive_when_stdin_not_isatty(monkeypatch): mock_stdin_isatty(monkeypatch, False) assert is_console_interactive() is False From c7e239c47ce33db7a832f7fda07c5e30183b0253 Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Wed, 2 Oct 2019 08:51:14 +0300 Subject: [PATCH 7/8] fix linter --- src/pip/_internal/vcs/subversion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index 16b0be855b8..6c76d1ad435 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -12,7 +12,7 @@ display_path, is_console_interactive, rmtree, - split_auth_from_netloc + split_auth_from_netloc, ) from pip._internal.utils.subprocess import make_command from pip._internal.utils.typing import MYPY_CHECK_RUNNING From 5089b84c560873e3778a59cff7aa94a727fee00f Mon Sep 17 00:00:00 2001 From: Emil Burzo Date: Wed, 2 Oct 2019 08:51:32 +0300 Subject: [PATCH 8/8] rewrite tests using `pytest.mark.parametrize` --- tests/unit/test_utils.py | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index bcf0841165f..25d39928f35 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -50,7 +50,7 @@ rmtree, rmtree_errorhandler, split_auth_from_netloc, - split_auth_netloc_from_url + split_auth_netloc_from_url, ) from pip._internal.utils.setuptools_build import make_setuptools_shim_args @@ -974,27 +974,16 @@ def test_make_setuptools_shim_args__unbuffered_output(unbuffered_output): assert ('-u' in args) == unbuffered_output -def mock_stdin_isatty(monkeypatch, return_value): - monkeypatch.setattr(sys.stdin, 'isatty', Mock(return_value=return_value)) - - -def test_is_console_interactive_when_stdin_none_and_isatty(monkeypatch): - mock_stdin_isatty(monkeypatch, True) - monkeypatch.setattr(sys, 'stdin', None) - assert is_console_interactive() is False - - -def test_is_console_interactive_when_stdin_none_and_not_isatty(monkeypatch): - mock_stdin_isatty(monkeypatch, False) - monkeypatch.setattr(sys, 'stdin', None) - assert is_console_interactive() is False - - -def test_is_console_interactive_when_stdin_isatty(monkeypatch): - mock_stdin_isatty(monkeypatch, True) - assert is_console_interactive() is True +@pytest.mark.parametrize('isatty,no_stdin,expected', [ + (True, False, True), + (False, False, False), + (True, True, False), + (False, True, False), +]) +def test_is_console_interactive(monkeypatch, isatty, no_stdin, expected): + monkeypatch.setattr(sys.stdin, 'isatty', Mock(return_value=isatty)) + if no_stdin: + monkeypatch.setattr(sys, 'stdin', None) -def test_is_console_interactive_when_stdin_not_isatty(monkeypatch): - mock_stdin_isatty(monkeypatch, False) - assert is_console_interactive() is False + assert is_console_interactive() is expected