Merge pull request #8695 from bluetech/export-parser
argparsing: export Parser and OptionGroup for typing purposes
This commit is contained in:
		
						commit
						1b5f5326d7
					
				|  | @ -1,7 +1,7 @@ | |||
| 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``. | ||||
| 
 | ||||
| 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")``, | ||||
| which is similar to the existing ``pathlist``, | ||||
| 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.runner.CallInfo`` | ||||
| - ``_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. | ||||
|  |  | |||
|  | @ -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.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.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. | ||||
| 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): | ||||
| 
 | ||||
| - ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead. | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ Backward compatibilities in ``Parser.addoption`` | |||
| 
 | ||||
| .. 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): | ||||
| 
 | ||||
| - ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead. | ||||
|  |  | |||
|  | @ -889,9 +889,14 @@ Node | |||
| Parser | ||||
| ~~~~~~ | ||||
| 
 | ||||
| .. autoclass:: _pytest.config.argparsing.Parser() | ||||
| .. autoclass:: pytest.Parser() | ||||
|     :members: | ||||
| 
 | ||||
| OptionGroup | ||||
| ~~~~~~~~~~~ | ||||
| 
 | ||||
| .. autoclass:: pytest.OptionGroup() | ||||
|     :members: | ||||
| 
 | ||||
| PytestPluginManager | ||||
| ~~~~~~~~~~~~~~~~~~~ | ||||
|  |  | |||
|  | @ -909,6 +909,7 @@ class Config: | |||
|         self._parser = Parser( | ||||
|             usage=f"%(prog)s [options] [{_a}] [{_a}] [...]", | ||||
|             processopt=self._processopt, | ||||
|             _ispytest=True, | ||||
|         ) | ||||
|         self.pluginmanager = pluginmanager | ||||
|         """The plugin manager handles plugin registration and hook invocation. | ||||
|  | @ -1380,8 +1381,8 @@ class Config: | |||
|         """Return configuration value from an :ref:`ini file <configfiles>`. | ||||
| 
 | ||||
|         If the specified name hasn't been registered through a prior | ||||
|         :py:func:`parser.addini <_pytest.config.argparsing.Parser.addini>` | ||||
|         call (usually from a plugin), a ValueError is raised. | ||||
|         :func:`parser.addini <pytest.Parser.addini>` call (usually from a | ||||
|         plugin), a ValueError is raised. | ||||
|         """ | ||||
|         try: | ||||
|             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_TYPE_STR | ||||
| from _pytest.deprecated import ARGUMENT_TYPE_STR_CHOICE | ||||
| from _pytest.deprecated import check_ispytest | ||||
| 
 | ||||
| if TYPE_CHECKING: | ||||
|     from typing import NoReturn | ||||
|  | @ -43,8 +44,11 @@ class Parser: | |||
|         self, | ||||
|         usage: Optional[str] = None, | ||||
|         processopt: Optional[Callable[["Argument"], None]] = None, | ||||
|         *, | ||||
|         _ispytest: bool = False, | ||||
|     ) -> 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._processopt = processopt | ||||
|         self._usage = usage | ||||
|  | @ -67,14 +71,14 @@ class Parser: | |||
|         :after: Name of another group, used for ordering --help output. | ||||
| 
 | ||||
|         The returned group object has an ``addoption`` method with the same | ||||
|         signature as :py:func:`parser.addoption | ||||
|         <_pytest.config.argparsing.Parser.addoption>` but will be shown in the | ||||
|         respective group in the output of ``pytest. --help``. | ||||
|         signature as :func:`parser.addoption <pytest.Parser.addoption>` but | ||||
|         will be shown in the respective group in the output of | ||||
|         ``pytest. --help``. | ||||
|         """ | ||||
|         for group in self._groups: | ||||
|             if group.name == name: | ||||
|                 return group | ||||
|         group = OptionGroup(name, description, parser=self) | ||||
|         group = OptionGroup(name, description, parser=self, _ispytest=True) | ||||
|         i = 0 | ||||
|         for i, grp in enumerate(self._groups): | ||||
|             if grp.name == after: | ||||
|  | @ -334,9 +338,17 @@ class Argument: | |||
| 
 | ||||
| 
 | ||||
| class OptionGroup: | ||||
|     """A group of options shown in its own section.""" | ||||
| 
 | ||||
|     def __init__( | ||||
|         self, name: str, description: str = "", parser: Optional[Parser] = None | ||||
|         self, | ||||
|         name: str, | ||||
|         description: str = "", | ||||
|         parser: Optional[Parser] = None, | ||||
|         *, | ||||
|         _ispytest: bool = False, | ||||
|     ) -> None: | ||||
|         check_ispytest(_ispytest) | ||||
|         self.name = name | ||||
|         self.description = description | ||||
|         self.options: List[Argument] = [] | ||||
|  | @ -346,9 +358,9 @@ class OptionGroup: | |||
|         """Add an option to this group. | ||||
| 
 | ||||
|         If a shortened version of a long option is specified, it will | ||||
|         be suppressed in the help. addoption('--twowords', '--two-words') | ||||
|         results in help showing '--two-words' only, but --twowords gets | ||||
|         accepted **and** the automatic destination is in args.twowords. | ||||
|         be suppressed in the help. ``addoption('--twowords', '--two-words')`` | ||||
|         results in help showing ``--two-words`` only, but ``--twowords`` gets | ||||
|         accepted **and** the automatic destination is in ``args.twowords``. | ||||
|         """ | ||||
|         conflict = set(optnames).intersection( | ||||
|             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 | ||||
|         :ref:`discovers plugins during startup <pluginorder>`. | ||||
| 
 | ||||
|     :param _pytest.config.argparsing.Parser parser: | ||||
|     :param pytest.Parser parser: | ||||
|         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(...) | ||||
|         <_pytest.config.argparsing.Parser.addini>`. | ||||
|         <pytest.Parser.addini>`. | ||||
| 
 | ||||
|     :param _pytest.config.PytestPluginManager pluginmanager: | ||||
|         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 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 main | ||||
| 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.fixtures import _fillfuncargs | ||||
| from _pytest.fixtures import fixture | ||||
|  | @ -103,8 +105,10 @@ __all__ = [ | |||
|     "Metafunc", | ||||
|     "Module", | ||||
|     "MonkeyPatch", | ||||
|     "OptionGroup", | ||||
|     "Package", | ||||
|     "param", | ||||
|     "Parser", | ||||
|     "PytestAssertRewriteWarning", | ||||
|     "PytestCacheWarning", | ||||
|     "PytestCollectionWarning", | ||||
|  |  | |||
|  | @ -14,12 +14,12 @@ from _pytest.pytester import Pytester | |||
| 
 | ||||
| @pytest.fixture | ||||
| def parser() -> parseopt.Parser: | ||||
|     return parseopt.Parser() | ||||
|     return parseopt.Parser(_ispytest=True) | ||||
| 
 | ||||
| 
 | ||||
| class TestParser: | ||||
|     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"])) | ||||
| 
 | ||||
|     def test_custom_prog(self, parser: parseopt.Parser) -> None: | ||||
|  | @ -90,13 +90,13 @@ class TestParser: | |||
|         assert groups_names == list("132") | ||||
| 
 | ||||
|     def test_group_addoption(self) -> None: | ||||
|         group = parseopt.OptionGroup("hello") | ||||
|         group = parseopt.OptionGroup("hello", _ispytest=True) | ||||
|         group.addoption("--option1", action="store_true") | ||||
|         assert len(group.options) == 1 | ||||
|         assert isinstance(group.options[0], parseopt.Argument) | ||||
| 
 | ||||
|     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") | ||||
|         with pytest.raises(ValueError) as err: | ||||
|             group.addoption("--option1", "--option-one", action="store_true") | ||||
|  | @ -188,7 +188,7 @@ class TestParser: | |||
|             elif option.type is str: | ||||
|                 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("--hello", dest="hello", type=str, action="store") | ||||
|         parser.addoption("--no", dest="no", action="store_true") | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue