From 69d9194d1fc044833909fd9eaeccb460e6ad03b8 Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Sun, 28 Jun 2020 12:39:21 +0100 Subject: [PATCH 01/10] Display empty or None help parameter on parser option as empty string in CLI --- src/_pytest/helpconfig.py | 13 ++++++++++--- testing/test_helpconfig.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 24952852be4..1a9b142997e 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -170,6 +170,9 @@ def showhelp(config: Config) -> None: help, type, default = config._parser._inidict[name] if type is None: type = "string" + # Empty string parseable by textwrap whereas None isn't. + if help is None: + help = "" spec = "{} ({}):".format(name, type) tw.write(" %s" % spec) spec_len = len(spec) @@ -191,9 +194,13 @@ def showhelp(config: Config) -> None: tw.write(" " * (indent_len - spec_len - 2)) wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False) - tw.line(wrapped[0]) - for line in wrapped[1:]: - tw.line(indent + line) + # If a help string wasn't specified, just write an empty line. + if not wrapped: + tw.write(" " * (indent_len - spec_len - 2)) + else: + tw.line(wrapped[0]) + for line in wrapped[1:]: + tw.line(indent + line) tw.line() tw.line("environment variables:") diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 24590dd3b55..bd5812bfea1 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -38,6 +38,34 @@ def test_help(testdir): ) +def test_empty_help_param(testdir): + """Tests empty help param is displayed correctly. + """ + testdir.makeconftest( + """ + def pytest_addoption(parser): + parser.addini("test_ini", "", default=True, type="bool") + """ + ) + result = testdir.runpytest("--help") + assert result.ret == 0 + result.stdout.fnmatch_lines(["*test_ini*(bool):*"]) + + +def test_none_help_param(testdir): + """Tests help param None is displayed as empty string. + """ + testdir.makeconftest( + """ + def pytest_addoption(parser): + parser.addini("test_ini", None, default=True, type="bool") + """ + ) + result = testdir.runpytest("--help") + assert result.ret == 0 + result.stdout.fnmatch_lines(["*test_ini*(bool):*"]) + + def test_hookvalidation_unknown(testdir): testdir.makeconftest( """ From 24282c76096f99c0870229e3e0305b36a86408c4 Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Sun, 28 Jun 2020 17:58:16 +0100 Subject: [PATCH 02/10] Parameterize parser help option tests --- testing/test_helpconfig.py | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index bd5812bfea1..522be99a6e0 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -38,32 +38,27 @@ def test_help(testdir): ) -def test_empty_help_param(testdir): - """Tests empty help param is displayed correctly. - """ - testdir.makeconftest( +@pytest.mark.parametrize( + "conftest", + [ """ def pytest_addoption(parser): parser.addini("test_ini", "", default=True, type="bool") - """ - ) - result = testdir.runpytest("--help") - assert result.ret == 0 - result.stdout.fnmatch_lines(["*test_ini*(bool):*"]) - - -def test_none_help_param(testdir): - """Tests help param None is displayed as empty string. - """ - testdir.makeconftest( + """, """ def pytest_addoption(parser): parser.addini("test_ini", None, default=True, type="bool") + """, + ], +) +@pytest.mark.parametrize("output", ["*test_ini*(bool):*"]) +def test_empty_or_none_help_param(conftest, output, testdir): + """Tests an empty/None help param is displayed correctly. """ - ) + testdir.makeconftest(conftest) result = testdir.runpytest("--help") assert result.ret == 0 - result.stdout.fnmatch_lines(["*test_ini*(bool):*"]) + result.stdout.fnmatch_lines([output]) def test_hookvalidation_unknown(testdir): From 79325bbdf20b495618708558da71f5c58c6329f4 Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Sun, 28 Jun 2020 18:11:17 +0100 Subject: [PATCH 03/10] Add changelog file for bugfix --- changelog/7394.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/7394.bugfix.rst diff --git a/changelog/7394.bugfix.rst b/changelog/7394.bugfix.rst new file mode 100644 index 00000000000..666aa844b0a --- /dev/null +++ b/changelog/7394.bugfix.rst @@ -0,0 +1 @@ +Fixed an empty/None help param on parser options from throwing an error when executing ``pytest --help``. From b8ea5c763e80f4d87b8bbcc41bd5af0e0e6cc716 Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Thu, 2 Jul 2020 20:50:37 +0100 Subject: [PATCH 04/10] Change missing help arg to throw error --- changelog/7394.bugfix.rst | 2 +- src/_pytest/helpconfig.py | 15 +++++---------- testing/test_helpconfig.py | 7 ++++--- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/changelog/7394.bugfix.rst b/changelog/7394.bugfix.rst index 666aa844b0a..e4e924a8166 100644 --- a/changelog/7394.bugfix.rst +++ b/changelog/7394.bugfix.rst @@ -1 +1 @@ -Fixed an empty/None help param on parser options from throwing an error when executing ``pytest --help``. +Fixed an empty/None help param on parser options from throwing an unexpected error when executing ``pytest --help``. diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 1a9b142997e..9879f9ee717 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -170,9 +170,8 @@ def showhelp(config: Config) -> None: help, type, default = config._parser._inidict[name] if type is None: type = "string" - # Empty string parseable by textwrap whereas None isn't. - if help is None: - help = "" + if help in (None, ""): + raise TypeError(f"help argument must be provided for {name}") spec = "{} ({}):".format(name, type) tw.write(" %s" % spec) spec_len = len(spec) @@ -194,13 +193,9 @@ def showhelp(config: Config) -> None: tw.write(" " * (indent_len - spec_len - 2)) wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False) - # If a help string wasn't specified, just write an empty line. - if not wrapped: - tw.write(" " * (indent_len - spec_len - 2)) - else: - tw.line(wrapped[0]) - for line in wrapped[1:]: - tw.line(indent + line) + tw.line(wrapped[0]) + for line in wrapped[1:]: + tw.line(indent + line) tw.line() tw.line("environment variables:") diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 522be99a6e0..d64f55cc299 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -51,14 +51,15 @@ def pytest_addoption(parser): """, ], ) -@pytest.mark.parametrize("output", ["*test_ini*(bool):*"]) +@pytest.mark.parametrize( + "output", ["*TypeError: help argument must be provided for test_ini*"] +) def test_empty_or_none_help_param(conftest, output, testdir): """Tests an empty/None help param is displayed correctly. """ testdir.makeconftest(conftest) result = testdir.runpytest("--help") - assert result.ret == 0 - result.stdout.fnmatch_lines([output]) + result.stderr.fnmatch_lines([output]) def test_hookvalidation_unknown(testdir): From 567f270af999ba5f73d2c20ae784683561202553 Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Thu, 2 Jul 2020 20:59:31 +0100 Subject: [PATCH 05/10] Change error formatting for py version compatability --- src/_pytest/helpconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 9879f9ee717..d078b894cab 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -171,7 +171,7 @@ def showhelp(config: Config) -> None: if type is None: type = "string" if help in (None, ""): - raise TypeError(f"help argument must be provided for {name}") + raise TypeError("help argument must be provided for {}".format(name)) spec = "{} ({}):".format(name, type) tw.write(" %s" % spec) spec_len = len(spec) From 25caa806fe5db07dc0b3fc9788650b0900c9fd66 Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Fri, 3 Jul 2020 08:23:13 +0100 Subject: [PATCH 06/10] Change wording of error for missing help arg --- src/_pytest/helpconfig.py | 2 +- testing/test_helpconfig.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index d078b894cab..ad3a7bde389 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -171,7 +171,7 @@ def showhelp(config: Config) -> None: if type is None: type = "string" if help in (None, ""): - raise TypeError("help argument must be provided for {}".format(name)) + raise TypeError("help argument cannot be empty for {}".format(name)) spec = "{} ({}):".format(name, type) tw.write(" %s" % spec) spec_len = len(spec) diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index d64f55cc299..82ee33700b5 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -52,7 +52,7 @@ def pytest_addoption(parser): ], ) @pytest.mark.parametrize( - "output", ["*TypeError: help argument must be provided for test_ini*"] + "output", ["*TypeError: help argument cannot be empty for test_ini*"] ) def test_empty_or_none_help_param(conftest, output, testdir): """Tests an empty/None help param is displayed correctly. From 358a738ca78ac384264d79a3ae9c5260b240d5dc Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Fri, 24 Jul 2020 19:21:10 +0100 Subject: [PATCH 07/10] Allow empty help string for parameter --- src/_pytest/helpconfig.py | 13 ++++++++----- testing/test_helpconfig.py | 37 +++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index ad3a7bde389..4fae49aac71 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -170,8 +170,8 @@ def showhelp(config: Config) -> None: help, type, default = config._parser._inidict[name] if type is None: type = "string" - if help in (None, ""): - raise TypeError("help argument cannot be empty for {}".format(name)) + if help is None: + raise TypeError("help argument cannot be None for {}".format(name)) spec = "{} ({}):".format(name, type) tw.write(" %s" % spec) spec_len = len(spec) @@ -193,9 +193,12 @@ def showhelp(config: Config) -> None: tw.write(" " * (indent_len - spec_len - 2)) wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False) - tw.line(wrapped[0]) - for line in wrapped[1:]: - tw.line(indent + line) + if not wrapped: + tw.write(" " * (indent_len - spec_len - 2)) + else: + tw.line(wrapped[0]) + for line in wrapped[1:]: + tw.line(indent + line) tw.line() tw.line("environment variables:") diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 82ee33700b5..5969feb07b1 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -38,28 +38,33 @@ def test_help(testdir): ) -@pytest.mark.parametrize( - "conftest", - [ +def test_none_help_param_raises_exception(testdir): + """Tests a None help param raises a TypeError. + """ + testdir.makeconftest( """ def pytest_addoption(parser): - parser.addini("test_ini", "", default=True, type="bool") - """, + parser.addini("test_ini", None, default=True, type="bool") + """ + ) + result = testdir.runpytest("--help") + result.stderr.fnmatch_lines( + ["*TypeError: help argument cannot be None for test_ini*"] + ) + + +def test_empty_help_param(testdir): + """Tests an empty help param is displayed correctly. + """ + testdir.makeconftest( """ def pytest_addoption(parser): - parser.addini("test_ini", None, default=True, type="bool") - """, - ], -) -@pytest.mark.parametrize( - "output", ["*TypeError: help argument cannot be empty for test_ini*"] -) -def test_empty_or_none_help_param(conftest, output, testdir): - """Tests an empty/None help param is displayed correctly. + parser.addini("test_ini", "", default=True, type="bool") """ - testdir.makeconftest(conftest) + ) result = testdir.runpytest("--help") - result.stderr.fnmatch_lines([output]) + assert result.ret == 0 + result.stdout.fnmatch_lines(["*test_ini*(bool):*"]) def test_hookvalidation_unknown(testdir): From 0e33480694377887ebebfc0b62232f69c687a82a Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Sun, 26 Jul 2020 18:04:05 +0100 Subject: [PATCH 08/10] Expand help param test to surrounding lines --- changelog/7394.bugfix.rst | 3 ++- testing/test_helpconfig.py | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/changelog/7394.bugfix.rst b/changelog/7394.bugfix.rst index e4e924a8166..d34c5bf62c6 100644 --- a/changelog/7394.bugfix.rst +++ b/changelog/7394.bugfix.rst @@ -1 +1,2 @@ -Fixed an empty/None help param on parser options from throwing an unexpected error when executing ``pytest --help``. +Passing an empty ``help`` value to ``Parser.add_option`` is now accepted instead of crashing when running ``pytest --help``. +Passing ``None`` raises a more informative ``TypeError``. \ No newline at end of file diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 5969feb07b1..0cb1882d7e6 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -64,7 +64,13 @@ def pytest_addoption(parser): ) result = testdir.runpytest("--help") assert result.ret == 0 - result.stdout.fnmatch_lines(["*test_ini*(bool):*"]) + lines = [ + " required_plugins (args):", + " plugins that must be present for pytest to run*", + " test_ini (bool):*", + "environment variables:" + ] + result.stdout.fnmatch_lines(lines, consecutive=True) def test_hookvalidation_unknown(testdir): From af131bcf2373352cec12b59198607f426270f38b Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Sun, 26 Jul 2020 18:45:37 +0100 Subject: [PATCH 09/10] Fix linting issues for 7394 changes --- changelog/7394.bugfix.rst | 2 +- testing/test_helpconfig.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog/7394.bugfix.rst b/changelog/7394.bugfix.rst index d34c5bf62c6..b39558cf1d2 100644 --- a/changelog/7394.bugfix.rst +++ b/changelog/7394.bugfix.rst @@ -1,2 +1,2 @@ Passing an empty ``help`` value to ``Parser.add_option`` is now accepted instead of crashing when running ``pytest --help``. -Passing ``None`` raises a more informative ``TypeError``. \ No newline at end of file +Passing ``None`` raises a more informative ``TypeError``. diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 0cb1882d7e6..a33273a2c1d 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -68,7 +68,7 @@ def pytest_addoption(parser): " required_plugins (args):", " plugins that must be present for pytest to run*", " test_ini (bool):*", - "environment variables:" + "environment variables:", ] result.stdout.fnmatch_lines(lines, consecutive=True) From 602c23ae54d0a02eb6b98664f76bfc5965d5d71b Mon Sep 17 00:00:00 2001 From: hp310780 <43389959+hp310780@users.noreply.github.com> Date: Tue, 28 Jul 2020 19:12:10 +0100 Subject: [PATCH 10/10] Remove redundant whitespace --- src/_pytest/helpconfig.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 4fae49aac71..f3623b8a103 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -193,9 +193,7 @@ def showhelp(config: Config) -> None: tw.write(" " * (indent_len - spec_len - 2)) wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False) - if not wrapped: - tw.write(" " * (indent_len - spec_len - 2)) - else: + if wrapped: tw.line(wrapped[0]) for line in wrapped[1:]: tw.line(indent + line)