From 87423d3cc8e3b19a7c332b8d76d407a2550edf06 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 25 Feb 2020 15:31:01 +0100 Subject: [PATCH 1/4] Keep explicit newlines with help texts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes a difference for e.g. pytest-xdist: Before: ``` --dist=distmode set mode for distributing tests to exec environments. each: … available environment. loadscope: … grouped by file to any available environment. (default) no: … ``` After: ``` --dist=distmode set mode for distributing tests to exec environments. each: send each test to all available environments. load: load balance by sending any pending test to any available environment. … (default) no: run tests inprocess, don't distribute. ``` This might also result in unexpected changes (hard wrapping), when line endings where used unintentionally, e.g. with: ``` help=""" some long help text """ ``` But the benefits from that are worth it, and it is easy to fix, as will be done for the internal `assertmode` option. --- src/_pytest/config/argparsing.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index b57db92ca..985a3fd1c 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -509,3 +509,15 @@ class DropShorterLongHelpFormatter(argparse.HelpFormatter): formatted_action_invocation = ", ".join(return_list) action._formatted_action_invocation = formatted_action_invocation # type: ignore return formatted_action_invocation + + def _split_lines(self, text, width): + """Wrap lines after splitting on original newlines. + + This allows to have explicit line breaks in the help text. + """ + import textwrap + + lines = [] + for line in text.splitlines(): + lines.extend(textwrap.wrap(line.strip(), width)) + return lines From 691a7fceea5188625689aea61bb78a12ea1e3571 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 25 Feb 2020 15:46:53 +0100 Subject: [PATCH 2/4] Revisit some help texts with regard to newlines --- src/_pytest/assertion/__init__.py | 11 ++++++----- src/_pytest/cacheprovider.py | 4 ++-- src/_pytest/helpconfig.py | 2 +- src/_pytest/mark/__init__.py | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index 7b5a5889d..b38c6c006 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -27,11 +27,12 @@ def pytest_addoption(parser): choices=("rewrite", "plain"), default="rewrite", metavar="MODE", - help="""Control assertion debugging tools. 'plain' - performs no assertion debugging. 'rewrite' - (the default) rewrites assert statements in - test modules on import to provide assert - expression information.""", + help=( + "Control assertion debugging tools.\n" + "'plain' performs no assertion debugging.\n" + "'rewrite' (the default) rewrites assert statements in test modules" + " on import to provide assert expression information." + ), ) parser.addini( "enable_assertion_pass_hook", diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index ce820ca2b..511ee2acf 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -397,9 +397,9 @@ def pytest_addoption(parser): "--failed-first", action="store_true", dest="failedfirst", - help="run all tests but run the last failures first. " + help="run all tests, but run the last failures first.\n" "This may re-order tests and thus lead to " - "repeated fixture setup/teardown", + "repeated fixture setup/teardown.", ) group.addoption( "--nf", diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index ae37fdea4..11fd02462 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -57,7 +57,7 @@ def pytest_addoption(parser): dest="plugins", default=[], metavar="name", - help="early-load given plugin module name or entry point (multi-allowed). " + help="early-load given plugin module name or entry point (multi-allowed).\n" "To avoid loading of plugins, use the `no:` prefix, e.g. " "`no:doctest`.", ) diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index 134ed1876..242b1e0ca 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -79,8 +79,8 @@ def pytest_addoption(parser): dest="markexpr", default="", metavar="MARKEXPR", - help="only run tests matching given mark expression. " - "example: -m 'mark1 and not mark2'.", + help="only run tests matching given mark expression.\n" + "For example: -m 'mark1 and not mark2'.", ) group.addoption( From 35d136161a577cc5ca75446d90887686ebad966c Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 25 Feb 2020 16:05:17 +0100 Subject: [PATCH 3/4] add test Fixes the test to not match e.g. hypothesis (ref: bdde2ac28). Conflicts: testing/test_helpconfig.py --- testing/test_helpconfig.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index aaf9a2e28..5e4f85228 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -19,7 +19,10 @@ def test_help(testdir): assert result.ret == 0 result.stdout.fnmatch_lines( """ - *-v*verbose* + -m MARKEXPR only run tests matching given mark expression. + For example: -m 'mark1 and not mark2'. + reporting: + --durations=N * *setup.cfg* *minversion* *to see*markers*pytest --markers* From 5a2c69f150d0b537fbb2ac89ad427c34bd60f31b Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Tue, 19 May 2020 19:33:51 -0300 Subject: [PATCH 4/4] Add CHANGELOG for #6817 --- changelog/6817.improvement.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/6817.improvement.rst diff --git a/changelog/6817.improvement.rst b/changelog/6817.improvement.rst new file mode 100644 index 000000000..8d7e30d34 --- /dev/null +++ b/changelog/6817.improvement.rst @@ -0,0 +1,2 @@ +Explicit new-lines in help texts of command-line options are preserved, allowing plugins better control +of the help displayed to users.