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. 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/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 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( 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*