Skip to content

Commit 5e3b7d5

Browse files
committed
config: remove after_preparse
The `after_preparse` hack was used to decide between two behaviors of `--help`: 1. Just set `help` on the Namespace and continue parsing 2. Interrupt the parsing The `after_preparse` was used to make 1 happen before `_preparse` and 2 after. But that's not what we want, the timing shouldn't really matter, only the "mode" in which we parse: - `Parser.parse_known_[and_unknown_]arguments` -- permissive mode, want behavior 1. - `Parser.parse` -- actual parsing, want behavior 2. Make it so.
1 parent e94518d commit 5e3b7d5

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

src/_pytest/config/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,6 @@ def parse(self, args: list[str], addopts: bool = True) -> None:
15281528
kwargs=dict(pluginmanager=self.pluginmanager)
15291529
)
15301530
self._preparse(args, addopts=addopts)
1531-
self._parser.after_preparse = True # type: ignore
15321531
try:
15331532
self._parser.parse(args, namespace=self.option)
15341533
except PrintHelp:

src/_pytest/config/argparsing.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,21 @@ def parse(
130130
"""Parse the arguments.
131131
132132
Unlike ``parse_known_args`` and ``parse_known_and_unknown_args``,
133-
raises UsageError on unknown flags.
133+
raises PrintHelp on `--help` and UsageError on unknown flags
134134
135135
:meta private:
136136
"""
137137
from _pytest._argcomplete import try_argcomplete
138138

139139
try_argcomplete(self.optparser)
140140
strargs = [os.fspath(x) for x in args]
141-
return self.optparser.parse_intermixed_args(strargs, namespace=namespace)
141+
if namespace is None:
142+
namespace = argparse.Namespace()
143+
try:
144+
namespace._raise_print_help = True
145+
return self.optparser.parse_intermixed_args(strargs, namespace=namespace)
146+
finally:
147+
del namespace._raise_print_help
142148

143149
def parse_known_args(
144150
self,

src/_pytest/helpconfig.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,21 @@
1414
from _pytest.config import ExitCode
1515
from _pytest.config import PrintHelp
1616
from _pytest.config.argparsing import Parser
17-
from _pytest.config.argparsing import PytestArgumentParser
1817
from _pytest.terminal import TerminalReporter
1918
import pytest
2019

2120

2221
class HelpAction(argparse.Action):
23-
"""An argparse Action that will raise an exception in order to skip the
24-
rest of the argument parsing when --help is passed.
22+
"""An argparse Action that will raise a PrintHelp exception in order to skip
23+
the rest of the argument parsing when --help is passed.
2524
26-
This prevents argparse from quitting due to missing required arguments
27-
when any are defined, for example by ``pytest_addoption``.
28-
This is similar to the way that the builtin argparse --help option is
29-
implemented by raising SystemExit.
25+
This prevents argparse from raising UsageError when `--help` is used along
26+
with missing required arguments when any are defined, for example by
27+
``pytest_addoption``. This is similar to the way that the builtin argparse
28+
--help option is implemented by raising SystemExit.
29+
30+
To opt in to this behavior, the parse caller must set
31+
`namespace._raise_print_help = True`. Otherwise it just sets the option.
3032
"""
3133

3234
def __init__(
@@ -50,9 +52,7 @@ def __call__(
5052
) -> None:
5153
setattr(namespace, self.dest, self.const)
5254

53-
# We should only skip the rest of the parsing after preparse is done.
54-
assert isinstance(parser, PytestArgumentParser)
55-
if getattr(parser._parser, "after_preparse", False):
55+
if getattr(namespace, "_raise_print_help", False):
5656
raise PrintHelp
5757

5858

testing/test_helpconfig.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ def pytest_addoption(parser):
8383
result.stdout.fnmatch_lines(lines, consecutive=True)
8484

8585

86+
def test_parse_known_args_doesnt_quit_on_help(pytester: Pytester) -> None:
87+
"""`parse_known_args` shouldn't exit on `--help`, unlike `parse`."""
88+
config = pytester.parseconfig()
89+
# Doesn't raise or exit!
90+
config._parser.parse_known_args(["--help"])
91+
config._parser.parse_known_and_unknown_args(["--help"])
92+
93+
8694
def test_hookvalidation_unknown(pytester: Pytester) -> None:
8795
pytester.makeconftest(
8896
"""

0 commit comments

Comments
 (0)