Merge branch 'main' into main
This commit is contained in:
commit
4ac59d8b53
|
@ -36,8 +36,10 @@ jobs:
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Download Package
|
- name: Download Package
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|
1
AUTHORS
1
AUTHORS
|
@ -235,6 +235,7 @@ Maho
|
||||||
Maik Figura
|
Maik Figura
|
||||||
Mandeep Bhutani
|
Mandeep Bhutani
|
||||||
Manuel Krebber
|
Manuel Krebber
|
||||||
|
Marc Mueller
|
||||||
Marc Schlaich
|
Marc Schlaich
|
||||||
Marcelo Duarte Trevisani
|
Marcelo Duarte Trevisani
|
||||||
Marcin Bachry
|
Marcin Bachry
|
||||||
|
|
|
@ -134,7 +134,8 @@ Releasing
|
||||||
Both automatic and manual processes described above follow the same steps from this point onward.
|
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
|
#. 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
|
This job will require approval from ``pytest-dev/core``, after which it will publish to PyPI
|
||||||
and tag the repository.
|
and tag the repository.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed ``:=`` in asserts impacting unrelated test cases.
|
|
@ -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
|
creating a PDF, because otherwise the table gets far too wide for the
|
||||||
page.
|
page.
|
||||||
|
|
||||||
This list contains 1315 plugins.
|
This list contains 1316 plugins.
|
||||||
|
|
||||||
.. only:: not latex
|
.. 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-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-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-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-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-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)
|
: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-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-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-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-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-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)
|
: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-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-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` 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-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-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)
|
: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-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-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-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-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-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
|
: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-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-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-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-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-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
|
: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-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-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-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-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-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
|
: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` 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-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` 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-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-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
|
: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-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-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-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-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-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-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-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-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-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-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-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
|
: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-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` 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-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-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-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)
|
: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-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-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-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` 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-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
|
: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-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-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-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-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-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
|
: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-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-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-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-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-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)
|
: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-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-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` 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-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-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
|
: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-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` 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-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-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-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
|
: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-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-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-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-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-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
|
: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`
|
:pypi:`pytest-aiohttp`
|
||||||
*last release*: Feb 12, 2022,
|
*last release*: Sep 06, 2023,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: pytest (>=6.1.0)
|
*requires*: pytest >=6.1.0
|
||||||
|
|
||||||
Pytest plugin for aiohttp support
|
Pytest plugin for aiohttp support
|
||||||
|
|
||||||
|
@ -1579,7 +1580,7 @@ This list contains 1315 plugins.
|
||||||
Static code checks used at Alphamoon
|
Static code checks used at Alphamoon
|
||||||
|
|
||||||
:pypi:`pytest-analyzer`
|
:pypi:`pytest-analyzer`
|
||||||
*last release*: Aug 24, 2023,
|
*last release*: Sep 05, 2023,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest >=7.3.1
|
*requires*: pytest >=7.3.1
|
||||||
|
|
||||||
|
@ -1712,7 +1713,7 @@ This list contains 1315 plugins.
|
||||||
A plugin to use approvaltests with pytest
|
A plugin to use approvaltests with pytest
|
||||||
|
|
||||||
:pypi:`pytest-approvaltests-geo`
|
:pypi:`pytest-approvaltests-geo`
|
||||||
*last release*: Mar 04, 2023,
|
*last release*: Sep 06, 2023,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: pytest
|
*requires*: pytest
|
||||||
|
|
||||||
|
@ -2824,6 +2825,13 @@ This list contains 1315 plugins.
|
||||||
|
|
||||||
The pytest plugin for your Cookiecutter templates. 🍪
|
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`
|
:pypi:`pytest-copier`
|
||||||
*last release*: Jun 23, 2023,
|
*last release*: Jun 23, 2023,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
|
@ -2888,9 +2896,9 @@ This list contains 1315 plugins.
|
||||||
Pytest plugin for excluding tests based on coverage data
|
Pytest plugin for excluding tests based on coverage data
|
||||||
|
|
||||||
:pypi:`pytest-cpp`
|
:pypi:`pytest-cpp`
|
||||||
*last release*: Jan 30, 2023,
|
*last release*: Sep 08, 2023,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: pytest (>=7.0)
|
*requires*: pytest >=7.0
|
||||||
|
|
||||||
Use pytest's runner to discover and execute C++ tests
|
Use pytest's runner to discover and execute C++ tests
|
||||||
|
|
||||||
|
@ -4456,8 +4464,8 @@ This list contains 1315 plugins.
|
||||||
pytest plugin to manipulate firefox
|
pytest plugin to manipulate firefox
|
||||||
|
|
||||||
:pypi:`pytest-fixture-classes`
|
:pypi:`pytest-fixture-classes`
|
||||||
*last release*: Jan 20, 2023,
|
*last release*: Sep 02, 2023,
|
||||||
*status*: 4 - Beta,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: pytest
|
*requires*: pytest
|
||||||
|
|
||||||
Fixtures as classes that work well with dependency injection, autocompletetion, type checkers, and language servers
|
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.
|
A pytest plugin for use with homeassistant custom components.
|
||||||
|
|
||||||
:pypi:`pytest-homeassistant-custom-component`
|
:pypi:`pytest-homeassistant-custom-component`
|
||||||
*last release*: Aug 25, 2023,
|
*last release*: Sep 09, 2023,
|
||||||
*status*: 3 - Alpha,
|
*status*: 3 - Alpha,
|
||||||
*requires*: pytest ==7.3.1
|
*requires*: pytest ==7.3.1
|
||||||
|
|
||||||
|
@ -5191,9 +5199,9 @@ This list contains 1315 plugins.
|
||||||
http_testing framework on top of pytest
|
http_testing framework on top of pytest
|
||||||
|
|
||||||
:pypi:`pytest-httpx`
|
:pypi:`pytest-httpx`
|
||||||
*last release*: Aug 02, 2023,
|
*last release*: Sep 04, 2023,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: pytest (<8.0,>=6.0)
|
*requires*: pytest <8.0,>=6.0
|
||||||
|
|
||||||
Send responses to httpx.
|
Send responses to httpx.
|
||||||
|
|
||||||
|
@ -5240,9 +5248,9 @@ This list contains 1315 plugins.
|
||||||
A plugin to sent pytest results to an Ibutsu server
|
A plugin to sent pytest results to an Ibutsu server
|
||||||
|
|
||||||
:pypi:`pytest-icdiff`
|
:pypi:`pytest-icdiff`
|
||||||
*last release*: Aug 09, 2022,
|
*last release*: Sep 04, 2023,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: N/A
|
*requires*: pytest
|
||||||
|
|
||||||
use icdiff for better error messages in pytest assertions
|
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
|
Plugin skips (xfail) tests if unresolved Jira issue(s) linked
|
||||||
|
|
||||||
:pypi:`pytest-jira-xray`
|
:pypi:`pytest-jira-xray`
|
||||||
*last release*: Jul 11, 2023,
|
*last release*: Sep 08, 2023,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: pytest
|
*requires*: pytest >=6.2.4
|
||||||
|
|
||||||
pytest plugin to integrate tests with JIRA XRAY
|
pytest plugin to integrate tests with JIRA XRAY
|
||||||
|
|
||||||
|
@ -6598,7 +6606,7 @@ This list contains 1315 plugins.
|
||||||
pytest ngs fixtures
|
pytest ngs fixtures
|
||||||
|
|
||||||
:pypi:`pytest-nhsd-apim`
|
:pypi:`pytest-nhsd-apim`
|
||||||
*last release*: Aug 02, 2023,
|
*last release*: Sep 08, 2023,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (==6.2.5)
|
*requires*: pytest (==6.2.5)
|
||||||
|
|
||||||
|
@ -7795,7 +7803,7 @@ This list contains 1315 plugins.
|
||||||
Test your README.md file
|
Test your README.md file
|
||||||
|
|
||||||
:pypi:`pytest-reana`
|
:pypi:`pytest-reana`
|
||||||
*last release*: Aug 04, 2023,
|
*last release*: Sep 05, 2023,
|
||||||
*status*: 3 - Alpha,
|
*status*: 3 - Alpha,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -8264,7 +8272,7 @@ This list contains 1315 plugins.
|
||||||
pytest plugin for ROAST configuration override and fixtures
|
pytest plugin for ROAST configuration override and fixtures
|
||||||
|
|
||||||
:pypi:`pytest-robotframework`
|
:pypi:`pytest-robotframework`
|
||||||
*last release*: Aug 30, 2023,
|
*last release*: Sep 09, 2023,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (>=7,<8)
|
*requires*: pytest (>=7,<8)
|
||||||
|
|
||||||
|
@ -8495,7 +8503,7 @@ This list contains 1315 plugins.
|
||||||
pytest plugin for Selenium
|
pytest plugin for Selenium
|
||||||
|
|
||||||
:pypi:`pytest-selenium-auto`
|
:pypi:`pytest-selenium-auto`
|
||||||
*last release*: Aug 29, 2023,
|
*last release*: Sep 06, 2023,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest >= 7.0.0
|
*requires*: pytest >= 7.0.0
|
||||||
|
|
||||||
|
@ -8999,7 +9007,7 @@ This list contains 1315 plugins.
|
||||||
|
|
||||||
|
|
||||||
:pypi:`pytest-splunk-addon`
|
:pypi:`pytest-splunk-addon`
|
||||||
*last release*: Jul 25, 2023,
|
*last release*: Sep 06, 2023,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (>5.4.0,<8)
|
*requires*: pytest (>5.4.0,<8)
|
||||||
|
|
||||||
|
@ -9097,7 +9105,7 @@ This list contains 1315 plugins.
|
||||||
A package to prevent Dependency Confusion attacks against Yandex.
|
A package to prevent Dependency Confusion attacks against Yandex.
|
||||||
|
|
||||||
:pypi:`pytest-static`
|
:pypi:`pytest-static`
|
||||||
*last release*: May 07, 2023,
|
*last release*: Sep 03, 2023,
|
||||||
*status*: 1 - Planning,
|
*status*: 1 - Planning,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,16 @@ class InvalidFeatureRelease(Exception):
|
||||||
SLUG = "pytest-dev/pytest"
|
SLUG = "pytest-dev/pytest"
|
||||||
|
|
||||||
PR_BODY = """\
|
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
|
Once all builds pass and it has been **approved** by one or more maintainers,
|
||||||
can be released by pushing a tag `{version}` to this repository.
|
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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import struct
|
||||||
import sys
|
import sys
|
||||||
import tokenize
|
import tokenize
|
||||||
import types
|
import types
|
||||||
|
from collections import defaultdict
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pathlib import PurePath
|
from pathlib import PurePath
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
@ -45,6 +46,10 @@ if TYPE_CHECKING:
|
||||||
from _pytest.assertion import AssertionState
|
from _pytest.assertion import AssertionState
|
||||||
|
|
||||||
|
|
||||||
|
class Sentinel:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
assertstate_key = StashKey["AssertionState"]()
|
assertstate_key = StashKey["AssertionState"]()
|
||||||
|
|
||||||
# pytest caches rewritten pycs in pycache dirs
|
# 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_EXT = ".py" + (__debug__ and "c" or "o")
|
||||||
PYC_TAIL = "." + PYTEST_TAG + PYC_EXT
|
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):
|
class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader):
|
||||||
"""PEP302/PEP451 import hook which rewrites asserts."""
|
"""PEP302/PEP451 import hook which rewrites asserts."""
|
||||||
|
@ -634,6 +642,8 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
.push_format_context() and .pop_format_context() which allows
|
.push_format_context() and .pop_format_context() which allows
|
||||||
to build another %-formatted string while already building one.
|
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
|
:variables_overwrite: A dict filled with references to variables
|
||||||
that change value within an assert. This happens when a variable is
|
that change value within an assert. This happens when a variable is
|
||||||
reassigned with the walrus operator
|
reassigned with the walrus operator
|
||||||
|
@ -655,7 +665,10 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
else:
|
else:
|
||||||
self.enable_assertion_pass_hook = False
|
self.enable_assertion_pass_hook = False
|
||||||
self.source = source
|
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:
|
def run(self, mod: ast.Module) -> None:
|
||||||
"""Find all assert statements in *mod* and rewrite them."""
|
"""Find all assert statements in *mod* and rewrite them."""
|
||||||
|
@ -719,9 +732,17 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
mod.body[pos:pos] = imports
|
mod.body[pos:pos] = imports
|
||||||
|
|
||||||
# Collect asserts.
|
# Collect asserts.
|
||||||
nodes: List[ast.AST] = [mod]
|
self.scope = (mod,)
|
||||||
|
nodes: List[Union[ast.AST, Sentinel]] = [mod]
|
||||||
while nodes:
|
while nodes:
|
||||||
node = nodes.pop()
|
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):
|
for name, field in ast.iter_fields(node):
|
||||||
if isinstance(field, list):
|
if isinstance(field, list):
|
||||||
new: List[ast.AST] = []
|
new: List[ast.AST] = []
|
||||||
|
@ -992,7 +1013,7 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
pytest_temp = self.variable()
|
pytest_temp = self.variable()
|
||||||
self.variables_overwrite[
|
self.variables_overwrite[self.scope][
|
||||||
v.left.target.id
|
v.left.target.id
|
||||||
] = v.left # type:ignore[assignment]
|
] = v.left # type:ignore[assignment]
|
||||||
v.left.target.id = pytest_temp
|
v.left.target.id = pytest_temp
|
||||||
|
@ -1035,17 +1056,20 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
new_args = []
|
new_args = []
|
||||||
new_kwargs = []
|
new_kwargs = []
|
||||||
for arg in call.args:
|
for arg in call.args:
|
||||||
if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite:
|
if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite.get(
|
||||||
arg = self.variables_overwrite[arg.id] # type:ignore[assignment]
|
self.scope, {}
|
||||||
|
):
|
||||||
|
arg = self.variables_overwrite[self.scope][
|
||||||
|
arg.id
|
||||||
|
] # type:ignore[assignment]
|
||||||
res, expl = self.visit(arg)
|
res, expl = self.visit(arg)
|
||||||
arg_expls.append(expl)
|
arg_expls.append(expl)
|
||||||
new_args.append(res)
|
new_args.append(res)
|
||||||
for keyword in call.keywords:
|
for keyword in call.keywords:
|
||||||
if (
|
if isinstance(
|
||||||
isinstance(keyword.value, ast.Name)
|
keyword.value, ast.Name
|
||||||
and keyword.value.id in self.variables_overwrite
|
) and keyword.value.id in self.variables_overwrite.get(self.scope, {}):
|
||||||
):
|
keyword.value = self.variables_overwrite[self.scope][
|
||||||
keyword.value = self.variables_overwrite[
|
|
||||||
keyword.value.id
|
keyword.value.id
|
||||||
] # type:ignore[assignment]
|
] # type:ignore[assignment]
|
||||||
res, expl = self.visit(keyword.value)
|
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]:
|
def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]:
|
||||||
self.push_format_context()
|
self.push_format_context()
|
||||||
# We first check if we have overwritten a variable in the previous assert
|
# 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:
|
if isinstance(
|
||||||
comp.left = self.variables_overwrite[
|
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
|
comp.left.id
|
||||||
] # type:ignore[assignment]
|
] # type:ignore[assignment]
|
||||||
if isinstance(comp.left, ast.NamedExpr):
|
if isinstance(comp.left, ast.NamedExpr):
|
||||||
self.variables_overwrite[
|
self.variables_overwrite[self.scope][
|
||||||
comp.left.target.id
|
comp.left.target.id
|
||||||
] = comp.left # type:ignore[assignment]
|
] = comp.left # type:ignore[assignment]
|
||||||
left_res, left_expl = self.visit(comp.left)
|
left_res, left_expl = self.visit(comp.left)
|
||||||
|
@ -1106,7 +1132,7 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
and next_operand.target.id == left_res.id
|
and next_operand.target.id == left_res.id
|
||||||
):
|
):
|
||||||
next_operand.target.id = self.variable()
|
next_operand.target.id = self.variable()
|
||||||
self.variables_overwrite[
|
self.variables_overwrite[self.scope][
|
||||||
left_res.id
|
left_res.id
|
||||||
] = next_operand # type:ignore[assignment]
|
] = next_operand # type:ignore[assignment]
|
||||||
next_res, next_expl = self.visit(next_operand)
|
next_res, next_expl = self.visit(next_operand)
|
||||||
|
|
|
@ -255,14 +255,20 @@ class DoctestItem(Item):
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
parent: "Union[DoctestTextfile, DoctestModule]",
|
parent: "Union[DoctestTextfile, DoctestModule]",
|
||||||
runner: Optional["doctest.DocTestRunner"] = None,
|
runner: "doctest.DocTestRunner",
|
||||||
dtest: Optional["doctest.DocTest"] = None,
|
dtest: "doctest.DocTest",
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(name, parent)
|
super().__init__(name, parent)
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
self.dtest = dtest
|
self.dtest = dtest
|
||||||
|
|
||||||
|
# Stuff needed for fixture support.
|
||||||
self.obj = None
|
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
|
@classmethod
|
||||||
def from_parent( # type: ignore
|
def from_parent( # type: ignore
|
||||||
|
@ -277,19 +283,18 @@ class DoctestItem(Item):
|
||||||
"""The public named constructor."""
|
"""The public named constructor."""
|
||||||
return super().from_parent(name=name, parent=parent, runner=runner, dtest=dtest)
|
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:
|
def setup(self) -> None:
|
||||||
if self.dtest is not None:
|
self._request._fillfixtures()
|
||||||
self.fixture_request = _setup_fixtures(self)
|
globs = dict(getfixture=self._request.getfixturevalue)
|
||||||
globs = dict(getfixture=self.fixture_request.getfixturevalue)
|
for name, value in self._request.getfixturevalue("doctest_namespace").items():
|
||||||
for name, value in self.fixture_request.getfixturevalue(
|
|
||||||
"doctest_namespace"
|
|
||||||
).items():
|
|
||||||
globs[name] = value
|
globs[name] = value
|
||||||
self.dtest.globs.update(globs)
|
self.dtest.globs.update(globs)
|
||||||
|
|
||||||
def runtest(self) -> None:
|
def runtest(self) -> None:
|
||||||
assert self.dtest is not None
|
|
||||||
assert self.runner is not None
|
|
||||||
_check_all_skipped(self.dtest)
|
_check_all_skipped(self.dtest)
|
||||||
self._disable_output_capturing_for_darwin()
|
self._disable_output_capturing_for_darwin()
|
||||||
failures: List["doctest.DocTestFailure"] = []
|
failures: List["doctest.DocTestFailure"] = []
|
||||||
|
@ -376,7 +381,6 @@ class DoctestItem(Item):
|
||||||
return ReprFailDoctest(reprlocation_lines)
|
return ReprFailDoctest(reprlocation_lines)
|
||||||
|
|
||||||
def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]:
|
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
|
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):
|
def get_optionflags(config: Config) -> int:
|
||||||
optionflags_str = parent.config.getini("doctest_optionflags")
|
optionflags_str = config.getini("doctest_optionflags")
|
||||||
flag_lookup_table = _get_flag_lookup()
|
flag_lookup_table = _get_flag_lookup()
|
||||||
flag_acc = 0
|
flag_acc = 0
|
||||||
for flag in optionflags_str:
|
for flag in optionflags_str:
|
||||||
|
@ -405,8 +409,8 @@ def get_optionflags(parent):
|
||||||
return flag_acc
|
return flag_acc
|
||||||
|
|
||||||
|
|
||||||
def _get_continue_on_failure(config):
|
def _get_continue_on_failure(config: Config) -> bool:
|
||||||
continue_on_failure = config.getvalue("doctest_continue_on_failure")
|
continue_on_failure: bool = config.getvalue("doctest_continue_on_failure")
|
||||||
if continue_on_failure:
|
if continue_on_failure:
|
||||||
# We need to turn off this if we use pdb since we should stop at
|
# We need to turn off this if we use pdb since we should stop at
|
||||||
# the first failure.
|
# the first failure.
|
||||||
|
@ -429,7 +433,7 @@ class DoctestTextfile(Module):
|
||||||
name = self.path.name
|
name = self.path.name
|
||||||
globs = {"__name__": "__main__"}
|
globs = {"__name__": "__main__"}
|
||||||
|
|
||||||
optionflags = get_optionflags(self)
|
optionflags = get_optionflags(self.config)
|
||||||
|
|
||||||
runner = _get_runner(
|
runner = _get_runner(
|
||||||
verbose=False,
|
verbose=False,
|
||||||
|
@ -574,7 +578,7 @@ class DoctestModule(Module):
|
||||||
raise
|
raise
|
||||||
# Uses internal doctest module parsing mechanism.
|
# Uses internal doctest module parsing mechanism.
|
||||||
finder = MockAwareDocTestFinder()
|
finder = MockAwareDocTestFinder()
|
||||||
optionflags = get_optionflags(self)
|
optionflags = get_optionflags(self.config)
|
||||||
runner = _get_runner(
|
runner = _get_runner(
|
||||||
verbose=False,
|
verbose=False,
|
||||||
optionflags=optionflags,
|
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"]:
|
def _init_checker_class() -> Type["doctest.OutputChecker"]:
|
||||||
import doctest
|
import doctest
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -8,6 +8,7 @@ from collections import defaultdict
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import AbstractSet
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import cast
|
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
|
"""Return all direct parametrization arguments of a node, so we don't
|
||||||
mistake them for fixtures.
|
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
|
These things are done later as well when dealing with parametrization
|
||||||
so this could be improved.
|
so this could be improved.
|
||||||
"""
|
"""
|
||||||
parametrize_argnames: List[str] = []
|
parametrize_argnames: Set[str] = set()
|
||||||
for marker in node.iter_markers(name="parametrize"):
|
for marker in node.iter_markers(name="parametrize"):
|
||||||
if not marker.kwargs.get("indirect", False):
|
if not marker.kwargs.get("indirect", False):
|
||||||
p_argnames, _ = ParameterSet._parse_parametrize_args(
|
p_argnames, _ = ParameterSet._parse_parametrize_args(
|
||||||
*marker.args, **marker.kwargs
|
*marker.args, **marker.kwargs
|
||||||
)
|
)
|
||||||
parametrize_argnames.extend(p_argnames)
|
parametrize_argnames.update(p_argnames)
|
||||||
|
|
||||||
return parametrize_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:
|
class FixtureManager:
|
||||||
"""pytest fixture definitions and information is stored and managed
|
"""pytest fixture definitions and information is stored and managed
|
||||||
from this class.
|
from this class.
|
||||||
|
@ -1454,13 +1460,12 @@ class FixtureManager:
|
||||||
def getfixtureinfo(
|
def getfixtureinfo(
|
||||||
self,
|
self,
|
||||||
node: nodes.Item,
|
node: nodes.Item,
|
||||||
func: Callable[..., object],
|
func: Optional[Callable[..., object]],
|
||||||
cls: Optional[type],
|
cls: Optional[type],
|
||||||
funcargs: bool = True,
|
|
||||||
) -> FuncFixtureInfo:
|
) -> FuncFixtureInfo:
|
||||||
"""Calculate the :class:`FuncFixtureInfo` for an item.
|
"""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.
|
``nofuncargs = True``, then ``func`` is not examined at all.
|
||||||
|
|
||||||
:param node:
|
:param node:
|
||||||
|
@ -1469,21 +1474,23 @@ class FixtureManager:
|
||||||
The item's function.
|
The item's function.
|
||||||
:param cls:
|
:param cls:
|
||||||
If the function is a method, the method's class.
|
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)
|
argnames = getfuncargnames(func, name=node.name, cls=cls)
|
||||||
else:
|
else:
|
||||||
argnames = ()
|
argnames = ()
|
||||||
|
usefixturesnames = self._getusefixturesnames(node)
|
||||||
|
autousenames = self._getautousenames(node.nodeid)
|
||||||
|
initialnames = deduplicate_names(autousenames, usefixturesnames, argnames)
|
||||||
|
|
||||||
usefixtures = tuple(
|
direct_parametrize_args = _get_direct_parametrize_args(node)
|
||||||
arg for mark in node.iter_markers(name="usefixtures") for arg in mark.args
|
|
||||||
)
|
names_closure, arg2fixturedefs = self.getfixtureclosure(
|
||||||
initialnames = usefixtures + argnames
|
parentnode=node,
|
||||||
initialnames, names_closure, arg2fixturedefs = self.getfixtureclosure(
|
initialnames=initialnames,
|
||||||
initialnames, node, ignore_args=_get_direct_parametrize_args(node)
|
ignore_args=direct_parametrize_args,
|
||||||
)
|
)
|
||||||
|
|
||||||
return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs)
|
return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs)
|
||||||
|
|
||||||
def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
|
def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
|
||||||
|
@ -1515,12 +1522,17 @@ class FixtureManager:
|
||||||
if basenames:
|
if basenames:
|
||||||
yield from 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(
|
def getfixtureclosure(
|
||||||
self,
|
self,
|
||||||
fixturenames: Tuple[str, ...],
|
|
||||||
parentnode: nodes.Node,
|
parentnode: nodes.Node,
|
||||||
ignore_args: Sequence[str] = (),
|
initialnames: Tuple[str, ...],
|
||||||
) -> Tuple[Tuple[str, ...], List[str], Dict[str, Sequence[FixtureDef[Any]]]]:
|
ignore_args: AbstractSet[str],
|
||||||
|
) -> Tuple[List[str], Dict[str, Sequence[FixtureDef[Any]]]]:
|
||||||
# Collect the closure of all fixtures, starting with the given
|
# Collect the closure of all fixtures, starting with the given
|
||||||
# fixturenames as the initial set. As we have to visit all
|
# fixturenames as the initial set. As we have to visit all
|
||||||
# factory definitions anyway, we also return an arg2fixturedefs
|
# factory definitions anyway, we also return an arg2fixturedefs
|
||||||
|
@ -1529,19 +1541,7 @@ class FixtureManager:
|
||||||
# (discovering matching fixtures for a given name/node is expensive).
|
# (discovering matching fixtures for a given name/node is expensive).
|
||||||
|
|
||||||
parentid = parentnode.nodeid
|
parentid = parentnode.nodeid
|
||||||
fixturenames_closure = list(self._getautousenames(parentid))
|
fixturenames_closure = list(initialnames)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
arg2fixturedefs: Dict[str, Sequence[FixtureDef[Any]]] = {}
|
arg2fixturedefs: Dict[str, Sequence[FixtureDef[Any]]] = {}
|
||||||
lastlen = -1
|
lastlen = -1
|
||||||
|
@ -1555,7 +1555,9 @@ class FixtureManager:
|
||||||
fixturedefs = self.getfixturedefs(argname, parentid)
|
fixturedefs = self.getfixturedefs(argname, parentid)
|
||||||
if fixturedefs:
|
if fixturedefs:
|
||||||
arg2fixturedefs[argname] = 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:
|
def sort_by_scope(arg_name: str) -> Scope:
|
||||||
try:
|
try:
|
||||||
|
@ -1566,7 +1568,7 @@ class FixtureManager:
|
||||||
return fixturedefs[-1]._scope
|
return fixturedefs[-1]._scope
|
||||||
|
|
||||||
fixturenames_closure.sort(key=sort_by_scope, reverse=True)
|
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:
|
def pytest_generate_tests(self, metafunc: "Metafunc") -> None:
|
||||||
"""Generate new tests based on parametrized fixtures used by the given metafunc"""
|
"""Generate new tests based on parametrized fixtures used by the given metafunc"""
|
||||||
|
|
|
@ -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.
|
# Use the parts for the relative path to the root path.
|
||||||
path_parts = relative_path.parts
|
path_parts = relative_path.parts
|
||||||
|
|
||||||
# Module name for packages do not contain the __init__ file.
|
# Module name for packages do not contain the __init__ file, unless
|
||||||
if path_parts[-1] == "__init__":
|
# the `__init__.py` file is at the root.
|
||||||
|
if len(path_parts) >= 2 and path_parts[-1] == "__init__":
|
||||||
path_parts = path_parts[:-1]
|
path_parts = path_parts[:-1]
|
||||||
|
|
||||||
return ".".join(path_parts)
|
return ".".join(path_parts)
|
||||||
|
@ -680,7 +681,7 @@ def resolve_package_path(path: Path) -> Optional[Path]:
|
||||||
result = None
|
result = None
|
||||||
for parent in itertools.chain((path,), path.parents):
|
for parent in itertools.chain((path,), path.parents):
|
||||||
if parent.is_dir():
|
if parent.is_dir():
|
||||||
if not parent.joinpath("__init__.py").is_file():
|
if not (parent / "__init__.py").is_file():
|
||||||
break
|
break
|
||||||
if not parent.name.isidentifier():
|
if not parent.name.isidentifier():
|
||||||
break
|
break
|
||||||
|
|
|
@ -1800,9 +1800,8 @@ class Function(PyobjMixin, nodes.Item):
|
||||||
self.keywords.update(keywords)
|
self.keywords.update(keywords)
|
||||||
|
|
||||||
if fixtureinfo is None:
|
if fixtureinfo is None:
|
||||||
fixtureinfo = self.session._fixturemanager.getfixtureinfo(
|
fm = self.session._fixturemanager
|
||||||
self, self.obj, self.cls, funcargs=True
|
fixtureinfo = fm.getfixtureinfo(self, self.obj, self.cls)
|
||||||
)
|
|
||||||
self._fixtureinfo: FuncFixtureInfo = fixtureinfo
|
self._fixtureinfo: FuncFixtureInfo = fixtureinfo
|
||||||
self.fixturenames = fixtureinfo.names_closure
|
self.fixturenames = fixtureinfo.names_closure
|
||||||
self._initrequest()
|
self._initrequest()
|
||||||
|
|
|
@ -6,6 +6,7 @@ from pathlib import Path
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.compat import getfuncargnames
|
from _pytest.compat import getfuncargnames
|
||||||
from _pytest.config import ExitCode
|
from _pytest.config import ExitCode
|
||||||
|
from _pytest.fixtures import deduplicate_names
|
||||||
from _pytest.fixtures import TopRequest
|
from _pytest.fixtures import TopRequest
|
||||||
from _pytest.monkeypatch import MonkeyPatch
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
from _pytest.pytester import get_public_names
|
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.assert_outcomes(errors=1)
|
||||||
result.stdout.fnmatch_lines([expected])
|
result.stdout.fnmatch_lines([expected])
|
||||||
assert result.ret == ExitCode.TESTS_FAILED
|
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")
|
||||||
|
|
|
@ -1543,6 +1543,27 @@ class TestIssue11028:
|
||||||
result.stdout.fnmatch_lines(["*assert 4 > 5", "*where 5 = add_one(4)"])
|
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(
|
@pytest.mark.skipif(
|
||||||
sys.maxsize <= (2**31 - 1), reason="Causes OverflowError on 32bit systems"
|
sys.maxsize <= (2**31 - 1), reason="Causes OverflowError on 32bit systems"
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,6 +28,7 @@ from _pytest.pathlib import resolve_package_path
|
||||||
from _pytest.pathlib import safe_exists
|
from _pytest.pathlib import safe_exists
|
||||||
from _pytest.pathlib import symlink_or_skip
|
from _pytest.pathlib import symlink_or_skip
|
||||||
from _pytest.pathlib import visit
|
from _pytest.pathlib import visit
|
||||||
|
from _pytest.pytester import Pytester
|
||||||
from _pytest.tmpdir import TempPathFactory
|
from _pytest.tmpdir import TempPathFactory
|
||||||
|
|
||||||
|
|
||||||
|
@ -345,18 +346,18 @@ def test_resolve_package_path(tmp_path: Path) -> None:
|
||||||
(pkg / "subdir").mkdir()
|
(pkg / "subdir").mkdir()
|
||||||
(pkg / "subdir/__init__.py").touch()
|
(pkg / "subdir/__init__.py").touch()
|
||||||
assert resolve_package_path(pkg) == pkg
|
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:
|
def test_package_unimportable(tmp_path: Path) -> None:
|
||||||
pkg = tmp_path / "pkg1-1"
|
pkg = tmp_path / "pkg1-1"
|
||||||
pkg.mkdir()
|
pkg.mkdir()
|
||||||
pkg.joinpath("__init__.py").touch()
|
pkg.joinpath("__init__.py").touch()
|
||||||
subdir = pkg.joinpath("subdir")
|
subdir = pkg / "subdir"
|
||||||
subdir.mkdir()
|
subdir.mkdir()
|
||||||
pkg.joinpath("subdir/__init__.py").touch()
|
(pkg / "subdir/__init__.py").touch()
|
||||||
assert resolve_package_path(subdir) == subdir
|
assert resolve_package_path(subdir) == subdir
|
||||||
xyz = subdir.joinpath("xyz.py")
|
xyz = subdir / "xyz.py"
|
||||||
xyz.touch()
|
xyz.touch()
|
||||||
assert resolve_package_path(xyz) == subdir
|
assert resolve_package_path(xyz) == subdir
|
||||||
assert not resolve_package_path(pkg)
|
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)
|
result = module_name_from_path(tmp_path / "src/app/__init__.py", tmp_path)
|
||||||
assert result == "src.app"
|
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(
|
def test_insert_missing_modules(
|
||||||
self, monkeypatch: MonkeyPatch, tmp_path: Path
|
self, monkeypatch: MonkeyPatch, tmp_path: Path
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -663,6 +668,22 @@ class TestImportLibMode:
|
||||||
mod = import_path(init, root=tmp_path, mode=ImportMode.importlib)
|
mod = import_path(init, root=tmp_path, mode=ImportMode.importlib)
|
||||||
assert len(mod.instance.INSTANCES) == 1
|
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:
|
def test_safe_exists(tmp_path: Path) -> None:
|
||||||
d = tmp_path.joinpath("some_dir")
|
d = tmp_path.joinpath("some_dir")
|
||||||
|
|
Loading…
Reference in New Issue