From cb7f5ed3b1cd0c8e90118adbcafb1b7c4bc8fd63 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sat, 13 Aug 2022 12:35:07 +0300 Subject: [PATCH 1/3] doc: require sphinx 5 Fix #9836. --- doc/en/conf.py | 12 +++++------- doc/en/reference/customize.rst | 2 +- doc/en/reference/reference.rst | 1 + doc/en/requirements.txt | 5 +---- src/_pytest/python_api.py | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/doc/en/conf.py b/doc/en/conf.py index 3c26b8ce0..fe1d54416 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -162,11 +162,11 @@ linkcheck_workers = 5 _repo = "https://github.com/pytest-dev/pytest" extlinks = { - "bpo": ("https://bugs.python.org/issue%s", "bpo-"), - "pypi": ("https://pypi.org/project/%s/", ""), - "issue": (f"{_repo}/issues/%s", "issue #"), - "pull": (f"{_repo}/pull/%s", "pull request #"), - "user": ("https://github.com/%s", "@"), + "bpo": ("https://bugs.python.org/issue%s", "bpo-%s"), + "pypi": ("https://pypi.org/project/%s/", "%s"), + "issue": (f"{_repo}/issues/%s", "issue #%s"), + "pull": (f"{_repo}/pull/%s", "pull request #%s"), + "user": ("https://github.com/%s", "@%s"), } @@ -419,8 +419,6 @@ def configure_logging(app: "sphinx.application.Sphinx") -> None: def setup(app: "sphinx.application.Sphinx") -> None: - # from sphinx.ext.autodoc import cut_lines - # app.connect('autodoc-process-docstring', cut_lines(4, what=['module'])) app.add_crossref_type( "fixture", "fixture", diff --git a/doc/en/reference/customize.rst b/doc/en/reference/customize.rst index b6d21445a..b794d646b 100644 --- a/doc/en/reference/customize.rst +++ b/doc/en/reference/customize.rst @@ -90,7 +90,7 @@ and can also be used to hold pytest configuration if they have a ``[pytest]`` se setup.cfg ~~~~~~~~~ -``setup.cfg`` files are general purpose configuration files, used originally by :doc:`distutils `, and can also be used to hold pytest configuration +``setup.cfg`` files are general purpose configuration files, used originally by :doc:`distutils `, and can also be used to hold pytest configuration if they have a ``[tool:pytest]`` section. .. code-block:: ini diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index bdad8fa59..de11cba55 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -529,6 +529,7 @@ New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`. .. autoclass:: pytest.Testdir() :members: + :noindex: TimeoutExpired .. fixture:: recwarn diff --git a/doc/en/requirements.txt b/doc/en/requirements.txt index 89446634e..a0d54cd4c 100644 --- a/doc/en/requirements.txt +++ b/doc/en/requirements.txt @@ -2,9 +2,6 @@ pallets-sphinx-themes pluggy>=1.0 pygments-pytest>=2.2.0 sphinx-removed-in>=0.2.0 -sphinx>=3.1,<4 +sphinx>=5,<6 sphinxcontrib-trio sphinxcontrib-svg2pdfconverter - -# XXX: sphinx<4 is broken with latest jinja2 -jinja2<3.1 diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 10762ee7b..d825931de 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -521,7 +521,7 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: """Assert that two numbers (or two ordered sequences of numbers) are equal to each other within some tolerance. - Due to the :std:doc:`tutorial/floatingpoint`, numbers that we + Due to the :doc:`python:tutorial/floatingpoint`, numbers that we would intuitively expect to be equal are not always so:: >>> 0.1 + 0.2 == 0.3 From 7431750bb6e48106ded6acd70ef2e4c67aad294a Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Fri, 29 Oct 2021 21:18:12 +0300 Subject: [PATCH 2/3] doc: have tighter control on what autodoc shows New versions of sphinx starting showing `__init__` parameters even when we don't want them to show because they are private (have `_ispytest` argument). The only working solution I found was to switch to `autodoc_typehints_description_target = "documented"` and explicitly document parameters for which we want to show the types. It's a little tedious and repetitive in some simple cases, but overall it results in nicer API docs. --- doc/en/conf.py | 1 + doc/en/reference/reference.rst | 2 +- src/_pytest/assertion/__init__.py | 2 +- src/_pytest/config/argparsing.py | 54 +++++--- src/_pytest/fixtures.py | 19 ++- src/_pytest/hookspec.py | 208 +++++++++++++++++++++--------- src/_pytest/junitxml.py | 5 +- src/_pytest/logging.py | 25 ++-- src/_pytest/mark/__init__.py | 4 +- src/_pytest/monkeypatch.py | 5 +- src/_pytest/nodes.py | 25 ++-- src/_pytest/outcomes.py | 9 +- src/_pytest/pytester.py | 113 ++++++++++------ src/_pytest/python_api.py | 15 ++- src/_pytest/reports.py | 10 +- src/_pytest/tmpdir.py | 6 +- 16 files changed, 335 insertions(+), 168 deletions(-) diff --git a/doc/en/conf.py b/doc/en/conf.py index fe1d54416..b0c158e5a 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -38,6 +38,7 @@ release = ".".join(version.split(".")[:2]) autodoc_member_order = "bysource" autodoc_typehints = "description" +autodoc_typehints_description_target = "documented" todo_include_todos = 1 latex_engine = "lualatex" diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index de11cba55..97afdef37 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -102,7 +102,7 @@ pytest.deprecated_call **Tutorial**: :ref:`ensuring_function_triggers` -.. autofunction:: pytest.deprecated_call() +.. autofunction:: pytest.deprecated_call([match]) :with: pytest.register_assert_rewrite diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index 5c971bb86..a46e58136 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -53,7 +53,7 @@ def register_assert_rewrite(*names: str) -> None: actually imported, usually in your __init__.py if you are a plugin using a package. - :raises TypeError: If the given module names are not strings. + :param names: The module names to register. """ for name in names: if not isinstance(name, str): diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index feae1ce7e..d3f01916b 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -66,14 +66,15 @@ class Parser: ) -> "OptionGroup": """Get (or create) a named option Group. - :name: Name of the option group. - :description: Long description for --help output. - :after: Name of another group, used for ordering --help output. + :param name: Name of the option group. + :param description: Long description for --help output. + :param after: Name of another group, used for ordering --help output. + :returns: The option group. The returned group object has an ``addoption`` method with the same signature as :func:`parser.addoption ` but will be shown in the respective group in the output of - ``pytest. --help``. + ``pytest --help``. """ for group in self._groups: if group.name == name: @@ -89,10 +90,11 @@ class Parser: def addoption(self, *opts: str, **attrs: Any) -> None: """Register a command line option. - :opts: Option names, can be short or long options. - :attrs: Same attributes which the ``add_argument()`` function of the - `argparse library `_ - accepts. + :param opts: + Option names, can be short or long options. + :param attrs: + Same attributes as the argparse library's :py:func:`add_argument() + ` function accepts. After command line parsing, options are available on the pytest config object via ``config.option.NAME`` where ``NAME`` is usually set @@ -148,7 +150,10 @@ class Parser: args: Sequence[Union[str, "os.PathLike[str]"]], namespace: Optional[argparse.Namespace] = None, ) -> argparse.Namespace: - """Parse and return a namespace object with known arguments at this point.""" + """Parse the known arguments at this point. + + :returns: An argparse namespace object. + """ return self.parse_known_and_unknown_args(args, namespace=namespace)[0] def parse_known_and_unknown_args( @@ -156,8 +161,13 @@ class Parser: args: Sequence[Union[str, "os.PathLike[str]"]], namespace: Optional[argparse.Namespace] = None, ) -> Tuple[argparse.Namespace, List[str]]: - """Parse and return a namespace object with known arguments, and - the remaining arguments unknown at this point.""" + """Parse the known arguments at this point, and also return the + remaining unknown arguments. + + :returns: + A tuple containing an argparse namespace object for the known + arguments, and a list of the unknown arguments. + """ optparser = self._getparser() strargs = [os.fspath(x) for x in args] return optparser.parse_known_args(strargs, namespace=namespace) @@ -173,9 +183,9 @@ class Parser: ) -> None: """Register an ini-file option. - :name: + :param name: Name of the ini-variable. - :type: + :param type: Type of the variable. Can be: * ``string``: a string @@ -189,7 +199,7 @@ class Parser: The ``paths`` variable type. Defaults to ``string`` if ``None`` or not passed. - :default: + :param default: Default value if no ini-file option exists but is queried. The value of ini-variables can be retrieved via a call to @@ -354,24 +364,30 @@ class OptionGroup: self.options: List[Argument] = [] self.parser = parser - def addoption(self, *optnames: str, **attrs: Any) -> None: + def addoption(self, *opts: str, **attrs: Any) -> None: """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``. + + :param opts: + Option names, can be short or long options. + :param attrs: + Same attributes as the argparse library's :py:func:`add_argument() + ` function accepts. """ - conflict = set(optnames).intersection( + conflict = set(opts).intersection( name for opt in self.options for name in opt.names() ) if conflict: raise ValueError("option names %s already added" % conflict) - option = Argument(*optnames, **attrs) + option = Argument(*opts, **attrs) self._addoption_instance(option, shortupper=False) - def _addoption(self, *optnames: str, **attrs: Any) -> None: - option = Argument(*optnames, **attrs) + def _addoption(self, *opts: str, **attrs: Any) -> None: + option = Argument(*opts, **attrs) self._addoption_instance(option, shortupper=True) def _addoption_instance(self, option: "Argument", shortupper: bool = False) -> None: diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index d1d36d7fa..30b6054d0 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -513,8 +513,8 @@ class FixtureRequest: return self._pyfuncitem.session # type: ignore[no-any-return] def addfinalizer(self, finalizer: Callable[[], object]) -> None: - """Add finalizer/teardown function to be called after the last test - within the requesting test context finished execution.""" + """Add finalizer/teardown function to be called without arguments after + the last test within the requesting test context finished execution.""" # XXX usually this method is shadowed by fixturedef specific ones. self._addfinalizer(finalizer, scope=self.scope) @@ -529,13 +529,16 @@ class FixtureRequest: on all function invocations. :param marker: - A :class:`pytest.MarkDecorator` object created by a call - to ``pytest.mark.NAME(...)``. + An object created by a call to ``pytest.mark.NAME(...)``. """ self.node.add_marker(marker) def raiseerror(self, msg: Optional[str]) -> NoReturn: - """Raise a FixtureLookupError with the given message.""" + """Raise a FixtureLookupError exception. + + :param msg: + An optional custom error message. + """ raise self._fixturemanager.FixtureLookupError(None, self, msg) def _fillfixtures(self) -> None: @@ -557,6 +560,8 @@ class FixtureRequest: phase, but during the test teardown phase a fixture's value may not be available. + :param argname: + The fixture name. :raises pytest.FixtureLookupError: If the given fixture could not be found. """ @@ -768,8 +773,8 @@ class SubRequest(FixtureRequest): return f"" def addfinalizer(self, finalizer: Callable[[], object]) -> None: - """Add finalizer/teardown function to be called after the last test - within the requesting test context finished execution.""" + """Add finalizer/teardown function to be called without arguments after + the last test within the requesting test context finished execution.""" self._fixturedef.addfinalizer(finalizer) def _schedule_finalizers( diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index a03c0e9ab..cc0828dd1 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -143,7 +143,7 @@ def pytest_configure(config: "Config") -> None: def pytest_cmdline_parse( pluginmanager: "PytestPluginManager", args: List[str] ) -> Optional["Config"]: - """Return an initialized config object, parsing the specified args. + """Return an initialized :class:`~pytest.Config`, parsing the specified args. Stops at first non-None result, see :ref:`firstresult`. @@ -152,8 +152,9 @@ def pytest_cmdline_parse( ``plugins`` arg when using `pytest.main`_ to perform an in-process test run. - :param pytest.PytestPluginManager pluginmanager: The pytest plugin manager. - :param List[str] args: List of arguments passed on the command line. + :param pluginmanager: The pytest plugin manager. + :param args: List of arguments passed on the command line. + :returns: A pytest config object. """ @@ -167,8 +168,8 @@ def pytest_cmdline_preparse(config: "Config", args: List[str]) -> None: .. note:: This hook will not be called for ``conftest.py`` files, only for setuptools plugins. - :param pytest.Config config: The pytest config object. - :param List[str] args: Arguments passed on the command line. + :param config: The pytest config object. + :param args: Arguments passed on the command line. """ @@ -179,7 +180,8 @@ def pytest_cmdline_main(config: "Config") -> Optional[Union["ExitCode", int]]: Stops at first non-None result, see :ref:`firstresult`. - :param pytest.Config config: The pytest config object. + :param config: The pytest config object. + :returns: The exit code. """ @@ -192,9 +194,9 @@ def pytest_load_initial_conftests( .. note:: This hook will not be called for ``conftest.py`` files, only for setuptools plugins. - :param pytest.Config early_config: The pytest config object. - :param List[str] args: Arguments passed on the command line. - :param pytest.Parser parser: To add command line options. + :param early_config: The pytest config object. + :param args: Arguments passed on the command line. + :param parser: To add command line options. """ @@ -236,7 +238,7 @@ def pytest_collection(session: "Session") -> Optional[object]: for example the terminal plugin uses it to start displaying the collection counter (and returns `None`). - :param pytest.Session session: The pytest session object. + :param session: The pytest session object. """ @@ -246,16 +248,16 @@ def pytest_collection_modifyitems( """Called after collection has been performed. May filter or re-order the items in-place. - :param pytest.Session session: The pytest session object. - :param pytest.Config config: The pytest config object. - :param List[pytest.Item] items: List of item objects. + :param session: The pytest session object. + :param config: The pytest config object. + :param items: List of item objects. """ def pytest_collection_finish(session: "Session") -> None: """Called after collection has been performed and modified. - :param pytest.Session session: The pytest session object. + :param session: The pytest session object. """ @@ -270,9 +272,9 @@ def pytest_ignore_collect( Stops at first non-None result, see :ref:`firstresult`. - :param pathlib.Path collection_path : The path to analyze. - :param LEGACY_PATH path: The path to analyze (deprecated). - :param pytest.Config config: The pytest config object. + :param collection_path: The path to analyze. + :param path: The path to analyze (deprecated). + :param config: The pytest config object. .. versionchanged:: 7.0.0 The ``collection_path`` parameter was added as a :class:`pathlib.Path` @@ -284,12 +286,12 @@ def pytest_ignore_collect( def pytest_collect_file( file_path: Path, path: "LEGACY_PATH", parent: "Collector" ) -> "Optional[Collector]": - """Create a Collector for the given path, or None if not relevant. + """Create a :class:`~pytest.Collector` for the given path, or None if not relevant. The new node needs to have the specified ``parent`` as a parent. - :param pathlib.Path file_path: The path to analyze. - :param LEGACY_PATH path: The path to collect (deprecated). + :param file_path: The path to analyze. + :param path: The path to collect (deprecated). .. versionchanged:: 7.0.0 The ``file_path`` parameter was added as a :class:`pathlib.Path` @@ -302,21 +304,36 @@ def pytest_collect_file( def pytest_collectstart(collector: "Collector") -> None: - """Collector starts collecting.""" + """Collector starts collecting. + + :param collector: + The collector. + """ def pytest_itemcollected(item: "Item") -> None: - """We just collected a test item.""" + """We just collected a test item. + + :param item: + The item. + """ def pytest_collectreport(report: "CollectReport") -> None: - """Collector finished collecting.""" + """Collector finished collecting. + + :param report: + The collect report. + """ def pytest_deselected(items: Sequence["Item"]) -> None: """Called for deselected test items, e.g. by keyword. May be called multiple times. + + :param items: + The items. """ @@ -326,6 +343,9 @@ def pytest_make_collect_report(collector: "Collector") -> "Optional[CollectRepor a :class:`~pytest.CollectReport`. Stops at first non-None result, see :ref:`firstresult`. + + :param collector: + The collector. """ @@ -338,16 +358,16 @@ def pytest_make_collect_report(collector: "Collector") -> "Optional[CollectRepor def pytest_pycollect_makemodule( module_path: Path, path: "LEGACY_PATH", parent ) -> Optional["Module"]: - """Return a Module collector or None for the given path. + """Return a :class:`pytest.Module` collector or None for the given path. This hook will be called for each matching test module path. - The pytest_collect_file hook needs to be used if you want to + The :hook:`pytest_collect_file` hook needs to be used if you want to create test modules for files that do not match as a test module. Stops at first non-None result, see :ref:`firstresult`. - :param pathlib.Path module_path: The path of the module to collect. - :param LEGACY_PATH path: The path of the module to collect (deprecated). + :param module_path: The path of the module to collect. + :param path: The path of the module to collect (deprecated). .. versionchanged:: 7.0.0 The ``module_path`` parameter was added as a :class:`pathlib.Path` @@ -364,6 +384,15 @@ def pytest_pycollect_makeitem( """Return a custom item/collector for a Python object in a module, or None. Stops at first non-None result, see :ref:`firstresult`. + + :param collector: + The module/class collector. + :param name: + The name of the object in the module/class. + :param obj: + The object. + :returns: + The created items/collectors. """ @@ -372,11 +401,18 @@ def pytest_pyfunc_call(pyfuncitem: "Function") -> Optional[object]: """Call underlying test function. Stops at first non-None result, see :ref:`firstresult`. + + :param pyfuncitem: + The function item. """ def pytest_generate_tests(metafunc: "Metafunc") -> None: - """Generate (multiple) parametrized calls to a test function.""" + """Generate (multiple) parametrized calls to a test function. + + :param metafunc: + The :class:`~pytest.Metafunc` helper for the test function. + """ @hookspec(firstresult=True) @@ -391,7 +427,7 @@ def pytest_make_parametrize_id( Stops at first non-None result, see :ref:`firstresult`. - :param pytest.Config config: The pytest config object. + :param config: The pytest config object. :param val: The parametrized value. :param str argname: The automatic parameter name produced by pytest. """ @@ -416,7 +452,7 @@ def pytest_runtestloop(session: "Session") -> Optional[object]: If at any point ``session.shouldfail`` or ``session.shouldstop`` are set, the loop is terminated after the runtest protocol for the current item is finished. - :param pytest.Session session: The pytest session object. + :param session: The pytest session object. Stops at first non-None result, see :ref:`firstresult`. The return value is not used, but only stops further processing. @@ -468,7 +504,7 @@ def pytest_runtest_logstart( See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. - :param str nodeid: Full node ID of the item. + :param nodeid: Full node ID of the item. :param location: A tuple of ``(filename, lineno, testname)``. """ @@ -480,7 +516,7 @@ def pytest_runtest_logfinish( See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. - :param str nodeid: Full node ID of the item. + :param nodeid: Full node ID of the item. :param location: A tuple of ``(filename, lineno, testname)``. """ @@ -492,6 +528,9 @@ def pytest_runtest_setup(item: "Item") -> None: parents (which haven't been setup yet). This includes obtaining the values of fixtures required by the item (which haven't been obtained yet). + + :param item: + The item. """ @@ -499,6 +538,9 @@ def pytest_runtest_call(item: "Item") -> None: """Called to run the test for test item (the call phase). The default implementation calls ``item.runtest()``. + + :param item: + The item. """ @@ -510,6 +552,8 @@ def pytest_runtest_teardown(item: "Item", nextitem: Optional["Item"]) -> None: includes running the teardown phase of fixtures required by the item (if they go out of scope). + :param item: + The item. :param nextitem: The scheduled-to-be-next test item (None if no further test item is scheduled). This argument is used to perform exact teardowns, i.e. @@ -527,6 +571,7 @@ def pytest_runtest_makereport( See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. + :param item: The item. :param call: The :class:`~pytest.CallInfo` for the phase. Stops at first non-None result, see :ref:`firstresult`. @@ -547,7 +592,11 @@ def pytest_report_to_serializable( report: Union["CollectReport", "TestReport"], ) -> Optional[Dict[str, Any]]: """Serialize the given report object into a data structure suitable for - sending over the wire, e.g. converted to JSON.""" + sending over the wire, e.g. converted to JSON. + + :param config: The pytest config object. + :param report: The report. + """ @hookspec(firstresult=True) @@ -556,7 +605,10 @@ def pytest_report_from_serializable( data: Dict[str, Any], ) -> Optional[Union["CollectReport", "TestReport"]]: """Restore a report object previously serialized with - :hook:`pytest_report_to_serializable`.""" + :hook:`pytest_report_to_serializable`. + + :param config: The pytest config object. + """ # ------------------------------------------------------------------------- @@ -570,7 +622,12 @@ def pytest_fixture_setup( ) -> Optional[object]: """Perform fixture setup execution. - :returns: The return value of the call to the fixture function. + :param fixturdef: + The fixture definition object. + :param request: + The fixture request object. + :returns: + The return value of the call to the fixture function. Stops at first non-None result, see :ref:`firstresult`. @@ -586,7 +643,13 @@ def pytest_fixture_post_finalizer( ) -> None: """Called after fixture teardown, but before the cache is cleared, so the fixture result ``fixturedef.cached_result`` is still available (not - ``None``).""" + ``None``). + + :param fixturdef: + The fixture definition object. + :param request: + The fixture request object. + """ # ------------------------------------------------------------------------- @@ -598,7 +661,7 @@ def pytest_sessionstart(session: "Session") -> None: """Called after the ``Session`` object has been created and before performing collection and entering the run test loop. - :param pytest.Session session: The pytest session object. + :param session: The pytest session object. """ @@ -608,15 +671,15 @@ def pytest_sessionfinish( ) -> None: """Called after whole test run finished, right before returning the exit status to the system. - :param pytest.Session session: The pytest session object. - :param int exitstatus: The status which pytest will return to the system. + :param session: The pytest session object. + :param exitstatus: The status which pytest will return to the system. """ def pytest_unconfigure(config: "Config") -> None: """Called before test process is exited. - :param pytest.Config config: The pytest config object. + :param config: The pytest config object. """ @@ -635,7 +698,10 @@ def pytest_assertrepr_compare( *in* a string will be escaped. Note that all but the first line will be indented slightly, the intention is for the first line to be a summary. - :param pytest.Config config: The pytest config object. + :param config: The pytest config object. + :param op: The operator, e.g. `"=="`, `"!="`, `"not in"`. + :param left: The left operand. + :param right: The right operand. """ @@ -660,10 +726,10 @@ def pytest_assertion_pass(item: "Item", lineno: int, orig: str, expl: str) -> No You need to **clean the .pyc** files in your project directory and interpreter libraries when enabling this option, as assertions will require to be re-written. - :param pytest.Item item: pytest item object of current test. - :param int lineno: Line number of the assert statement. - :param str orig: String with the original assertion. - :param str expl: String with the assert explanation. + :param item: pytest item object of current test. + :param lineno: Line number of the assert statement. + :param orig: String with the original assertion. + :param expl: String with the assert explanation. """ @@ -677,9 +743,9 @@ def pytest_report_header( ) -> Union[str, List[str]]: """Return a string or list of strings to be displayed as header info for terminal reporting. - :param pytest.Config config: The pytest config object. - :param Path start_path: The starting dir. - :param LEGACY_PATH startdir: The starting dir (deprecated). + :param config: The pytest config object. + :param start_path: The starting dir. + :param startdir: The starting dir (deprecated). .. note:: @@ -714,9 +780,9 @@ def pytest_report_collectionfinish( .. versionadded:: 3.2 - :param pytest.Config config: The pytest config object. - :param Path start_path: The starting dir. - :param LEGACY_PATH startdir: The starting dir (deprecated). + :param config: The pytest config object. + :param start_path: The starting dir. + :param startdir: The starting dir (deprecated). :param items: List of pytest items that are going to be executed; this list should not be modified. .. note:: @@ -755,6 +821,7 @@ def pytest_report_teststatus( :param report: The report object whose status is to be returned. :param config: The pytest config object. + :returns: The test status. Stops at first non-None result, see :ref:`firstresult`. """ @@ -767,9 +834,9 @@ def pytest_terminal_summary( ) -> None: """Add a section to terminal summary reporting. - :param _pytest.terminal.TerminalReporter terminalreporter: The internal terminal reporter object. - :param int exitstatus: The exit status that will be reported back to the OS. - :param pytest.Config config: The pytest config object. + :param terminalreporter: The internal terminal reporter object. + :param exitstatus: The exit status that will be reported back to the OS. + :param config: The pytest config object. .. versionadded:: 4.2 The ``config`` parameter. @@ -785,21 +852,21 @@ def pytest_warning_recorded( ) -> None: """Process a warning captured by the internal pytest warnings plugin. - :param warnings.WarningMessage warning_message: + :param warning_message: The captured warning. This is the same object produced by :py:func:`warnings.catch_warnings`, and contains the same attributes as the parameters of :py:func:`warnings.showwarning`. - :param str when: + :param when: Indicates when the warning was captured. Possible values: * ``"config"``: during pytest configuration/initialization stage. * ``"collect"``: during test collection. * ``"runtest"``: during test execution. - :param str nodeid: + :param nodeid: Full id of the item. - :param tuple|None location: + :param location: When available, holds information about the execution context of the captured warning (filename, linenumber, function). ``function`` evaluates to when the execution context is at the module level. @@ -824,7 +891,7 @@ def pytest_markeval_namespace(config: "Config") -> Dict[str, Any]: .. versionadded:: 6.2 - :param pytest.Config config: The pytest config object. + :param config: The pytest config object. :returns: A dictionary of additional globals to add. """ @@ -842,13 +909,19 @@ def pytest_internalerror( Return True to suppress the fallback handling of printing an INTERNALERROR message directly to sys.stderr. + + :param excrepr: The exception repr object. + :param excinfo: The exception info. """ def pytest_keyboard_interrupt( excinfo: "ExceptionInfo[Union[KeyboardInterrupt, Exit]]", ) -> None: - """Called for keyboard interrupt.""" + """Called for keyboard interrupt. + + :param excinfo: The exception info. + """ def pytest_exception_interact( @@ -867,6 +940,13 @@ def pytest_exception_interact( This hook is not called if the exception that was raised is an internal exception like ``skip.Exception``. + + :param node: + The item or collector. + :param call: + The call information. Contains the exception. + :param report: + The collection or test report. """ @@ -876,8 +956,8 @@ def pytest_enter_pdb(config: "Config", pdb: "pdb.Pdb") -> None: Can be used by plugins to take special action just before the python debugger enters interactive mode. - :param pytest.Config config: The pytest config object. - :param pdb.Pdb pdb: The Pdb instance. + :param config: The pytest config object. + :param pdb: The Pdb instance. """ @@ -887,6 +967,6 @@ def pytest_leave_pdb(config: "Config", pdb: "pdb.Pdb") -> None: Can be used by plugins to take special action just after the python debugger leaves interactive mode. - :param pytest.Config config: The pytest config object. - :param pdb.Pdb pdb: The Pdb instance. + :param config: The pytest config object. + :param pdb: The Pdb instance. """ diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 66057ef6f..7a5170f32 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -354,7 +354,10 @@ def record_testsuite_property(request: FixtureRequest) -> Callable[[str, object] record_testsuite_property("ARCH", "PPC") record_testsuite_property("STORAGE_TYPE", "CEPH") - ``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped. + :param name: + The property name. + :param value: + The property value. Will be converted to a string. .. warning:: diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 2eb69fdbf..f9091399f 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -37,6 +37,8 @@ from _pytest.terminal import TerminalReporter if TYPE_CHECKING: logging_StreamHandler = logging.StreamHandler[StringIO] + + from typing_extensions import Literal else: logging_StreamHandler = logging.StreamHandler @@ -382,20 +384,19 @@ class LogCaptureFixture: @property def handler(self) -> LogCaptureHandler: - """Get the logging handler used by the fixture. - - :rtype: LogCaptureHandler - """ + """Get the logging handler used by the fixture.""" return self._item.stash[caplog_handler_key] - def get_records(self, when: str) -> List[logging.LogRecord]: + def get_records( + self, when: "Literal['setup', 'call', 'teardown']" + ) -> List[logging.LogRecord]: """Get the logging records for one of the possible test phases. - :param str when: - Which test phase to obtain the records from. Valid values are: "setup", "call" and "teardown". + :param when: + Which test phase to obtain the records from. + Valid values are: "setup", "call" and "teardown". :returns: The list of captured records at the given stage. - :rtype: List[logging.LogRecord] .. versionadded:: 3.4 """ @@ -452,8 +453,8 @@ class LogCaptureFixture: The levels of the loggers changed by this function will be restored to their initial values at the end of the test. - :param int level: The level. - :param str logger: The logger to update. If not given, the root logger. + :param level: The level. + :param logger: The logger to update. If not given, the root logger. """ logger_obj = logging.getLogger(logger) # Save the original log-level to restore it during teardown. @@ -471,8 +472,8 @@ class LogCaptureFixture: the end of the 'with' statement the level is restored to its original value. - :param int level: The level. - :param str logger: The logger to update. If not given, the root logger. + :param level: The level. + :param logger: The logger to update. If not given, the root logger. """ logger_obj = logging.getLogger(logger) orig_level = logger_obj.level diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index a03f0f89c..6717d1135 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -62,8 +62,8 @@ def param( assert eval(test_input) == expected :param values: Variable args of the values of the parameter set, in order. - :keyword marks: A single mark or a list of marks to be applied to this parameter set. - :keyword str id: The id to attribute to this parameter set. + :param marks: A single mark or a list of marks to be applied to this parameter set. + :param id: The id to attribute to this parameter set. """ return ParameterSet.param(*values, marks=marks, id=id) diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index 91d590fb3..fdb252c5c 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -115,7 +115,7 @@ class MonkeyPatch: Returned by the :fixture:`monkeypatch` fixture. - :versionchanged:: 6.2 + .. versionchanged:: 6.2 Can now also be used directly as `pytest.MonkeyPatch()`, for when the fixture is not available. In this case, use :meth:`with MonkeyPatch.context() as mp: ` or remember to call @@ -338,7 +338,8 @@ class MonkeyPatch: def chdir(self, path: Union[str, "os.PathLike[str]"]) -> None: """Change the current working directory to the specified path. - Path can be a string or a path object. + :param path: + The path to change into. """ if self._cwd is None: self._cwd = os.getcwd() diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 1a168043a..cfb9b5a36 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -193,7 +193,7 @@ class Node(metaclass=NodeMeta): nodeid: Optional[str] = None, ) -> None: #: A unique name within the scope of the parent node. - self.name = name + self.name: str = name #: The parent collector node. self.parent = parent @@ -208,7 +208,7 @@ class Node(metaclass=NodeMeta): if session: #: The pytest session this node is part of. - self.session = session + self.session: Session = session else: if not parent: raise TypeError("session or parent must be provided") @@ -239,9 +239,7 @@ class Node(metaclass=NodeMeta): #: A place where plugins can store information on the node for their #: own use. - #: - #: :type: Stash - self.stash = Stash() + self.stash: Stash = Stash() # Deprecated alias. Was never public. Can be removed in a few releases. self._store = self.stash @@ -326,7 +324,10 @@ class Node(metaclass=NodeMeta): def listchain(self) -> List["Node"]: """Return list of all parent collectors up to self, starting from - the root of collection tree.""" + the root of collection tree. + + :returns: The nodes. + """ chain = [] item: Optional[Node] = self while item is not None: @@ -340,6 +341,8 @@ class Node(metaclass=NodeMeta): ) -> None: """Dynamically add a marker object to the node. + :param marker: + The marker. :param append: Whether to append the marker, or prepend it. """ @@ -361,6 +364,7 @@ class Node(metaclass=NodeMeta): """Iterate over all markers of the node. :param name: If given, filter the results by the name attribute. + :returns: An iterator of the markers of the node. """ return (x[1] for x in self.iter_markers_with_node(name=name)) @@ -407,7 +411,8 @@ class Node(metaclass=NodeMeta): return [x.name for x in self.listchain()] def addfinalizer(self, fin: Callable[[], object]) -> None: - """Register a function to be called when this node is finalized. + """Register a function to be called without arguments when this node is + finalized. This method can only be called when this node is active in a setup chain, for example during self.setup(). @@ -416,7 +421,11 @@ class Node(metaclass=NodeMeta): def getparent(self, cls: Type[_NodeType]) -> Optional[_NodeType]: """Get the next parent node (including self) which is an instance of - the given class.""" + the given class. + + :param cls: The node class to search for. + :returns: The node, if found. + """ current: Optional[Node] = self while current and not isinstance(current, cls): current = current.parent diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 684efae77..e46b663dd 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -241,6 +241,9 @@ def xfail(reason: str = "") -> NoReturn: This function should be called only during testing (setup, call or teardown). + :param reason: + The message to show the user as reason for the xfail. + .. note:: It is better to use the :ref:`pytest.mark.xfail ref` marker when possible to declare a test to be xfailed under certain conditions @@ -256,12 +259,12 @@ def importorskip( """Import and return the requested module ``modname``, or skip the current test if the module cannot be imported. - :param str modname: + :param modname: The name of the module to import. - :param str minversion: + :param minversion: If given, the imported module's ``__version__`` attribute must be at least this minimal version, otherwise the test is still skipped. - :param str reason: + :param reason: If given, this reason is shown as the message when the module cannot be imported. diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index d8586a056..a9299944d 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -661,17 +661,7 @@ class Pytester: against expected output, perfect for black-box testing of pytest plugins. It attempts to isolate the test run from external factors as much as possible, modifying - the current working directory to ``path`` and environment variables during initialization. - - Attributes: - - :ivar Path path: temporary directory path used to create files/run tests from, etc. - - :ivar plugins: - A list of plugins to use with :py:meth:`parseconfig` and - :py:meth:`runpytest`. Initially this is an empty list but plugins can - be added to the list. The type of items to add to the list depends on - the method using them so refer to them for details. + the current working directory to :attr:`path` and environment variables during initialization. """ __test__ = False @@ -700,6 +690,10 @@ class Pytester: name = request.node.name self._name = name self._path: Path = tmp_path_factory.mktemp(name, numbered=True) + #: A list of plugins to use with :py:meth:`parseconfig` and + #: :py:meth:`runpytest`. Initially this is an empty list but plugins can + #: be added to the list. The type of items to add to the list depends on + #: the method using them so refer to them for details. self.plugins: List[Union[str, _PluggyPlugin]] = [] self._cwd_snapshot = CwdSnapshot() self._sys_path_snapshot = SysPathsSnapshot() @@ -724,7 +718,7 @@ class Pytester: @property def path(self) -> Path: - """Temporary directory where files are created and pytest is executed.""" + """Temporary directory path used to create files/run tests from, etc.""" return self._path def __repr__(self) -> str: @@ -755,7 +749,7 @@ class Pytester: return SysModulesSnapshot(preserve=preserve_module) def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder: - """Create a new :py:class:`HookRecorder` for a PluginManager.""" + """Create a new :class:`HookRecorder` for a :class:`PytestPluginManager`.""" pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True) self._request.addfinalizer(reprec.finish_recording) return reprec @@ -804,7 +798,7 @@ class Pytester: def makefile(self, ext: str, *args: str, **kwargs: str) -> Path: r"""Create new text file(s) in the test directory. - :param str ext: + :param ext: The extension the file(s) should use, including the dot, e.g. `.py`. :param args: All args are treated as strings and joined using newlines. @@ -813,6 +807,8 @@ class Pytester: :param kwargs: Each keyword is the name of a file, while the value of it will be written as contents of the file. + :returns: + The first created file. Examples: @@ -832,11 +828,19 @@ class Pytester: return self._makefile(ext, args, kwargs) def makeconftest(self, source: str) -> Path: - """Write a conftest.py file with 'source' as contents.""" + """Write a contest.py file. + + :param source: The contents. + :returns: The conftest.py file. + """ return self.makepyfile(conftest=source) def makeini(self, source: str) -> Path: - """Write a tox.ini file with 'source' as contents.""" + """Write a tox.ini file. + + :param source: The contents. + :returns: The tox.ini file. + """ return self.makefile(".ini", tox=source) def getinicfg(self, source: str) -> SectionWrapper: @@ -845,7 +849,10 @@ class Pytester: return IniConfig(str(p))["pytest"] def makepyprojecttoml(self, source: str) -> Path: - """Write a pyproject.toml file with 'source' as contents. + """Write a pyproject.toml file. + + :param source: The contents. + :returns: The pyproject.ini file. .. versionadded:: 6.0 """ @@ -898,6 +905,9 @@ class Pytester: This is undone automatically when this object dies at the end of each test. + + :param path: + The path. """ if path is None: path = self.path @@ -905,7 +915,13 @@ class Pytester: self._monkeypatch.syspath_prepend(str(path)) def mkdir(self, name: Union[str, "os.PathLike[str]"]) -> Path: - """Create a new (sub)directory.""" + """Create a new (sub)directory. + + :param name: + The name of the directory, relative to the pytester path. + :returns: + The created directory. + """ p = self.path / name p.mkdir() return p @@ -924,14 +940,15 @@ class Pytester: def copy_example(self, name: Optional[str] = None) -> Path: """Copy file from project's directory into the testdir. - :param str name: The name of the file to copy. - :return: path to the copied directory (inside ``self.path``). - + :param name: + The name of the file to copy. + :return: + Path to the copied directory (inside ``self.path``). """ - example_dir = self._request.config.getini("pytester_example_dir") - if example_dir is None: + example_dir_ = self._request.config.getini("pytester_example_dir") + if example_dir_ is None: raise ValueError("pytester_example_dir is unset, can't copy examples") - example_dir = self._request.config.rootpath / example_dir + example_dir: Path = self._request.config.rootpath / example_dir_ for extra_element in self._request.node.iter_markers("pytester_example_path"): assert extra_element.args @@ -967,14 +984,16 @@ class Pytester: def getnode( self, config: Config, arg: Union[str, "os.PathLike[str]"] - ) -> Optional[Union[Collector, Item]]: - """Return the collection node of a file. + ) -> Union[Collector, Item]: + """Get the collection node of a file. - :param pytest.Config config: + :param config: A pytest config. See :py:meth:`parseconfig` and :py:meth:`parseconfigure` for creating it. - :param os.PathLike[str] arg: + :param arg: Path to the file. + :returns: + The node. """ session = Session.from_config(config) assert "::" not in str(arg) @@ -984,13 +1003,18 @@ class Pytester: config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK) return res - def getpathnode(self, path: Union[str, "os.PathLike[str]"]): + def getpathnode( + self, path: Union[str, "os.PathLike[str]"] + ) -> Union[Collector, Item]: """Return the collection node of a file. This is like :py:meth:`getnode` but uses :py:meth:`parseconfigure` to create the (configured) pytest Config instance. - :param os.PathLike[str] path: Path to the file. + :param path: + Path to the file. + :returns: + The node. """ path = Path(path) config = self.parseconfigure(path) @@ -1006,6 +1030,11 @@ class Pytester: This recurses into the collection node and returns a list of all the test items contained within. + + :param colitems: + The collection nodes. + :returns: + The collected items. """ session = colitems[0].session result: List[Item] = [] @@ -1192,15 +1221,16 @@ class Pytester: return new_args def parseconfig(self, *args: Union[str, "os.PathLike[str]"]) -> Config: - """Return a new pytest Config instance from given commandline args. + """Return a new pytest :class:`pytest.Config` instance from given + commandline args. - This invokes the pytest bootstrapping code in _pytest.config to create - a new :py:class:`_pytest.core.PluginManager` and call the - pytest_cmdline_parse hook to create a new - :py:class:`pytest.Config` instance. + This invokes the pytest bootstrapping code in _pytest.config to create a + new :py:class:`pytest.PytestPluginManager` and call the + :hook:`pytest_cmdline_parse` hook to create a new :class:`pytest.Config` + instance. - If :py:attr:`plugins` has been populated they should be plugin modules - to be registered with the PluginManager. + If :attr:`plugins` has been populated they should be plugin modules + to be registered with the plugin manager. """ import _pytest.config @@ -1218,7 +1248,8 @@ class Pytester: """Return a new pytest configured Config instance. Returns a new :py:class:`pytest.Config` instance like - :py:meth:`parseconfig`, but also calls the pytest_configure hook. + :py:meth:`parseconfig`, but also calls the :hook:`pytest_configure` + hook. """ config = self.parseconfig(*args) config._do_configure() @@ -1237,6 +1268,8 @@ class Pytester: The module source. :param funcname: The name of the test function for which to return a test item. + :returns: + The test item. """ items = self.getitems(source) for item in items: @@ -1377,6 +1410,8 @@ class Pytester: - Otherwise, it is passed through to :py:class:`subprocess.Popen`. For further information in this case, consult the document of the ``stdin`` parameter in :py:class:`subprocess.Popen`. + :returns: + The result. """ __tracebackhide__ = True @@ -1463,6 +1498,8 @@ class Pytester: :param timeout: The period in seconds after which to timeout and raise :py:class:`Pytester.TimeoutExpired`. + :returns: + The result. """ __tracebackhide__ = True p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700) diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index d825931de..00e377f40 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -798,15 +798,18 @@ def raises( def raises( expected_exception: Union[Type[E], Tuple[Type[E], ...]], *args: Any, **kwargs: Any ) -> Union["RaisesContext[E]", _pytest._code.ExceptionInfo[E]]: - r"""Assert that a code block/function call raises ``expected_exception`` - or raise a failure exception otherwise. + r"""Assert that a code block/function call raises an exception. - :kwparam match: + :param typing.Type[E] | typing.Tuple[typing.Type[E], ...] expected_exception: + The excpected exception type, or a tuple if one of multiple possible + exception types are excepted. + :kwparam str | typing.Pattern[str] | None match: If specified, a string containing a regular expression, or a regular expression object, that is tested against the string - representation of the exception using :py:func:`re.search`. To match a literal - string that may contain :std:ref:`special characters `, the pattern can - first be escaped with :py:func:`re.escape`. + representation of the exception using :func:`re.search`. + + To match a literal string that may contain :ref:`special characters + `, the pattern can first be escaped with :func:`re.escape`. (This is only used when :py:func:`pytest.raises` is used as a context manager, and passed through to the function otherwise. diff --git a/src/_pytest/reports.py b/src/_pytest/reports.py index 20862d603..c35f7087e 100644 --- a/src/_pytest/reports.py +++ b/src/_pytest/reports.py @@ -276,7 +276,7 @@ class TestReport(BaseReport): #: A name -> value dictionary containing all keywords and #: markers associated with a test invocation. - self.keywords = keywords + self.keywords: Mapping[str, Any] = keywords #: Test outcome, always one of "passed", "failed", "skipped". self.outcome = outcome @@ -298,7 +298,7 @@ class TestReport(BaseReport): self.sections = list(sections) #: Time it took to run just the test. - self.duration = duration + self.duration: float = duration self.__dict__.update(extra) @@ -309,7 +309,11 @@ class TestReport(BaseReport): @classmethod def from_item_and_call(cls, item: Item, call: "CallInfo[None]") -> "TestReport": - """Create and fill a TestReport with standard item and call info.""" + """Create and fill a TestReport with standard item and call info. + + :param item: The item. + :param call: The call info. + """ when = call.when # Remove "collect" from the Literal type -- only for collection calls. assert when != "collect" diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 12dc463a2..9497a0d49 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -100,7 +100,11 @@ class TempPathFactory: return p def getbasetemp(self) -> Path: - """Return the base temporary directory, creating it if needed.""" + """Return the base temporary directory, creating it if needed. + + :returns: + The base temporary directory. + """ if self._basetemp is not None: return self._basetemp From beae7fd0ba063dd8ef980e15d66286a584aebc97 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sat, 13 Aug 2022 21:04:59 +0300 Subject: [PATCH 3/3] doc: workaround for ugly API docs for overloaded functions with new Sphinx New Sphinx added support for overloads and always displays them all with full type annotations etc. This regresses the API reference for overloaded functions like `fixture()`, `warns()`, `raises()` and friends to become impossible to read. I tried various workarounds but none worked except this one. --- src/_pytest/compat.py | 11 ++++++++++- src/_pytest/fixtures.py | 6 +++--- src/_pytest/main.py | 6 +++--- src/_pytest/python_api.py | 6 +++--- src/_pytest/recwarn.py | 12 +++++++----- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index d0cb07b22..fab4c3110 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -20,6 +20,16 @@ from typing import Union import attr import py +# fmt: off +# Workaround for https://github.com/sphinx-doc/sphinx/issues/10351. +# If `overload` is imported from `compat` instead of from `typing`, +# Sphinx doesn't recognize it as `overload` and the API docs for +# overloaded functions look good again. But type checkers handle +# it fine. +# fmt: on +if True: + from typing import overload as overload + if TYPE_CHECKING: from typing_extensions import Final @@ -345,7 +355,6 @@ else: if sys.version_info >= (3, 8): from functools import cached_property as cached_property else: - from typing import overload from typing import Type class cached_property(Generic[_S, _T]): diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 30b6054d0..d79895c26 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -20,7 +20,6 @@ from typing import List from typing import MutableMapping from typing import NoReturn from typing import Optional -from typing import overload from typing import Sequence from typing import Set from typing import Tuple @@ -48,6 +47,7 @@ from _pytest.compat import getimfunc from _pytest.compat import getlocation from _pytest.compat import is_generator from _pytest.compat import NOTSET +from _pytest.compat import overload from _pytest.compat import safe_getattr from _pytest.config import _PluggyPlugin from _pytest.config import Config @@ -1231,7 +1231,7 @@ def fixture( @overload -def fixture( +def fixture( # noqa: F811 fixture_function: None = ..., *, scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ..., @@ -1245,7 +1245,7 @@ def fixture( ... -def fixture( +def fixture( # noqa: F811 fixture_function: Optional[FixtureFunction] = None, *, scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = "function", diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 4a117fc2e..61fb7eaa4 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -12,7 +12,6 @@ from typing import FrozenSet from typing import Iterator from typing import List from typing import Optional -from typing import overload from typing import Sequence from typing import Set from typing import Tuple @@ -25,6 +24,7 @@ import attr import _pytest._code from _pytest import nodes from _pytest.compat import final +from _pytest.compat import overload from _pytest.config import Config from _pytest.config import directory_arg from _pytest.config import ExitCode @@ -597,12 +597,12 @@ class Session(nodes.FSCollector): ... @overload - def perform_collect( + def perform_collect( # noqa: F811 self, args: Optional[Sequence[str]] = ..., genitems: bool = ... ) -> Sequence[Union[nodes.Item, nodes.Collector]]: ... - def perform_collect( + def perform_collect( # noqa: F811 self, args: Optional[Sequence[str]] = None, genitems: bool = True ) -> Sequence[Union[nodes.Item, nodes.Collector]]: """Perform the collection phase for this session. diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 00e377f40..515d437f0 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -12,7 +12,6 @@ from typing import Generic from typing import List from typing import Mapping from typing import Optional -from typing import overload from typing import Pattern from typing import Sequence from typing import Tuple @@ -28,6 +27,7 @@ if TYPE_CHECKING: import _pytest._code from _pytest.compat import final from _pytest.compat import STRING_TYPES +from _pytest.compat import overload from _pytest.outcomes import fail @@ -786,7 +786,7 @@ def raises( @overload -def raises( +def raises( # noqa: F811 expected_exception: Union[Type[E], Tuple[Type[E], ...]], func: Callable[..., Any], *args: Any, @@ -795,7 +795,7 @@ def raises( ... -def raises( +def raises( # noqa: F811 expected_exception: Union[Type[E], Tuple[Type[E], ...]], *args: Any, **kwargs: Any ) -> Union["RaisesContext[E]", _pytest._code.ExceptionInfo[E]]: r"""Assert that a code block/function call raises an exception. diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 9c6e7e91d..9971bb52f 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -9,7 +9,6 @@ from typing import Generator from typing import Iterator from typing import List from typing import Optional -from typing import overload from typing import Pattern from typing import Tuple from typing import Type @@ -17,6 +16,7 @@ from typing import TypeVar from typing import Union from _pytest.compat import final +from _pytest.compat import overload from _pytest.deprecated import check_ispytest from _pytest.deprecated import WARNS_NONE_ARG from _pytest.fixtures import fixture @@ -47,11 +47,13 @@ def deprecated_call( @overload -def deprecated_call(func: Callable[..., T], *args: Any, **kwargs: Any) -> T: +def deprecated_call( # noqa: F811 + func: Callable[..., T], *args: Any, **kwargs: Any +) -> T: ... -def deprecated_call( +def deprecated_call( # noqa: F811 func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any ) -> Union["WarningsRecorder", Any]: """Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``. @@ -93,7 +95,7 @@ def warns( @overload -def warns( +def warns( # noqa: F811 expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]], func: Callable[..., T], *args: Any, @@ -102,7 +104,7 @@ def warns( ... -def warns( +def warns( # noqa: F811 expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning, *args: Any, match: Optional[Union[str, Pattern[str]]] = None,