argparsing: export Parser and OptionGroup for typing purposes
`Parser` is used by many plugins and custom hooks. `OptionGroup` is exposed by the `parser.addgroup` API. The constructors of both are marked private, they are not meant to be constructed directly.
This commit is contained in:
parent
c198a7a67e
commit
538b5c2499
|
@ -1,7 +1,7 @@
|
||||||
Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing :meth:`cache.makedir() <pytest.Cache.makedir>`,
|
Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing :meth:`cache.makedir() <pytest.Cache.makedir>`,
|
||||||
but returns a :class:`pathlib.Path` instead of a legacy ``py.path.local``.
|
but returns a :class:`pathlib.Path` instead of a legacy ``py.path.local``.
|
||||||
|
|
||||||
Added a ``paths`` type to :meth:`parser.addini() <_pytest.config.argparsing.Parser.addini>`,
|
Added a ``paths`` type to :meth:`parser.addini() <pytest.Parser.addini>`,
|
||||||
as in ``parser.addini("mypaths", "my paths", type="paths")``,
|
as in ``parser.addini("mypaths", "my paths", type="paths")``,
|
||||||
which is similar to the existing ``pathlist``,
|
which is similar to the existing ``pathlist``,
|
||||||
but returns a list of :class:`pathlib.Path` instead of legacy ``py.path.local``.
|
but returns a list of :class:`pathlib.Path` instead of legacy ``py.path.local``.
|
||||||
|
|
|
@ -6,5 +6,7 @@ Directly constructing the following classes is now deprecated:
|
||||||
- ``_pytest.python.Metafunc``
|
- ``_pytest.python.Metafunc``
|
||||||
- ``_pytest.runner.CallInfo``
|
- ``_pytest.runner.CallInfo``
|
||||||
- ``_pytest._code.ExceptionInfo``
|
- ``_pytest._code.ExceptionInfo``
|
||||||
|
- ``_pytest.config.argparsing.Parser``
|
||||||
|
- ``_pytest.config.argparsing.OptionGroup``
|
||||||
|
|
||||||
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
|
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
|
||||||
|
|
|
@ -8,6 +8,8 @@ The newly-exported types are:
|
||||||
- ``pytest.Metafunc`` for the :class:`metafunc <pytest.MarkGenerator>` argument to the :func:`pytest_generate_tests <pytest.hookspec.pytest_generate_tests>` hook.
|
- ``pytest.Metafunc`` for the :class:`metafunc <pytest.MarkGenerator>` argument to the :func:`pytest_generate_tests <pytest.hookspec.pytest_generate_tests>` hook.
|
||||||
- ``pytest.CallInfo`` for the :class:`CallInfo <pytest.CallInfo>` type passed to various hooks.
|
- ``pytest.CallInfo`` for the :class:`CallInfo <pytest.CallInfo>` type passed to various hooks.
|
||||||
- ``pytest.ExceptionInfo`` for the :class:`ExceptionInfo <pytest.ExceptionInfo>` type returned from :func:`pytest.raises` and passed to various hooks.
|
- ``pytest.ExceptionInfo`` for the :class:`ExceptionInfo <pytest.ExceptionInfo>` type returned from :func:`pytest.raises` and passed to various hooks.
|
||||||
|
- ``pytest.Parser`` for the :class:`Parser <pytest.Parser>` type passed to the :func:`pytest_addoption <pytest.hookspec.pytest_addoption>` hook.
|
||||||
|
- ``pytest.OptionGroup`` for the :class:`OptionGroup <pytest.OptionGroup>` type returned from the :func:`parser.addgroup <pytest.Parser.getgroup>` method.
|
||||||
|
|
||||||
Constructing them directly is not supported; they are only meant for use in type annotations.
|
Constructing them directly is not supported; they are only meant for use in type annotations.
|
||||||
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
|
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Several behaviors of :meth:`Parser.addoption <_pytest.config.argparsing.Parser.addoption>` are now
|
Several behaviors of :meth:`Parser.addoption <pytest.Parser.addoption>` are now
|
||||||
scheduled for removal in pytest 7 (deprecated since pytest 2.4.0):
|
scheduled for removal in pytest 7 (deprecated since pytest 2.4.0):
|
||||||
|
|
||||||
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
|
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
|
||||||
|
|
|
@ -48,7 +48,7 @@ Backward compatibilities in ``Parser.addoption``
|
||||||
|
|
||||||
.. deprecated:: 2.4
|
.. deprecated:: 2.4
|
||||||
|
|
||||||
Several behaviors of :meth:`Parser.addoption <_pytest.config.argparsing.Parser.addoption>` are now
|
Several behaviors of :meth:`Parser.addoption <pytest.Parser.addoption>` are now
|
||||||
scheduled for removal in pytest 7 (deprecated since pytest 2.4.0):
|
scheduled for removal in pytest 7 (deprecated since pytest 2.4.0):
|
||||||
|
|
||||||
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
|
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
|
||||||
|
|
|
@ -889,9 +889,14 @@ Node
|
||||||
Parser
|
Parser
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
.. autoclass:: _pytest.config.argparsing.Parser()
|
.. autoclass:: pytest.Parser()
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
OptionGroup
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: pytest.OptionGroup()
|
||||||
|
:members:
|
||||||
|
|
||||||
PytestPluginManager
|
PytestPluginManager
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -909,6 +909,7 @@ class Config:
|
||||||
self._parser = Parser(
|
self._parser = Parser(
|
||||||
usage=f"%(prog)s [options] [{_a}] [{_a}] [...]",
|
usage=f"%(prog)s [options] [{_a}] [{_a}] [...]",
|
||||||
processopt=self._processopt,
|
processopt=self._processopt,
|
||||||
|
_ispytest=True,
|
||||||
)
|
)
|
||||||
self.pluginmanager = pluginmanager
|
self.pluginmanager = pluginmanager
|
||||||
"""The plugin manager handles plugin registration and hook invocation.
|
"""The plugin manager handles plugin registration and hook invocation.
|
||||||
|
@ -1380,8 +1381,8 @@ class Config:
|
||||||
"""Return configuration value from an :ref:`ini file <configfiles>`.
|
"""Return configuration value from an :ref:`ini file <configfiles>`.
|
||||||
|
|
||||||
If the specified name hasn't been registered through a prior
|
If the specified name hasn't been registered through a prior
|
||||||
:py:func:`parser.addini <_pytest.config.argparsing.Parser.addini>`
|
:func:`parser.addini <pytest.Parser.addini>` call (usually from a
|
||||||
call (usually from a plugin), a ValueError is raised.
|
plugin), a ValueError is raised.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self._inicache[name]
|
return self._inicache[name]
|
||||||
|
|
|
@ -21,6 +21,7 @@ from _pytest.config.exceptions import UsageError
|
||||||
from _pytest.deprecated import ARGUMENT_PERCENT_DEFAULT
|
from _pytest.deprecated import ARGUMENT_PERCENT_DEFAULT
|
||||||
from _pytest.deprecated import ARGUMENT_TYPE_STR
|
from _pytest.deprecated import ARGUMENT_TYPE_STR
|
||||||
from _pytest.deprecated import ARGUMENT_TYPE_STR_CHOICE
|
from _pytest.deprecated import ARGUMENT_TYPE_STR_CHOICE
|
||||||
|
from _pytest.deprecated import check_ispytest
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import NoReturn
|
from typing import NoReturn
|
||||||
|
@ -43,8 +44,11 @@ class Parser:
|
||||||
self,
|
self,
|
||||||
usage: Optional[str] = None,
|
usage: Optional[str] = None,
|
||||||
processopt: Optional[Callable[["Argument"], None]] = None,
|
processopt: Optional[Callable[["Argument"], None]] = None,
|
||||||
|
*,
|
||||||
|
_ispytest: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._anonymous = OptionGroup("custom options", parser=self)
|
check_ispytest(_ispytest)
|
||||||
|
self._anonymous = OptionGroup("custom options", parser=self, _ispytest=True)
|
||||||
self._groups: List[OptionGroup] = []
|
self._groups: List[OptionGroup] = []
|
||||||
self._processopt = processopt
|
self._processopt = processopt
|
||||||
self._usage = usage
|
self._usage = usage
|
||||||
|
@ -67,14 +71,14 @@ class Parser:
|
||||||
:after: Name of another group, used for ordering --help output.
|
:after: Name of another group, used for ordering --help output.
|
||||||
|
|
||||||
The returned group object has an ``addoption`` method with the same
|
The returned group object has an ``addoption`` method with the same
|
||||||
signature as :py:func:`parser.addoption
|
signature as :func:`parser.addoption <pytest.Parser.addoption>` but
|
||||||
<_pytest.config.argparsing.Parser.addoption>` but will be shown in the
|
will be shown in the respective group in the output of
|
||||||
respective group in the output of ``pytest. --help``.
|
``pytest. --help``.
|
||||||
"""
|
"""
|
||||||
for group in self._groups:
|
for group in self._groups:
|
||||||
if group.name == name:
|
if group.name == name:
|
||||||
return group
|
return group
|
||||||
group = OptionGroup(name, description, parser=self)
|
group = OptionGroup(name, description, parser=self, _ispytest=True)
|
||||||
i = 0
|
i = 0
|
||||||
for i, grp in enumerate(self._groups):
|
for i, grp in enumerate(self._groups):
|
||||||
if grp.name == after:
|
if grp.name == after:
|
||||||
|
@ -334,9 +338,17 @@ class Argument:
|
||||||
|
|
||||||
|
|
||||||
class OptionGroup:
|
class OptionGroup:
|
||||||
|
"""A group of options shown in its own section."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, name: str, description: str = "", parser: Optional[Parser] = None
|
self,
|
||||||
|
name: str,
|
||||||
|
description: str = "",
|
||||||
|
parser: Optional[Parser] = None,
|
||||||
|
*,
|
||||||
|
_ispytest: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
check_ispytest(_ispytest)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.description = description
|
self.description = description
|
||||||
self.options: List[Argument] = []
|
self.options: List[Argument] = []
|
||||||
|
@ -346,9 +358,9 @@ class OptionGroup:
|
||||||
"""Add an option to this group.
|
"""Add an option to this group.
|
||||||
|
|
||||||
If a shortened version of a long option is specified, it will
|
If a shortened version of a long option is specified, it will
|
||||||
be suppressed in the help. addoption('--twowords', '--two-words')
|
be suppressed in the help. ``addoption('--twowords', '--two-words')``
|
||||||
results in help showing '--two-words' only, but --twowords gets
|
results in help showing ``--two-words`` only, but ``--twowords`` gets
|
||||||
accepted **and** the automatic destination is in args.twowords.
|
accepted **and** the automatic destination is in ``args.twowords``.
|
||||||
"""
|
"""
|
||||||
conflict = set(optnames).intersection(
|
conflict = set(optnames).intersection(
|
||||||
name for opt in self.options for name in opt.names()
|
name for opt in self.options for name in opt.names()
|
||||||
|
|
|
@ -88,11 +88,11 @@ def pytest_addoption(parser: "Parser", pluginmanager: "PytestPluginManager") ->
|
||||||
files situated at the tests root directory due to how pytest
|
files situated at the tests root directory due to how pytest
|
||||||
:ref:`discovers plugins during startup <pluginorder>`.
|
:ref:`discovers plugins during startup <pluginorder>`.
|
||||||
|
|
||||||
:param _pytest.config.argparsing.Parser parser:
|
:param pytest.Parser parser:
|
||||||
To add command line options, call
|
To add command line options, call
|
||||||
:py:func:`parser.addoption(...) <_pytest.config.argparsing.Parser.addoption>`.
|
:py:func:`parser.addoption(...) <pytest.Parser.addoption>`.
|
||||||
To add ini-file values call :py:func:`parser.addini(...)
|
To add ini-file values call :py:func:`parser.addini(...)
|
||||||
<_pytest.config.argparsing.Parser.addini>`.
|
<pytest.Parser.addini>`.
|
||||||
|
|
||||||
:param _pytest.config.PytestPluginManager pluginmanager:
|
:param _pytest.config.PytestPluginManager pluginmanager:
|
||||||
pytest plugin manager, which can be used to install :py:func:`hookspec`'s
|
pytest plugin manager, which can be used to install :py:func:`hookspec`'s
|
||||||
|
@ -193,7 +193,7 @@ def pytest_load_initial_conftests(
|
||||||
|
|
||||||
:param _pytest.config.Config early_config: The pytest config object.
|
:param _pytest.config.Config early_config: The pytest config object.
|
||||||
:param List[str] args: Arguments passed on the command line.
|
:param List[str] args: Arguments passed on the command line.
|
||||||
:param _pytest.config.argparsing.Parser parser: To add command line options.
|
:param pytest.Parser parser: To add command line options.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ from _pytest.config import hookimpl
|
||||||
from _pytest.config import hookspec
|
from _pytest.config import hookspec
|
||||||
from _pytest.config import main
|
from _pytest.config import main
|
||||||
from _pytest.config import UsageError
|
from _pytest.config import UsageError
|
||||||
|
from _pytest.config.argparsing import OptionGroup
|
||||||
|
from _pytest.config.argparsing import Parser
|
||||||
from _pytest.debugging import pytestPDB as __pytestPDB
|
from _pytest.debugging import pytestPDB as __pytestPDB
|
||||||
from _pytest.fixtures import _fillfuncargs
|
from _pytest.fixtures import _fillfuncargs
|
||||||
from _pytest.fixtures import fixture
|
from _pytest.fixtures import fixture
|
||||||
|
@ -103,8 +105,10 @@ __all__ = [
|
||||||
"Metafunc",
|
"Metafunc",
|
||||||
"Module",
|
"Module",
|
||||||
"MonkeyPatch",
|
"MonkeyPatch",
|
||||||
|
"OptionGroup",
|
||||||
"Package",
|
"Package",
|
||||||
"param",
|
"param",
|
||||||
|
"Parser",
|
||||||
"PytestAssertRewriteWarning",
|
"PytestAssertRewriteWarning",
|
||||||
"PytestCacheWarning",
|
"PytestCacheWarning",
|
||||||
"PytestCollectionWarning",
|
"PytestCollectionWarning",
|
||||||
|
|
|
@ -14,12 +14,12 @@ from _pytest.pytester import Pytester
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def parser() -> parseopt.Parser:
|
def parser() -> parseopt.Parser:
|
||||||
return parseopt.Parser()
|
return parseopt.Parser(_ispytest=True)
|
||||||
|
|
||||||
|
|
||||||
class TestParser:
|
class TestParser:
|
||||||
def test_no_help_by_default(self) -> None:
|
def test_no_help_by_default(self) -> None:
|
||||||
parser = parseopt.Parser(usage="xyz")
|
parser = parseopt.Parser(usage="xyz", _ispytest=True)
|
||||||
pytest.raises(UsageError, lambda: parser.parse(["-h"]))
|
pytest.raises(UsageError, lambda: parser.parse(["-h"]))
|
||||||
|
|
||||||
def test_custom_prog(self, parser: parseopt.Parser) -> None:
|
def test_custom_prog(self, parser: parseopt.Parser) -> None:
|
||||||
|
@ -90,13 +90,13 @@ class TestParser:
|
||||||
assert groups_names == list("132")
|
assert groups_names == list("132")
|
||||||
|
|
||||||
def test_group_addoption(self) -> None:
|
def test_group_addoption(self) -> None:
|
||||||
group = parseopt.OptionGroup("hello")
|
group = parseopt.OptionGroup("hello", _ispytest=True)
|
||||||
group.addoption("--option1", action="store_true")
|
group.addoption("--option1", action="store_true")
|
||||||
assert len(group.options) == 1
|
assert len(group.options) == 1
|
||||||
assert isinstance(group.options[0], parseopt.Argument)
|
assert isinstance(group.options[0], parseopt.Argument)
|
||||||
|
|
||||||
def test_group_addoption_conflict(self) -> None:
|
def test_group_addoption_conflict(self) -> None:
|
||||||
group = parseopt.OptionGroup("hello again")
|
group = parseopt.OptionGroup("hello again", _ispytest=True)
|
||||||
group.addoption("--option1", "--option-1", action="store_true")
|
group.addoption("--option1", "--option-1", action="store_true")
|
||||||
with pytest.raises(ValueError) as err:
|
with pytest.raises(ValueError) as err:
|
||||||
group.addoption("--option1", "--option-one", action="store_true")
|
group.addoption("--option1", "--option-one", action="store_true")
|
||||||
|
@ -188,7 +188,7 @@ class TestParser:
|
||||||
elif option.type is str:
|
elif option.type is str:
|
||||||
option.default = "world"
|
option.default = "world"
|
||||||
|
|
||||||
parser = parseopt.Parser(processopt=defaultget)
|
parser = parseopt.Parser(processopt=defaultget, _ispytest=True)
|
||||||
parser.addoption("--this", dest="this", type=int, action="store")
|
parser.addoption("--this", dest="this", type=int, action="store")
|
||||||
parser.addoption("--hello", dest="hello", type=str, action="store")
|
parser.addoption("--hello", dest="hello", type=str, action="store")
|
||||||
parser.addoption("--no", dest="no", action="store_true")
|
parser.addoption("--no", dest="no", action="store_true")
|
||||||
|
|
Loading…
Reference in New Issue