Merge branch 'main' into main
This commit is contained in:
commit
4ac59d8b53
|
@ -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:
|
||||
|
|
1
AUTHORS
1
AUTHORS
|
@ -235,6 +235,7 @@ Maho
|
|||
Maik Figura
|
||||
Mandeep Bhutani
|
||||
Manuel Krebber
|
||||
Marc Mueller
|
||||
Marc Schlaich
|
||||
Marcelo Duarte Trevisani
|
||||
Marcin Bachry
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
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
|
||||
|
||||
|
|
|
@ -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.
|
||||
"""
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue