Merge branch 'main' into main

This commit is contained in:
Warren Markham 2023-09-11 02:49:17 +10:00 committed by GitHub
commit 4ac59d8b53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 220 additions and 137 deletions

View File

@ -36,8 +36,10 @@ jobs:
timeout-minutes: 30
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v3
- name: Download Package
uses: actions/download-artifact@v3
with:

View File

@ -235,6 +235,7 @@ Maho
Maik Figura
Mandeep Bhutani
Manuel Krebber
Marc Mueller
Marc Schlaich
Marcelo Duarte Trevisani
Marcin Bachry

View File

@ -134,7 +134,8 @@ Releasing
Both automatic and manual processes described above follow the same steps from this point onward.
#. After all tests pass and the PR has been approved, trigger the ``deploy`` job
in https://github.com/pytest-dev/pytest/actions/workflows/deploy.yml.
in https://github.com/pytest-dev/pytest/actions/workflows/deploy.yml, using the ``release-MAJOR.MINOR.PATCH`` branch
as source.
This job will require approval from ``pytest-dev/core``, after which it will publish to PyPI
and tag the repository.

View File

@ -0,0 +1 @@
Fixed ``:=`` in asserts impacting unrelated test cases.

View File

@ -27,7 +27,7 @@ please refer to `the update script <https://github.com/pytest-dev/pytest/blob/ma
creating a PDF, because otherwise the table gets far too wide for the
page.
This list contains 1315 plugins.
This list contains 1316 plugins.
.. only:: not latex
@ -50,7 +50,7 @@ This list contains 1315 plugins.
:pypi:`pytest-aio` Pytest plugin for testing async python code Feb 03, 2023 4 - Beta pytest
:pypi:`pytest-aiofiles` pytest fixtures for writing aiofiles tests with pyfakefs May 14, 2017 5 - Production/Stable N/A
:pypi:`pytest-aiogram` May 06, 2023 N/A N/A
:pypi:`pytest-aiohttp` Pytest plugin for aiohttp support Feb 12, 2022 4 - Beta pytest (>=6.1.0)
:pypi:`pytest-aiohttp` Pytest plugin for aiohttp support Sep 06, 2023 4 - Beta pytest >=6.1.0
:pypi:`pytest-aiohttp-client` Pytest \`client\` fixture for the Aiohttp Jan 10, 2023 N/A pytest (>=7.2.0,<8.0.0)
:pypi:`pytest-aiomoto` pytest-aiomoto Jun 24, 2023 N/A pytest (>=7.0,<8.0)
:pypi:`pytest-aioresponses` py.test integration for aioresponses Jul 29, 2021 4 - Beta pytest (>=3.5.0)
@ -66,7 +66,7 @@ This list contains 1315 plugins.
:pypi:`pytest-allure-intersection` Oct 27, 2022 N/A pytest (<5)
:pypi:`pytest-allure-spec-coverage` The pytest plugin aimed to display test coverage of the specs(requirements) in Allure Oct 26, 2021 N/A pytest
:pypi:`pytest-alphamoon` Static code checks used at Alphamoon Dec 30, 2021 5 - Production/Stable pytest (>=3.5.0)
:pypi:`pytest-analyzer` this plugin allows to analyze tests in pytest project, collect test metadata and sync it with testomat.io TCM system Aug 24, 2023 N/A pytest >=7.3.1
:pypi:`pytest-analyzer` this plugin allows to analyze tests in pytest project, collect test metadata and sync it with testomat.io TCM system Sep 05, 2023 N/A pytest >=7.3.1
:pypi:`pytest-android` This fixture provides a configured "driver" for Android Automated Testing, using uiautomator2. Feb 21, 2019 3 - Alpha pytest
:pypi:`pytest-anki` A pytest plugin for testing Anki add-ons Jul 31, 2022 4 - Beta pytest (>=3.5.0)
:pypi:`pytest-annotate` pytest-annotate: Generate PyAnnotate annotations from your pytest tests. Jun 07, 2022 3 - Alpha pytest (<8.0.0,>=3.2.0)
@ -85,7 +85,7 @@ This list contains 1315 plugins.
:pypi:`pytest-appengine` AppEngine integration that works well with pytest-django Feb 27, 2017 N/A N/A
:pypi:`pytest-appium` Pytest plugin for appium Dec 05, 2019 N/A N/A
:pypi:`pytest-approvaltests` A plugin to use approvaltests with pytest May 08, 2022 4 - Beta pytest (>=7.0.1)
:pypi:`pytest-approvaltests-geo` Extension for ApprovalTests.Python specific to geo data verification Mar 04, 2023 5 - Production/Stable pytest
:pypi:`pytest-approvaltests-geo` Extension for ApprovalTests.Python specific to geo data verification Sep 06, 2023 5 - Production/Stable pytest
:pypi:`pytest-archon` Rule your architecture like a real developer Jul 11, 2023 5 - Production/Stable pytest (>=7.2)
:pypi:`pytest-argus` pyest results colection plugin Jun 24, 2021 5 - Production/Stable pytest (>=6.2.4)
:pypi:`pytest-arraydiff` pytest plugin to help with comparing array output from tests Jan 13, 2022 4 - Beta pytest (>=4.6)
@ -244,6 +244,7 @@ This list contains 1315 plugins.
:pypi:`pytest-contextfixture` Define pytest fixtures as context managers. Mar 12, 2013 4 - Beta N/A
:pypi:`pytest-contexts` A plugin to run tests written with the Contexts framework using pytest May 19, 2021 4 - Beta N/A
:pypi:`pytest-cookies` The pytest plugin for your Cookiecutter templates. 🍪 Mar 22, 2023 5 - Production/Stable pytest (>=3.9.0)
:pypi:`pytest-copie` The pytest plugin for your Copier templates. Sep 07, 2023 3 - Alpha pytest
:pypi:`pytest-copier` A pytest plugin to help testing Copier templates Jun 23, 2023 4 - Beta pytest>=7.1.2
:pypi:`pytest-couchdbkit` py.test extension for per-test couchdb databases using couchdbkit Apr 17, 2012 N/A N/A
:pypi:`pytest-count` count erros and send email Jan 12, 2018 4 - Beta N/A
@ -253,7 +254,7 @@ This list contains 1315 plugins.
:pypi:`pytest-coverage-context` Coverage dynamic context support for PyTest, including sub-processes Jun 28, 2023 4 - Beta N/A
:pypi:`pytest-coveragemarkers` Using pytest markers to track functional coverage and filtering of tests Nov 29, 2022 N/A pytest (>=7.1.2,<8.0.0)
:pypi:`pytest-cov-exclude` Pytest plugin for excluding tests based on coverage data Apr 29, 2016 4 - Beta pytest (>=2.8.0,<2.9.0); extra == 'dev'
:pypi:`pytest-cpp` Use pytest's runner to discover and execute C++ tests Jan 30, 2023 5 - Production/Stable pytest (>=7.0)
:pypi:`pytest-cpp` Use pytest's runner to discover and execute C++ tests Sep 08, 2023 5 - Production/Stable pytest >=7.0
:pypi:`pytest-cppython` A pytest plugin that imports CPPython testing types Aug 26, 2023 N/A N/A
:pypi:`pytest-cqase` Custom qase pytest plugin Aug 22, 2022 N/A pytest (>=7.1.2,<8.0.0)
:pypi:`pytest-cram` Run cram tests with pytest. Aug 08, 2020 N/A N/A
@ -477,7 +478,7 @@ This list contains 1315 plugins.
:pypi:`pytest-find-dependencies` A pytest plugin to find dependencies between tests Apr 09, 2022 4 - Beta pytest (>=4.3.0)
:pypi:`pytest-finer-verdicts` A pytest plugin to treat non-assertion failures as test errors. Jun 18, 2020 N/A pytest (>=5.4.3)
:pypi:`pytest-firefox` pytest plugin to manipulate firefox Aug 08, 2017 3 - Alpha pytest (>=3.0.2)
:pypi:`pytest-fixture-classes` Fixtures as classes that work well with dependency injection, autocompletetion, type checkers, and language servers Jan 20, 2023 4 - Beta pytest
:pypi:`pytest-fixture-classes` Fixtures as classes that work well with dependency injection, autocompletetion, type checkers, and language servers Sep 02, 2023 5 - Production/Stable pytest
:pypi:`pytest-fixture-config` Fixture configuration utils for py.test May 28, 2019 5 - Production/Stable pytest
:pypi:`pytest-fixture-maker` Pytest plugin to load fixtures from YAML files Sep 21, 2021 N/A N/A
:pypi:`pytest-fixture-marker` A pytest plugin to add markers based on fixtures used. Oct 11, 2020 5 - Production/Stable N/A
@ -558,7 +559,7 @@ This list contains 1315 plugins.
:pypi:`pytest-historic` Custom report to display pytest historical execution records Apr 08, 2020 N/A pytest
:pypi:`pytest-historic-hook` Custom listener to store execution results into MYSQL DB, which is used for pytest-historic report Apr 08, 2020 N/A pytest
:pypi:`pytest-homeassistant` A pytest plugin for use with homeassistant custom components. Aug 12, 2020 4 - Beta N/A
:pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components Aug 25, 2023 3 - Alpha pytest ==7.3.1
:pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components Sep 09, 2023 3 - Alpha pytest ==7.3.1
:pypi:`pytest-honey` A simple plugin to use with pytest Jan 07, 2022 4 - Beta pytest (>=3.5.0)
:pypi:`pytest-honors` Report on tests that honor constraints, and guard against regressions Mar 06, 2020 4 - Beta N/A
:pypi:`pytest-hot-reloading` Jun 23, 2023 N/A N/A
@ -582,14 +583,14 @@ This list contains 1315 plugins.
:pypi:`pytest-httpretty` A thin wrapper of HTTPretty for pytest Feb 16, 2014 3 - Alpha N/A
:pypi:`pytest-httpserver` pytest-httpserver is a httpserver for pytest May 22, 2023 3 - Alpha N/A
:pypi:`pytest-httptesting` http_testing framework on top of pytest Jul 24, 2023 N/A pytest (>=7.2.0,<8.0.0)
:pypi:`pytest-httpx` Send responses to httpx. Aug 02, 2023 5 - Production/Stable pytest (<8.0,>=6.0)
:pypi:`pytest-httpx` Send responses to httpx. Sep 04, 2023 5 - Production/Stable pytest <8.0,>=6.0
:pypi:`pytest-httpx-blockage` Disable httpx requests during a test run Feb 16, 2023 N/A pytest (>=7.2.1)
:pypi:`pytest-hue` Visualise PyTest status via your Phillips Hue lights May 09, 2019 N/A N/A
:pypi:`pytest-hylang` Pytest plugin to allow running tests written in hylang Mar 28, 2021 N/A pytest
:pypi:`pytest-hypo-25` help hypo module for pytest Jan 12, 2020 3 - Alpha N/A
:pypi:`pytest-iam` A fully functional OAUTH2 / OpenID Connect (OIDC) server to be used in your testsuite Aug 31, 2023 3 - Alpha pytest (>=7.0.0,<8.0.0)
:pypi:`pytest-ibutsu` A plugin to sent pytest results to an Ibutsu server Aug 05, 2022 4 - Beta pytest>=7.1
:pypi:`pytest-icdiff` use icdiff for better error messages in pytest assertions Aug 09, 2022 4 - Beta N/A
:pypi:`pytest-icdiff` use icdiff for better error messages in pytest assertions Sep 04, 2023 4 - Beta pytest
:pypi:`pytest-idapro` A pytest plugin for idapython. Allows a pytest setup to run tests outside and inside IDA in an automated manner by runnig pytest inside IDA and by mocking idapython api Nov 03, 2018 N/A N/A
:pypi:`pytest-idem` A pytest plugin to help with testing idem projects Jun 23, 2023 5 - Production/Stable N/A
:pypi:`pytest-idempotent` Pytest plugin for testing function idempotence. Jul 25, 2022 N/A N/A
@ -632,7 +633,7 @@ This list contains 1315 plugins.
:pypi:`pytest-jinja` A plugin to generate customizable jinja-based HTML reports in pytest Oct 04, 2022 3 - Alpha pytest (>=6.2.5,<7.0.0)
:pypi:`pytest-jira` py.test JIRA integration plugin, using markers Jun 12, 2023 3 - Alpha N/A
:pypi:`pytest-jira-xfail` Plugin skips (xfail) tests if unresolved Jira issue(s) linked Jun 19, 2023 N/A pytest (>=7.2.0)
:pypi:`pytest-jira-xray` pytest plugin to integrate tests with JIRA XRAY Jul 11, 2023 4 - Beta pytest
:pypi:`pytest-jira-xray` pytest plugin to integrate tests with JIRA XRAY Sep 08, 2023 4 - Beta pytest >=6.2.4
:pypi:`pytest-job-selection` A pytest plugin for load balancing test suites Jan 30, 2023 4 - Beta pytest (>=3.5.0)
:pypi:`pytest-jobserver` Limit parallel tests with posix jobserver. May 15, 2019 5 - Production/Stable pytest
:pypi:`pytest-joke` Test failures are better served with humor. Oct 08, 2019 4 - Beta pytest (>=4.2.1)
@ -783,7 +784,7 @@ This list contains 1315 plugins.
:pypi:`pytest-nginx-iplweb` nginx fixture for pytest - iplweb temporary fork Mar 01, 2019 5 - Production/Stable N/A
:pypi:`pytest-ngrok` Jan 20, 2022 3 - Alpha pytest
:pypi:`pytest-ngsfixtures` pytest ngs fixtures Sep 06, 2019 2 - Pre-Alpha pytest (>=5.0.0)
:pypi:`pytest-nhsd-apim` Pytest plugin accessing NHSDigital's APIM proxies Aug 02, 2023 N/A pytest (==6.2.5)
:pypi:`pytest-nhsd-apim` Pytest plugin accessing NHSDigital's APIM proxies Sep 08, 2023 N/A pytest (==6.2.5)
:pypi:`pytest-nice` A pytest plugin that alerts user of failed test cases with screen notifications May 04, 2019 4 - Beta pytest
:pypi:`pytest-nice-parametrize` A small snippet for nicer PyTest's Parametrize Apr 17, 2021 5 - Production/Stable N/A
:pypi:`pytest-nlcov` Pytest plugin to get the coverage of the new lines (based on git diff) only Jul 07, 2021 N/A N/A
@ -954,7 +955,7 @@ This list contains 1315 plugins.
:pypi:`pytest-random-num` Randomise the order in which pytest tests are run with some control over the randomness Oct 19, 2020 5 - Production/Stable N/A
:pypi:`pytest-random-order` Randomise the order in which pytest tests are run with some control over the randomness Dec 03, 2022 5 - Production/Stable pytest (>=3.0.0)
:pypi:`pytest-readme` Test your README.md file Sep 02, 2022 5 - Production/Stable N/A
:pypi:`pytest-reana` Pytest fixtures for REANA. Aug 04, 2023 3 - Alpha N/A
:pypi:`pytest-reana` Pytest fixtures for REANA. Sep 05, 2023 3 - Alpha N/A
:pypi:`pytest-recorder` Pytest plugin, meant to facilitate unit tests writing for tools consumming Web APIs. Mar 30, 2023 N/A N/A
:pypi:`pytest-recording` A pytest plugin that allows you recording of network interactions via VCR.py Jul 31, 2023 4 - Beta pytest>=3.5.0
:pypi:`pytest-recordings` Provides pytest plugins for reporting request/response traffic, screenshots, and more to ReportPortal Aug 13, 2020 N/A N/A
@ -1021,7 +1022,7 @@ This list contains 1315 plugins.
:pypi:`pytest-rmsis` Sycronise pytest results to Jira RMsis Aug 10, 2022 N/A pytest (>=5.3.5)
:pypi:`pytest-rng` Fixtures for seeding tests and making randomness reproducible Aug 08, 2019 5 - Production/Stable pytest
:pypi:`pytest-roast` pytest plugin for ROAST configuration override and fixtures Nov 09, 2022 5 - Production/Stable pytest
:pypi:`pytest-robotframework` a pytest plugin that can run both python and robotframework tests while generating robot reports for them Aug 30, 2023 N/A pytest (>=7,<8)
:pypi:`pytest-robotframework` a pytest plugin that can run both python and robotframework tests while generating robot reports for them Sep 09, 2023 N/A pytest (>=7,<8)
:pypi:`pytest-rocketchat` Pytest to Rocket.Chat reporting plugin Apr 18, 2021 5 - Production/Stable N/A
:pypi:`pytest-rotest` Pytest integration with rotest Sep 08, 2019 N/A pytest (>=3.5.0)
:pypi:`pytest-rpc` Extend py.test for RPC OpenStack testing. Feb 22, 2019 4 - Beta pytest (~=3.6)
@ -1054,7 +1055,7 @@ This list contains 1315 plugins.
:pypi:`pytest-securestore` An encrypted password store for use within pytest cases Nov 08, 2021 4 - Beta N/A
:pypi:`pytest-select` A pytest plugin which allows to (de-)select tests from a file. Jan 18, 2019 3 - Alpha pytest (>=3.0)
:pypi:`pytest-selenium` pytest plugin for Selenium May 28, 2023 5 - Production/Stable pytest>=6.0.0
:pypi:`pytest-selenium-auto` pytest plugin to automatically capture screenshots upon selenium webdriver events Aug 29, 2023 N/A pytest >= 7.0.0
:pypi:`pytest-selenium-auto` pytest plugin to automatically capture screenshots upon selenium webdriver events Sep 06, 2023 N/A pytest >= 7.0.0
:pypi:`pytest-seleniumbase` A complete web automation framework for end-to-end testing. Sep 02, 2023 5 - Production/Stable N/A
:pypi:`pytest-selenium-enhancer` pytest plugin for Selenium Apr 29, 2022 5 - Production/Stable N/A
:pypi:`pytest-selenium-pdiff` A pytest package implementing perceptualdiff for Selenium tests. Apr 06, 2017 2 - Pre-Alpha N/A
@ -1126,7 +1127,7 @@ This list contains 1315 plugins.
:pypi:`pytest-splitio` Split.io SDK integration for e2e tests Sep 22, 2020 N/A pytest (<7,>=5.0)
:pypi:`pytest-split-tests` A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. Forked from Mark Adams' original project pytest-test-groups. Jul 30, 2021 5 - Production/Stable pytest (>=2.5)
:pypi:`pytest-split-tests-tresorit` Feb 22, 2021 1 - Planning N/A
:pypi:`pytest-splunk-addon` A Dynamic test tool for Splunk Apps and Add-ons Jul 25, 2023 N/A pytest (>5.4.0,<8)
:pypi:`pytest-splunk-addon` A Dynamic test tool for Splunk Apps and Add-ons Sep 06, 2023 N/A pytest (>5.4.0,<8)
:pypi:`pytest-splunk-addon-ui-smartx` Library to support testing Splunk Add-on UX Mar 07, 2023 N/A N/A
:pypi:`pytest-splunk-env` pytest fixtures for interaction with Splunk Enterprise and Splunk Cloud Oct 22, 2020 N/A pytest (>=6.1.1,<7.0.0)
:pypi:`pytest-sqitch` sqitch for pytest Apr 06, 2020 4 - Beta N/A
@ -1140,7 +1141,7 @@ This list contains 1315 plugins.
:pypi:`pytest-ssh` pytest plugin for ssh command run May 27, 2019 N/A pytest
:pypi:`pytest-start-from` Start pytest run from a given point Apr 11, 2016 N/A N/A
:pypi:`pytest-star-track-issue` A package to prevent Dependency Confusion attacks against Yandex. Feb 10, 2023 N/A N/A
:pypi:`pytest-static` pytest-static May 07, 2023 1 - Planning N/A
:pypi:`pytest-static` pytest-static Sep 03, 2023 1 - Planning N/A
:pypi:`pytest-statsd` pytest plugin for reporting to graphite Nov 30, 2018 5 - Production/Stable pytest (>=3.0.0)
:pypi:`pytest-stepfunctions` A small description May 08, 2021 4 - Beta pytest
:pypi:`pytest-steps` Create step-wise / incremental tests in pytest. Sep 23, 2021 5 - Production/Stable N/A
@ -1467,9 +1468,9 @@ This list contains 1315 plugins.
:pypi:`pytest-aiohttp`
*last release*: Feb 12, 2022,
*last release*: Sep 06, 2023,
*status*: 4 - Beta,
*requires*: pytest (>=6.1.0)
*requires*: pytest >=6.1.0
Pytest plugin for aiohttp support
@ -1579,7 +1580,7 @@ This list contains 1315 plugins.
Static code checks used at Alphamoon
:pypi:`pytest-analyzer`
*last release*: Aug 24, 2023,
*last release*: Sep 05, 2023,
*status*: N/A,
*requires*: pytest >=7.3.1
@ -1712,7 +1713,7 @@ This list contains 1315 plugins.
A plugin to use approvaltests with pytest
:pypi:`pytest-approvaltests-geo`
*last release*: Mar 04, 2023,
*last release*: Sep 06, 2023,
*status*: 5 - Production/Stable,
*requires*: pytest
@ -2824,6 +2825,13 @@ This list contains 1315 plugins.
The pytest plugin for your Cookiecutter templates. 🍪
:pypi:`pytest-copie`
*last release*: Sep 07, 2023,
*status*: 3 - Alpha,
*requires*: pytest
The pytest plugin for your Copier templates.
:pypi:`pytest-copier`
*last release*: Jun 23, 2023,
*status*: 4 - Beta,
@ -2888,9 +2896,9 @@ This list contains 1315 plugins.
Pytest plugin for excluding tests based on coverage data
:pypi:`pytest-cpp`
*last release*: Jan 30, 2023,
*last release*: Sep 08, 2023,
*status*: 5 - Production/Stable,
*requires*: pytest (>=7.0)
*requires*: pytest >=7.0
Use pytest's runner to discover and execute C++ tests
@ -4456,8 +4464,8 @@ This list contains 1315 plugins.
pytest plugin to manipulate firefox
:pypi:`pytest-fixture-classes`
*last release*: Jan 20, 2023,
*status*: 4 - Beta,
*last release*: Sep 02, 2023,
*status*: 5 - Production/Stable,
*requires*: pytest
Fixtures as classes that work well with dependency injection, autocompletetion, type checkers, and language servers
@ -5023,7 +5031,7 @@ This list contains 1315 plugins.
A pytest plugin for use with homeassistant custom components.
:pypi:`pytest-homeassistant-custom-component`
*last release*: Aug 25, 2023,
*last release*: Sep 09, 2023,
*status*: 3 - Alpha,
*requires*: pytest ==7.3.1
@ -5191,9 +5199,9 @@ This list contains 1315 plugins.
http_testing framework on top of pytest
:pypi:`pytest-httpx`
*last release*: Aug 02, 2023,
*last release*: Sep 04, 2023,
*status*: 5 - Production/Stable,
*requires*: pytest (<8.0,>=6.0)
*requires*: pytest <8.0,>=6.0
Send responses to httpx.
@ -5240,9 +5248,9 @@ This list contains 1315 plugins.
A plugin to sent pytest results to an Ibutsu server
:pypi:`pytest-icdiff`
*last release*: Aug 09, 2022,
*last release*: Sep 04, 2023,
*status*: 4 - Beta,
*requires*: N/A
*requires*: pytest
use icdiff for better error messages in pytest assertions
@ -5541,9 +5549,9 @@ This list contains 1315 plugins.
Plugin skips (xfail) tests if unresolved Jira issue(s) linked
:pypi:`pytest-jira-xray`
*last release*: Jul 11, 2023,
*last release*: Sep 08, 2023,
*status*: 4 - Beta,
*requires*: pytest
*requires*: pytest >=6.2.4
pytest plugin to integrate tests with JIRA XRAY
@ -6598,7 +6606,7 @@ This list contains 1315 plugins.
pytest ngs fixtures
:pypi:`pytest-nhsd-apim`
*last release*: Aug 02, 2023,
*last release*: Sep 08, 2023,
*status*: N/A,
*requires*: pytest (==6.2.5)
@ -7795,7 +7803,7 @@ This list contains 1315 plugins.
Test your README.md file
:pypi:`pytest-reana`
*last release*: Aug 04, 2023,
*last release*: Sep 05, 2023,
*status*: 3 - Alpha,
*requires*: N/A
@ -8264,7 +8272,7 @@ This list contains 1315 plugins.
pytest plugin for ROAST configuration override and fixtures
:pypi:`pytest-robotframework`
*last release*: Aug 30, 2023,
*last release*: Sep 09, 2023,
*status*: N/A,
*requires*: pytest (>=7,<8)
@ -8495,7 +8503,7 @@ This list contains 1315 plugins.
pytest plugin for Selenium
:pypi:`pytest-selenium-auto`
*last release*: Aug 29, 2023,
*last release*: Sep 06, 2023,
*status*: N/A,
*requires*: pytest >= 7.0.0
@ -8999,7 +9007,7 @@ This list contains 1315 plugins.
:pypi:`pytest-splunk-addon`
*last release*: Jul 25, 2023,
*last release*: Sep 06, 2023,
*status*: N/A,
*requires*: pytest (>5.4.0,<8)
@ -9097,7 +9105,7 @@ This list contains 1315 plugins.
A package to prevent Dependency Confusion attacks against Yandex.
:pypi:`pytest-static`
*last release*: May 07, 2023,
*last release*: Sep 03, 2023,
*status*: 1 - Planning,
*requires*: N/A

View File

@ -31,10 +31,16 @@ class InvalidFeatureRelease(Exception):
SLUG = "pytest-dev/pytest"
PR_BODY = """\
Created automatically from manual trigger.
Created by the [prepare release pr](https://github.com/pytest-dev/pytest/actions/workflows/prepare-release-pr.yml)
workflow.
Once all builds pass and it has been **approved** by one or more maintainers, the build
can be released by pushing a tag `{version}` to this repository.
Once all builds pass and it has been **approved** by one or more maintainers,
start the [deploy](https://github.com/pytest-dev/pytest/actions/workflows/deploy.yml) workflow, using these parameters:
* `Use workflow from`: `release-{version}`.
* `Release version`: `{version}`.
After the `deploy` workflow has been approved by a core maintainer, the package will be uploaded to PyPI automatically.
"""

View File

@ -13,6 +13,7 @@ import struct
import sys
import tokenize
import types
from collections import defaultdict
from pathlib import Path
from pathlib import PurePath
from typing import Callable
@ -45,6 +46,10 @@ if TYPE_CHECKING:
from _pytest.assertion import AssertionState
class Sentinel:
pass
assertstate_key = StashKey["AssertionState"]()
# pytest caches rewritten pycs in pycache dirs
@ -52,6 +57,9 @@ PYTEST_TAG = f"{sys.implementation.cache_tag}-pytest-{version}"
PYC_EXT = ".py" + (__debug__ and "c" or "o")
PYC_TAIL = "." + PYTEST_TAG + PYC_EXT
# Special marker that denotes we have just left a scope definition
_SCOPE_END_MARKER = Sentinel()
class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader):
"""PEP302/PEP451 import hook which rewrites asserts."""
@ -634,6 +642,8 @@ class AssertionRewriter(ast.NodeVisitor):
.push_format_context() and .pop_format_context() which allows
to build another %-formatted string while already building one.
:scope: A tuple containing the current scope used for variables_overwrite.
:variables_overwrite: A dict filled with references to variables
that change value within an assert. This happens when a variable is
reassigned with the walrus operator
@ -655,7 +665,10 @@ class AssertionRewriter(ast.NodeVisitor):
else:
self.enable_assertion_pass_hook = False
self.source = source
self.variables_overwrite: Dict[str, str] = {}
self.scope: tuple[ast.AST, ...] = ()
self.variables_overwrite: defaultdict[
tuple[ast.AST, ...], Dict[str, str]
] = defaultdict(dict)
def run(self, mod: ast.Module) -> None:
"""Find all assert statements in *mod* and rewrite them."""
@ -719,9 +732,17 @@ class AssertionRewriter(ast.NodeVisitor):
mod.body[pos:pos] = imports
# Collect asserts.
nodes: List[ast.AST] = [mod]
self.scope = (mod,)
nodes: List[Union[ast.AST, Sentinel]] = [mod]
while nodes:
node = nodes.pop()
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
self.scope = tuple((*self.scope, node))
nodes.append(_SCOPE_END_MARKER)
if node == _SCOPE_END_MARKER:
self.scope = self.scope[:-1]
continue
assert isinstance(node, ast.AST)
for name, field in ast.iter_fields(node):
if isinstance(field, list):
new: List[ast.AST] = []
@ -992,7 +1013,7 @@ class AssertionRewriter(ast.NodeVisitor):
]
):
pytest_temp = self.variable()
self.variables_overwrite[
self.variables_overwrite[self.scope][
v.left.target.id
] = v.left # type:ignore[assignment]
v.left.target.id = pytest_temp
@ -1035,17 +1056,20 @@ class AssertionRewriter(ast.NodeVisitor):
new_args = []
new_kwargs = []
for arg in call.args:
if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite:
arg = self.variables_overwrite[arg.id] # type:ignore[assignment]
if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite.get(
self.scope, {}
):
arg = self.variables_overwrite[self.scope][
arg.id
] # type:ignore[assignment]
res, expl = self.visit(arg)
arg_expls.append(expl)
new_args.append(res)
for keyword in call.keywords:
if (
isinstance(keyword.value, ast.Name)
and keyword.value.id in self.variables_overwrite
):
keyword.value = self.variables_overwrite[
if isinstance(
keyword.value, ast.Name
) and keyword.value.id in self.variables_overwrite.get(self.scope, {}):
keyword.value = self.variables_overwrite[self.scope][
keyword.value.id
] # type:ignore[assignment]
res, expl = self.visit(keyword.value)
@ -1081,12 +1105,14 @@ class AssertionRewriter(ast.NodeVisitor):
def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]:
self.push_format_context()
# We first check if we have overwritten a variable in the previous assert
if isinstance(comp.left, ast.Name) and comp.left.id in self.variables_overwrite:
comp.left = self.variables_overwrite[
if isinstance(
comp.left, ast.Name
) and comp.left.id in self.variables_overwrite.get(self.scope, {}):
comp.left = self.variables_overwrite[self.scope][
comp.left.id
] # type:ignore[assignment]
if isinstance(comp.left, ast.NamedExpr):
self.variables_overwrite[
self.variables_overwrite[self.scope][
comp.left.target.id
] = comp.left # type:ignore[assignment]
left_res, left_expl = self.visit(comp.left)
@ -1106,7 +1132,7 @@ class AssertionRewriter(ast.NodeVisitor):
and next_operand.target.id == left_res.id
):
next_operand.target.id = self.variable()
self.variables_overwrite[
self.variables_overwrite[self.scope][
left_res.id
] = next_operand # type:ignore[assignment]
next_res, next_expl = self.visit(next_operand)

View File

@ -255,14 +255,20 @@ class DoctestItem(Item):
self,
name: str,
parent: "Union[DoctestTextfile, DoctestModule]",
runner: Optional["doctest.DocTestRunner"] = None,
dtest: Optional["doctest.DocTest"] = None,
runner: "doctest.DocTestRunner",
dtest: "doctest.DocTest",
) -> None:
super().__init__(name, parent)
self.runner = runner
self.dtest = dtest
# Stuff needed for fixture support.
self.obj = None
self.fixture_request: Optional[TopRequest] = None
fm = self.session._fixturemanager
fixtureinfo = fm.getfixtureinfo(node=self, func=None, cls=None)
self._fixtureinfo = fixtureinfo
self.fixturenames = fixtureinfo.names_closure
self._initrequest()
@classmethod
def from_parent( # type: ignore
@ -277,19 +283,18 @@ class DoctestItem(Item):
"""The public named constructor."""
return super().from_parent(name=name, parent=parent, runner=runner, dtest=dtest)
def _initrequest(self) -> None:
self.funcargs: Dict[str, object] = {}
self._request = TopRequest(self, _ispytest=True) # type: ignore[arg-type]
def setup(self) -> None:
if self.dtest is not None:
self.fixture_request = _setup_fixtures(self)
globs = dict(getfixture=self.fixture_request.getfixturevalue)
for name, value in self.fixture_request.getfixturevalue(
"doctest_namespace"
).items():
globs[name] = value
self.dtest.globs.update(globs)
self._request._fillfixtures()
globs = dict(getfixture=self._request.getfixturevalue)
for name, value in self._request.getfixturevalue("doctest_namespace").items():
globs[name] = value
self.dtest.globs.update(globs)
def runtest(self) -> None:
assert self.dtest is not None
assert self.runner is not None
_check_all_skipped(self.dtest)
self._disable_output_capturing_for_darwin()
failures: List["doctest.DocTestFailure"] = []
@ -376,7 +381,6 @@ class DoctestItem(Item):
return ReprFailDoctest(reprlocation_lines)
def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]:
assert self.dtest is not None
return self.path, self.dtest.lineno, "[doctest] %s" % self.name
@ -396,8 +400,8 @@ def _get_flag_lookup() -> Dict[str, int]:
)
def get_optionflags(parent):
optionflags_str = parent.config.getini("doctest_optionflags")
def get_optionflags(config: Config) -> int:
optionflags_str = config.getini("doctest_optionflags")
flag_lookup_table = _get_flag_lookup()
flag_acc = 0
for flag in optionflags_str:
@ -405,8 +409,8 @@ def get_optionflags(parent):
return flag_acc
def _get_continue_on_failure(config):
continue_on_failure = config.getvalue("doctest_continue_on_failure")
def _get_continue_on_failure(config: Config) -> bool:
continue_on_failure: bool = config.getvalue("doctest_continue_on_failure")
if continue_on_failure:
# We need to turn off this if we use pdb since we should stop at
# the first failure.
@ -429,7 +433,7 @@ class DoctestTextfile(Module):
name = self.path.name
globs = {"__name__": "__main__"}
optionflags = get_optionflags(self)
optionflags = get_optionflags(self.config)
runner = _get_runner(
verbose=False,
@ -574,7 +578,7 @@ class DoctestModule(Module):
raise
# Uses internal doctest module parsing mechanism.
finder = MockAwareDocTestFinder()
optionflags = get_optionflags(self)
optionflags = get_optionflags(self.config)
runner = _get_runner(
verbose=False,
optionflags=optionflags,
@ -589,24 +593,6 @@ class DoctestModule(Module):
)
def _setup_fixtures(doctest_item: DoctestItem) -> TopRequest:
"""Used by DoctestTextfile and DoctestItem to setup fixture information."""
def func() -> None:
pass
doctest_item.funcargs = {} # type: ignore[attr-defined]
fm = doctest_item.session._fixturemanager
fixtureinfo = fm.getfixtureinfo(
node=doctest_item, func=func, cls=None, funcargs=False
)
doctest_item._fixtureinfo = fixtureinfo # type: ignore[attr-defined]
doctest_item.fixturenames = fixtureinfo.names_closure # type: ignore[attr-defined]
fixture_request = TopRequest(doctest_item, _ispytest=True) # type: ignore[arg-type]
fixture_request._fillfixtures()
return fixture_request
def _init_checker_class() -> Type["doctest.OutputChecker"]:
import doctest
import re

View File

@ -8,6 +8,7 @@ from collections import defaultdict
from collections import deque
from contextlib import suppress
from pathlib import Path
from typing import AbstractSet
from typing import Any
from typing import Callable
from typing import cast
@ -1382,7 +1383,7 @@ def pytest_addoption(parser: Parser) -> None:
)
def _get_direct_parametrize_args(node: nodes.Node) -> List[str]:
def _get_direct_parametrize_args(node: nodes.Node) -> Set[str]:
"""Return all direct parametrization arguments of a node, so we don't
mistake them for fixtures.
@ -1391,17 +1392,22 @@ def _get_direct_parametrize_args(node: nodes.Node) -> List[str]:
These things are done later as well when dealing with parametrization
so this could be improved.
"""
parametrize_argnames: List[str] = []
parametrize_argnames: Set[str] = set()
for marker in node.iter_markers(name="parametrize"):
if not marker.kwargs.get("indirect", False):
p_argnames, _ = ParameterSet._parse_parametrize_args(
*marker.args, **marker.kwargs
)
parametrize_argnames.extend(p_argnames)
parametrize_argnames.update(p_argnames)
return parametrize_argnames
def deduplicate_names(*seqs: Iterable[str]) -> Tuple[str, ...]:
"""De-duplicate the sequence of names while keeping the original order."""
# Ideally we would use a set, but it does not preserve insertion order.
return tuple(dict.fromkeys(name for seq in seqs for name in seq))
class FixtureManager:
"""pytest fixture definitions and information is stored and managed
from this class.
@ -1454,13 +1460,12 @@ class FixtureManager:
def getfixtureinfo(
self,
node: nodes.Item,
func: Callable[..., object],
func: Optional[Callable[..., object]],
cls: Optional[type],
funcargs: bool = True,
) -> FuncFixtureInfo:
"""Calculate the :class:`FuncFixtureInfo` for an item.
If ``funcargs`` is false, or if the item sets an attribute
If ``func`` is None, or if the item sets an attribute
``nofuncargs = True``, then ``func`` is not examined at all.
:param node:
@ -1469,21 +1474,23 @@ class FixtureManager:
The item's function.
:param cls:
If the function is a method, the method's class.
:param funcargs:
Whether to look into func's parameters as fixture requests.
"""
if funcargs and not getattr(node, "nofuncargs", False):
if func is not None and not getattr(node, "nofuncargs", False):
argnames = getfuncargnames(func, name=node.name, cls=cls)
else:
argnames = ()
usefixturesnames = self._getusefixturesnames(node)
autousenames = self._getautousenames(node.nodeid)
initialnames = deduplicate_names(autousenames, usefixturesnames, argnames)
usefixtures = tuple(
arg for mark in node.iter_markers(name="usefixtures") for arg in mark.args
)
initialnames = usefixtures + argnames
initialnames, names_closure, arg2fixturedefs = self.getfixtureclosure(
initialnames, node, ignore_args=_get_direct_parametrize_args(node)
direct_parametrize_args = _get_direct_parametrize_args(node)
names_closure, arg2fixturedefs = self.getfixtureclosure(
parentnode=node,
initialnames=initialnames,
ignore_args=direct_parametrize_args,
)
return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs)
def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
@ -1515,12 +1522,17 @@ class FixtureManager:
if basenames:
yield from basenames
def _getusefixturesnames(self, node: nodes.Item) -> Iterator[str]:
"""Return the names of usefixtures fixtures applicable to node."""
for mark in node.iter_markers(name="usefixtures"):
yield from mark.args
def getfixtureclosure(
self,
fixturenames: Tuple[str, ...],
parentnode: nodes.Node,
ignore_args: Sequence[str] = (),
) -> Tuple[Tuple[str, ...], List[str], Dict[str, Sequence[FixtureDef[Any]]]]:
initialnames: Tuple[str, ...],
ignore_args: AbstractSet[str],
) -> Tuple[List[str], Dict[str, Sequence[FixtureDef[Any]]]]:
# Collect the closure of all fixtures, starting with the given
# fixturenames as the initial set. As we have to visit all
# factory definitions anyway, we also return an arg2fixturedefs
@ -1529,19 +1541,7 @@ class FixtureManager:
# (discovering matching fixtures for a given name/node is expensive).
parentid = parentnode.nodeid
fixturenames_closure = list(self._getautousenames(parentid))
def merge(otherlist: Iterable[str]) -> None:
for arg in otherlist:
if arg not in fixturenames_closure:
fixturenames_closure.append(arg)
merge(fixturenames)
# At this point, fixturenames_closure contains what we call "initialnames",
# which is a set of fixturenames the function immediately requests. We
# need to return it as well, so save this.
initialnames = tuple(fixturenames_closure)
fixturenames_closure = list(initialnames)
arg2fixturedefs: Dict[str, Sequence[FixtureDef[Any]]] = {}
lastlen = -1
@ -1555,7 +1555,9 @@ class FixtureManager:
fixturedefs = self.getfixturedefs(argname, parentid)
if fixturedefs:
arg2fixturedefs[argname] = fixturedefs
merge(fixturedefs[-1].argnames)
for arg in fixturedefs[-1].argnames:
if arg not in fixturenames_closure:
fixturenames_closure.append(arg)
def sort_by_scope(arg_name: str) -> Scope:
try:
@ -1566,7 +1568,7 @@ class FixtureManager:
return fixturedefs[-1]._scope
fixturenames_closure.sort(key=sort_by_scope, reverse=True)
return initialnames, fixturenames_closure, arg2fixturedefs
return fixturenames_closure, arg2fixturedefs
def pytest_generate_tests(self, metafunc: "Metafunc") -> None:
"""Generate new tests based on parametrized fixtures used by the given metafunc"""

View File

@ -623,8 +623,9 @@ def module_name_from_path(path: Path, root: Path) -> str:
# Use the parts for the relative path to the root path.
path_parts = relative_path.parts
# Module name for packages do not contain the __init__ file.
if path_parts[-1] == "__init__":
# Module name for packages do not contain the __init__ file, unless
# the `__init__.py` file is at the root.
if len(path_parts) >= 2 and path_parts[-1] == "__init__":
path_parts = path_parts[:-1]
return ".".join(path_parts)
@ -680,7 +681,7 @@ def resolve_package_path(path: Path) -> Optional[Path]:
result = None
for parent in itertools.chain((path,), path.parents):
if parent.is_dir():
if not parent.joinpath("__init__.py").is_file():
if not (parent / "__init__.py").is_file():
break
if not parent.name.isidentifier():
break

View File

@ -1800,9 +1800,8 @@ class Function(PyobjMixin, nodes.Item):
self.keywords.update(keywords)
if fixtureinfo is None:
fixtureinfo = self.session._fixturemanager.getfixtureinfo(
self, self.obj, self.cls, funcargs=True
)
fm = self.session._fixturemanager
fixtureinfo = fm.getfixtureinfo(self, self.obj, self.cls)
self._fixtureinfo: FuncFixtureInfo = fixtureinfo
self.fixturenames = fixtureinfo.names_closure
self._initrequest()

View File

@ -6,6 +6,7 @@ from pathlib import Path
import pytest
from _pytest.compat import getfuncargnames
from _pytest.config import ExitCode
from _pytest.fixtures import deduplicate_names
from _pytest.fixtures import TopRequest
from _pytest.monkeypatch import MonkeyPatch
from _pytest.pytester import get_public_names
@ -4531,3 +4532,10 @@ def test_yield_fixture_with_no_value(pytester: Pytester) -> None:
result.assert_outcomes(errors=1)
result.stdout.fnmatch_lines([expected])
assert result.ret == ExitCode.TESTS_FAILED
def test_deduplicate_names() -> None:
items = deduplicate_names("abacd")
assert items == ("a", "b", "c", "d")
items = deduplicate_names(items + ("g", "f", "g", "e", "b"))
assert items == ("a", "b", "c", "d", "g", "f", "e")

View File

@ -1543,6 +1543,27 @@ class TestIssue11028:
result.stdout.fnmatch_lines(["*assert 4 > 5", "*where 5 = add_one(4)"])
class TestIssue11239:
def test_assertion_walrus_different_test_cases(self, pytester: Pytester) -> None:
"""Regression for (#11239)
Walrus operator rewriting would leak to separate test cases if they used the same variables.
"""
pytester.makepyfile(
"""
def test_1():
state = {"x": 2}.get("x")
assert state is not None
def test_2():
db = {"x": 2}
assert (state := db.get("x")) is not None
"""
)
result = pytester.runpytest()
assert result.ret == 0
@pytest.mark.skipif(
sys.maxsize <= (2**31 - 1), reason="Causes OverflowError on 32bit systems"
)

View File

@ -28,6 +28,7 @@ from _pytest.pathlib import resolve_package_path
from _pytest.pathlib import safe_exists
from _pytest.pathlib import symlink_or_skip
from _pytest.pathlib import visit
from _pytest.pytester import Pytester
from _pytest.tmpdir import TempPathFactory
@ -345,18 +346,18 @@ def test_resolve_package_path(tmp_path: Path) -> None:
(pkg / "subdir").mkdir()
(pkg / "subdir/__init__.py").touch()
assert resolve_package_path(pkg) == pkg
assert resolve_package_path(pkg.joinpath("subdir", "__init__.py")) == pkg
assert resolve_package_path(pkg / "subdir/__init__.py") == pkg
def test_package_unimportable(tmp_path: Path) -> None:
pkg = tmp_path / "pkg1-1"
pkg.mkdir()
pkg.joinpath("__init__.py").touch()
subdir = pkg.joinpath("subdir")
subdir = pkg / "subdir"
subdir.mkdir()
pkg.joinpath("subdir/__init__.py").touch()
(pkg / "subdir/__init__.py").touch()
assert resolve_package_path(subdir) == subdir
xyz = subdir.joinpath("xyz.py")
xyz = subdir / "xyz.py"
xyz.touch()
assert resolve_package_path(xyz) == subdir
assert not resolve_package_path(pkg)
@ -592,6 +593,10 @@ class TestImportLibMode:
result = module_name_from_path(tmp_path / "src/app/__init__.py", tmp_path)
assert result == "src.app"
# Unless __init__.py file is at the root, in which case we cannot have an empty module name.
result = module_name_from_path(tmp_path / "__init__.py", tmp_path)
assert result == "__init__"
def test_insert_missing_modules(
self, monkeypatch: MonkeyPatch, tmp_path: Path
) -> None:
@ -663,6 +668,22 @@ class TestImportLibMode:
mod = import_path(init, root=tmp_path, mode=ImportMode.importlib)
assert len(mod.instance.INSTANCES) == 1
def test_importlib_root_is_package(self, pytester: Pytester) -> None:
"""
Regression for importing a `__init__`.py file that is at the root
(#11417).
"""
pytester.makepyfile(__init__="")
pytester.makepyfile(
"""
def test_my_test():
assert True
"""
)
result = pytester.runpytest("--import-mode=importlib")
result.stdout.fnmatch_lines("* 1 passed *")
def test_safe_exists(tmp_path: Path) -> None:
d = tmp_path.joinpath("some_dir")