Compare commits

...

53 Commits
7.2.0 ... 7.2.2

Author SHA1 Message Date
pytest bot
4191e02598 Prepare release version 7.2.2 2023-03-03 17:05:52 +00:00
github-actions[bot]
eb50c6ce99 [7.2.x] Normalize how changelog entries are written (#10790)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-03-03 16:26:35 +00:00
github-actions[bot]
9693556f27 [7.2.x] Fix test_cmdline_python_namespace_package (#10789)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-03-03 15:52:49 +00:00
github-actions[bot]
e8e7d44a4c [7.2.x] made minor updates to fixtures docs (#10778)
Co-authored-by: Billy <william.j.kern@gmail.com>
2023-02-28 16:08:54 +00:00
github-actions[bot]
2fd4549db5 [7.2.x] docs: be more explicit about module level skip preventing collection (#10777)
Co-authored-by: Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>
2023-02-28 16:03:47 +00:00
github-actions[bot]
cee8d6f274 [7.2.x] Update import mode documentation to not refer to __import__() anymore. (#10751)
Co-authored-by: Manuel Jacob <me@manueljacob.de>
2023-02-18 18:57:56 -03:00
github-actions[bot]
79108bf9a3 [7.2.x] add CI and BUILD_NUMBER env var in docs (#10750)
Co-authored-by: bitzge <4791819+bitzge@users.noreply.github.com>
2023-02-18 18:57:28 -03:00
github-actions[bot]
779a87aada [7.2.x] Update open training (#10740)
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2023-02-15 16:07:30 +01:00
Bruno Oliveira
60216810d9 Merge pull request #10734 from pytest-dev/backport-10725-to-7.2.x
[7.2.x] Fix entry-points declaration in the documentation example using Hatch
2023-02-14 12:10:39 -03:00
Garvit Shubham
37e410fce8 [7.2.x] Fix entry-points declaration in the documentation example using Hatch 2023-02-14 14:01:18 +00:00
Bruno Oliveira
0aeb843e25 Merge pull request #10729 from nicoddemus/backport-10722
[7.2.x] Use build-and-inspect-python-package action (#10722)
2023-02-14 10:57:58 -03:00
Bruno Oliveira
1e83bd8386 Use build-and-inspect-python-package action (#10722)
This uses https://github.com/hynek/build-and-inspect-python-package to ensure our package is correct, both during testing and deploy,
2023-02-12 21:42:24 -03:00
Bruno Oliveira
02e9e8403e Merge pull request #10715 from pytest-dev/backport-10713-to-7.2.x
[7.2.x] DOCS-#10687: Add a note about -W vs filterwarnings.
2023-02-07 19:55:03 -03:00
Mahesh Vashishtha
7e1549dfb6 [7.2.x] DOCS-#10687: Add a note about -W vs filterwarnings. 2023-02-07 22:29:03 +00:00
Bruno Oliveira
d61f83c030 Merge pull request #10698 from pytest-dev/backport-10696-to-7.2.x
[7.2.x] Fix fixtures named teardown being considered by nose
2023-01-27 14:58:14 -03:00
Teejay
432a60bd52 [7.2.x] Fix fixtures named teardown being considered by nose 2023-01-27 17:35:34 +00:00
Bruno Oliveira
4b83a05939 Merge pull request #10697 from pytest-dev/backport-10695-to-7.2.x
[7.2.x] Clarify docs for `match` regarding escaping
2023-01-27 08:47:14 -03:00
vin01
4e14609b99 [7.2.x] Clarify docs for match regarding escaping 2023-01-27 11:13:22 +00:00
github-actions[bot]
76bef68f3e [7.2.x] Add check for zero denominator in approx (#10689)
Co-authored-by: Jay <43951088+jayendra-patil33@users.noreply.github.com>
2023-01-24 10:30:54 +00:00
Bruno Oliveira
af22d34158 Merge pull request #10681 from pytest-dev/backport-10664-to-7.2.x
[7.2.x] Check if config args and args_source exist
2023-01-21 08:46:56 -03:00
q0w
d1b9660402 [7.2.x] Check if config args and args_source exist 2023-01-21 11:21:12 +00:00
Bruno Oliveira
9c103aef2f Merge pull request #10673 from pytest-dev/backport-10660-to-7.2.x
[7.2.x] Derive pytest.raises from AbstractContextManager
2023-01-19 16:44:28 -03:00
Bruno Oliveira
624ae81eb1 Merge pull request #10675 from nicoddemus/backport-10608-to-7.2.x
[7.2.x] Fix crash if `--cache-show` and `--help` are passed at the same time
2023-01-19 11:35:09 -03:00
Ramsey
5bf361f24e Fix crash if --cache-show and --help are passed at the same time
Closes #10592

(cherry picked from commit 4d4ed42c34)
2023-01-19 10:06:05 -03:00
Ronny Pfannschmidt
baa938eea5 [7.2.x] Derive pytest.raises from AbstractContextManager 2023-01-18 05:44:44 +00:00
Bruno Oliveira
94c05bc2a4 Merge pull request #10659 from pytest-dev/release-7.2.1
Prepare release 7.2.1
2023-01-14 09:20:20 -03:00
pytest bot
1ae778f13e Prepare release version 7.2.1 2023-01-13 11:01:33 +00:00
Bruno Oliveira
cb07711846 Merge pull request #10656 from pytest-dev/backport-10641-to-7.2.x
[7.2.x] Dont update cache from xdist worker
2023-01-13 07:50:57 -03:00
Bruno Oliveira
944070259e Merge pull request #10657 from pytest-dev/backport-10640-to-7.2.x
[7.2.x] Fix regen tox environment
2023-01-13 07:22:04 -03:00
Bruno Oliveira
e8055c1609 [7.2.x] Fix regen tox environment 2023-01-13 10:20:49 +00:00
s-padmanaban
f22fbbf9f1 [7.2.x] Dont update cache from xdist worker 2023-01-13 10:16:42 +00:00
Bruno Oliveira
211d08e9bc Merge pull request #10638 from pytest-dev/backport-10607-to-7.2.x
[7.2.x] Mitigate directory creation race condition
2023-01-06 09:33:55 -03:00
Kadino
a6f85a0e3e [7.2.x] Mitigate directory creation race condition 2023-01-06 12:13:46 +00:00
Bruno Oliveira
08d0dd06ac Merge pull request #10637 from pytest-dev/backport-10632-to-7.2.x
[7.2.x] Fix tests pygments 2.14.0
2023-01-05 13:20:53 -03:00
Bruno Oliveira
405fd15128 [7.2.x] Fix tests pygments 2.14.0 2023-01-05 15:59:54 +00:00
Bruno Oliveira
c16315f5c3 Merge pull request #10586 from nicoddemus/backport-10578
[7.2.x] Fix tox 4.0 support and docs
2022-12-14 14:58:44 -03:00
Bruno Oliveira
f1989747b7 Fix tox 4.0 support and docs
Also includes pre-commit autoupdate
2022-12-14 09:09:43 -03:00
Bruno Oliveira
7d35baaa3c Merge pull request #10529 from pytest-dev/backport-10526-to-7.2.x
[7.2.x] Issue #10506
2022-11-23 15:47:02 -03:00
Prerak Patel
c3b0080c87 [7.2.x] Issue #10506 2022-11-23 17:49:15 +00:00
Bruno Oliveira
3c2f90b9b9 Merge pull request #10513 from pytest-dev/backport-10482-to-7.2.x
[7.2.x] issue-10457/show test name when skipping from fixture
2022-11-18 10:06:57 -03:00
Daniel Valenzuela
f5d2edc1fc [7.2.x] issue-10457/show test name when skipping from fixture 2022-11-18 12:22:15 +00:00
Bruno Oliveira
47d6adf890 Merge pull request #10489 from pytest-dev/backport-10488-to-7.2.x
[7.2.x] Fix test_raising_repr test
2022-11-09 20:46:56 -03:00
Bruno Oliveira
dbd4c5fb2f [7.2.x] Fix test_raising_repr test 2022-11-09 23:21:32 +00:00
github-actions[bot]
b2271afa65 [7.2.x] Remove done trainings (#10472)
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2022-11-04 18:50:45 +01:00
github-actions[bot]
6a5076db9f [7.2.x] Fix 'importlib.abc.TraversableResources' deprecation warning in Python 3.12 (#10453)
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
2022-10-31 16:16:34 +00:00
Bruno Oliveira
8606feb3a4 Merge pull request #10431 from pytest-dev/backport-10426-to-7.2.x
[7.2.x] Add the PyPI classifier for Python 3.11
2022-10-25 15:53:46 -03:00
Bruno Oliveira
6a4a0f43b5 Merge pull request #10430 from pytest-dev/backport-10425-to-7.2.x
[7.2.x] upgrade pygments-pytest for 7.2.x coloring
2022-10-25 15:32:05 -03:00
Bruno Oliveira
eff2e2decd Merge pull request #10432 from nicoddemus/backport-10417
[2.7.x] Use specific tag in the gh-action-pypi-publish action
2022-10-25 15:21:08 -03:00
Bruno Oliveira
23bbd5a628 Merge pull request #10417 from nicoddemus/publish-action-pin
Use specific tag in the gh-action-pypi-publish action
2022-10-25 18:19:53 -03:00
github-actions[bot]
651c7bf932 [7.2.x] Edit changelog for 7.2.0 (#10429)
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2022-10-25 18:11:35 +00:00
Santiago Castro
1f08cd7225 [7.2.x] Add the PyPI classifier for Python 3.11 2022-10-25 18:10:30 +00:00
Anthony Sottile
5c6a9a6504 [7.2.x] upgrade pygments-pytest for 7.2.x coloring 2022-10-25 17:53:54 +00:00
Ronny Pfannschmidt
ac4e3cced9 Merge pull request #10412 from pytest-dev/release-7.2.0
Prepare release 7.2.0
2022-10-25 10:58:30 +02:00
49 changed files with 491 additions and 107 deletions

View File

@@ -28,25 +28,29 @@ jobs:
fetch-depth: 0
persist-credentials: false
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5
- name: Download Package
uses: actions/download-artifact@v3
with:
name: Packages
path: dist
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.pypi_token }}
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: "3.7"
- name: Install dependencies
- name: Install tox
run: |
python -m pip install --upgrade pip
pip install --upgrade build tox
- name: Build package
run: |
python -m build
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_token }}
pip install --upgrade tox
- name: Publish GitHub release notes
env:

View File

@@ -18,6 +18,11 @@ on:
env:
PYTEST_ADDOPTS: "--color=yes"
# Cancel running jobs for the same workflow and branch.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Set permissions at the job level.
permissions: {}
@@ -189,3 +194,10 @@ jobs:
fail_ci_if_error: true
files: ./coverage.xml
verbose: true
check-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5

View File

@@ -2,7 +2,7 @@ default_language_version:
python: "3.10"
repos:
- repo: https://github.com/psf/black
rev: 22.10.0
rev: 22.12.0
hooks:
- id: black
args: [--safe, --quiet]
@@ -44,7 +44,7 @@ repos:
- id: reorder-python-imports
args: ['--application-directories=.:src', --py37-plus]
- repo: https://github.com/asottile/pyupgrade
rev: v3.1.0
rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py37-plus]
@@ -52,7 +52,7 @@ repos:
rev: v2.1.0
hooks:
- id: setup-cfg-fmt
args: ["--max-py-version=3.10", "--include-version-classifiers"]
args: ["--max-py-version=3.11", "--include-version-classifiers"]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:

View File

@@ -2,9 +2,12 @@ version: 2
python:
install:
- requirements: doc/en/requirements.txt
- method: pip
path: .
# Install pytest first, then doc/en/requirements.txt.
# This order is important to honor any pins in doc/en/requirements.txt
# when the pinned library is also a dependency of pytest.
- method: pip
path: .
- requirements: doc/en/requirements.txt
build:
os: ubuntu-20.04

View File

@@ -88,6 +88,7 @@ Daniel Grana
Daniel Hahler
Daniel Nuri
Daniel Sánchez Castelló
Daniel Valenzuela Zenteno
Daniel Wandschneider
Daniele Procida
Danielle Jenkins
@@ -285,6 +286,7 @@ Prashant Sharma
Pulkit Goyal
Punyashloka Biswal
Quentin Pradet
q0w
Ralf Schmitt
Ram Rachum
Ralph Giles
@@ -310,6 +312,7 @@ Samuel Searles-Bryant
Samuele Pedroni
Sanket Duthade
Sankt Petersbug
Saravanan Padmanaban
Segev Finer
Serhii Mozghovyi
Seth Junot
@@ -341,6 +344,7 @@ Thomas Grainger
Thomas Hisch
Tim Hoffmann
Tim Strazny
TJ Bruno
Tobias Diez
Tom Dalton
Tom Viner
@@ -372,6 +376,8 @@ Xixi Zhao
Xuan Luong
Xuecong Liao
Yoav Caspi
Yuliang Shao
Yusuke Kadowaki
Yuval Shimon
Zac Hatfield-Dodds
Zachary Kneupper

View File

@@ -6,6 +6,8 @@ Release announcements
:maxdepth: 2
release-7.2.2
release-7.2.1
release-7.2.0
release-7.1.3
release-7.1.2

View File

@@ -0,0 +1,25 @@
pytest-7.2.1
=======================================
pytest 7.2.1 has just been released to PyPI.
This is a bug-fix release, being a drop-in replacement. To upgrade::
pip install --upgrade pytest
The full changelog is available at https://docs.pytest.org/en/stable/changelog.html.
Thanks to all of the contributors to this release:
* Anthony Sottile
* Bruno Oliveira
* Daniel Valenzuela
* Kadino
* Prerak Patel
* Ronny Pfannschmidt
* Santiago Castro
* s-padmanaban
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,25 @@
pytest-7.2.2
=======================================
pytest 7.2.2 has just been released to PyPI.
This is a bug-fix release, being a drop-in replacement. To upgrade::
pip install --upgrade pytest
The full changelog is available at https://docs.pytest.org/en/stable/changelog.html.
Thanks to all of the contributors to this release:
* Bruno Oliveira
* Garvit Shubham
* Mahesh Vashishtha
* Ramsey
* Ronny Pfannschmidt
* Teejay
* q0w
* vin01
Happy testing,
The pytest Development Team

View File

@@ -22,7 +22,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
cachedir: .pytest_cache
rootdir: /home/sweet/project
collected 0 items
cache -- .../_pytest/cacheprovider.py:510
cache -- .../_pytest/cacheprovider.py:509
Return a cache object that can persist state between testing sessions.
cache.get(key, default)
@@ -119,7 +119,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
For more details: :ref:`doctest_namespace`.
pytestconfig [session scope] -- .../_pytest/fixtures.py:1351
pytestconfig [session scope] -- .../_pytest/fixtures.py:1356
Session-scoped fixture that returns the session's :class:`pytest.Config`
object.

View File

@@ -28,6 +28,63 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start
pytest 7.2.2 (2023-03-03)
=========================
Bug Fixes
---------
- `#10533 <https://github.com/pytest-dev/pytest/issues/10533>`_: Fixed :func:`pytest.approx` handling of dictionaries containing one or more values of `0.0`.
- `#10592 <https://github.com/pytest-dev/pytest/issues/10592>`_: Fixed crash if `--cache-show` and `--help` are passed at the same time.
- `#10597 <https://github.com/pytest-dev/pytest/issues/10597>`_: Fixed bug where a fixture method named ``teardown`` would be called as part of ``nose`` teardown stage.
- `#10626 <https://github.com/pytest-dev/pytest/issues/10626>`_: Fixed crash if ``--fixtures`` and ``--help`` are passed at the same time.
- `#10660 <https://github.com/pytest-dev/pytest/issues/10660>`_: Fixed :py:func:`pytest.raises` to return a 'ContextManager' so that type-checkers could narrow
:code:`pytest.raises(...) if ... else nullcontext()` down to 'ContextManager' rather than 'object'.
Improved Documentation
----------------------
- `#10690 <https://github.com/pytest-dev/pytest/issues/10690>`_: Added `CI` and `BUILD_NUMBER` environment variables to the documentation.
- `#10721 <https://github.com/pytest-dev/pytest/issues/10721>`_: Fixed entry-points declaration in the documentation example using Hatch.
- `#10753 <https://github.com/pytest-dev/pytest/issues/10753>`_: Changed wording of the module level skip to be very explicit
about not collecting tests and not executing the rest of the module.
pytest 7.2.1 (2023-01-13)
=========================
Bug Fixes
---------
- `#10452 <https://github.com/pytest-dev/pytest/issues/10452>`_: Fix 'importlib.abc.TraversableResources' deprecation warning in Python 3.12.
- `#10457 <https://github.com/pytest-dev/pytest/issues/10457>`_: If a test is skipped from inside a fixture, the test summary now shows the test location instead of the fixture location.
- `#10506 <https://github.com/pytest-dev/pytest/issues/10506>`_: Fix bug where sometimes pytest would use the file system root directory as :ref:`rootdir <rootdir>` on Windows.
- `#10607 <https://github.com/pytest-dev/pytest/issues/10607>`_: Fix a race condition when creating junitxml reports, which could occur when multiple instances of pytest execute in parallel.
- `#10641 <https://github.com/pytest-dev/pytest/issues/10641>`_: Fix a race condition when creating or updating the stepwise plugin's cache, which could occur when multiple xdist worker nodes try to simultaneously update the stepwise plugin's cache.
pytest 7.2.0 (2022-10-23)
=========================
@@ -57,6 +114,7 @@ Deprecations
.. _`with-setup-nose`: https://nose.readthedocs.io/en/latest/testing_tools.html?highlight=with_setup#nose.tools.with_setup
- `#7337 <https://github.com/pytest-dev/pytest/issues/7337>`_: A deprecation warning is now emitted if a test function returns something other than `None`. This prevents a common mistake among beginners that expect that returning a `bool` (for example `return foo(a, b) == result`) would cause a test to pass or fail, instead of using `assert`. The plan is to make returning non-`None` from tests an error in the future.
Features
@@ -79,10 +137,7 @@ Improvements
- `#10381 <https://github.com/pytest-dev/pytest/issues/10381>`_: The ``--no-showlocals`` flag has been added. This can be passed directly to tests to override ``--showlocals`` declared through ``addopts``.
- `#3426 <https://github.com/pytest-dev/pytest/issues/3426>`_: Assertion failures with strings in NFC and NFD forms that normalize to the same string now have a dedicated error message detailing the issue, and their utf-8 representation is expresed instead.
- `#7337 <https://github.com/pytest-dev/pytest/issues/7337>`_: A warning is now emitted if a test function returns something other than `None`. This prevents a common mistake among beginners that expect that returning a `bool` (for example `return foo(a, b) == result`) would cause a test to pass or fail, instead of using `assert`.
- `#3426 <https://github.com/pytest-dev/pytest/issues/3426>`_: Assertion failures with strings in NFC and NFD forms that normalize to the same string now have a dedicated error message detailing the issue, and their utf-8 representation is expressed instead.
- `#8508 <https://github.com/pytest-dev/pytest/issues/8508>`_: Introduce multiline display for warning matching via :py:func:`pytest.warns` and
@@ -95,7 +150,7 @@ Improvements
- `#9741 <https://github.com/pytest-dev/pytest/issues/9741>`_: On Python 3.11, use the standard library's :mod:`tomllib` to parse TOML.
:mod:`tomli`` is no longer a dependency on Python 3.11.
:mod:`tomli` is no longer a dependency on Python 3.11.
- `#9742 <https://github.com/pytest-dev/pytest/issues/9742>`_: Display assertion message without escaped newline characters with ``-vv``.
@@ -110,7 +165,7 @@ Improvements
- `#9883 <https://github.com/pytest-dev/pytest/issues/9883>`_: Normalize the help description of all command-line options.
- `#9920 <https://github.com/pytest-dev/pytest/issues/9920>`_: Display full crash messages in ``short test summary info``, when runng in a CI environment.
- `#9920 <https://github.com/pytest-dev/pytest/issues/9920>`_: Display full crash messages in ``short test summary info``, when running in a CI environment.
- `#9987 <https://github.com/pytest-dev/pytest/issues/9987>`_: Added support for hidden configuration file by allowing ``.pytest.ini`` as an alternative to ``pytest.ini``.
@@ -156,9 +211,6 @@ Improved Documentation
Trivial/Internal Changes
------------------------
- `#10196 <https://github.com/pytest-dev/pytest/issues/10196>`_: :class:`~pytest.PytestReturnNotNoneWarning` is now a subclass of :class:`~pytest.PytestRemovedIn8Warning`: the plan is to make returning non-``None`` from tests an error in the future.
- `#10313 <https://github.com/pytest-dev/pytest/issues/10313>`_: Made ``_pytest.doctest.DoctestItem`` export ``pytest.DoctestItem`` for
type check and runtime purposes. Made `_pytest.doctest` use internal APIs
to avoid circular imports.
@@ -173,7 +225,7 @@ Trivial/Internal Changes
- `#9984 <https://github.com/pytest-dev/pytest/issues/9984>`_: Improve the error message when we attempt to access a fixture that has been
torn down.
Add an additional sentence to the docstring explaining when it's not a good
idea to call getfixturevalue.
idea to call ``getfixturevalue``.
pytest 7.1.3 (2022-08-31)

View File

@@ -17,7 +17,7 @@ def b(a, order):
@pytest.fixture
def c(a, b, order):
def c(b, order):
order.append("c")

View File

@@ -504,9 +504,9 @@ Running it results in some skips if we don't have all the python interpreters in
. $ pytest -rs -q multipython.py
sssssssssssssssssssssssssss [100%]
========================= short test summary info ==========================
SKIPPED [9] multipython.py:29: 'python3.5' not found
SKIPPED [9] multipython.py:29: 'python3.6' not found
SKIPPED [9] multipython.py:29: 'python3.7' not found
SKIPPED [9] multipython.py:69: 'python3.5' not found
SKIPPED [9] multipython.py:69: 'python3.6' not found
SKIPPED [9] multipython.py:69: 'python3.7' not found
27 skipped in 0.12s
Indirect parametrization of optional implementations/imports
@@ -574,7 +574,7 @@ If you run this with reporting for skips enabled:
test_module.py .s [100%]
========================= short test summary info ==========================
SKIPPED [1] conftest.py:12: could not import 'opt2': No module named 'opt2'
SKIPPED [1] test_module.py:3: could not import 'opt2': No module named 'opt2'
======================= 1 passed, 1 skipped in 0.12s =======================
You'll see that we don't have an ``opt2`` module and thus the second test run

View File

@@ -270,8 +270,8 @@ tox
Once you are done with your work and want to make sure that your actual
package passes all tests you may want to look into :doc:`tox <tox:index>`, the
virtualenv test automation tool and its :doc:`pytest support <tox:example/pytest>`.
tox helps you to setup virtualenv environments with pre-defined
virtualenv test automation tool.
``tox`` helps you to setup virtualenv environments with pre-defined
dependencies and then executing a pre-configured test command with
options. It will run tests against the installed package and not
against your source code checkout, helping to detect packaging

View File

@@ -16,7 +16,7 @@ import process can be controlled through the ``--import-mode`` command-line flag
these values:
* ``prepend`` (default): the directory path containing each module will be inserted into the *beginning*
of :py:data:`sys.path` if not already there, and then imported with the :func:`__import__ <__import__>` builtin.
of :py:data:`sys.path` if not already there, and then imported with the :func:`importlib.import_module <importlib.import_module>` function.
This requires test module names to be unique when the test directory tree is not arranged in
packages, because the modules will put in :py:data:`sys.modules` after importing.
@@ -24,7 +24,7 @@ these values:
This is the classic mechanism, dating back from the time Python 2 was still supported.
* ``append``: the directory containing each module is appended to the end of :py:data:`sys.path` if not already
there, and imported with ``__import__``.
there, and imported with :func:`importlib.import_module <importlib.import_module>`.
This better allows to run test modules against installed versions of a package even if the
package under test has the same import root. For example:
@@ -43,7 +43,7 @@ these values:
Same as ``prepend``, requires test module names to be unique when the test directory tree is
not arranged in packages, because the modules will put in :py:data:`sys.modules` after importing.
* ``importlib``: new in pytest-6.0, this mode uses :mod:`importlib` to import test modules. This gives full control over the import process, and doesn't require changing :py:data:`sys.path`.
* ``importlib``: new in pytest-6.0, this mode uses more fine control mechanisms provided by :mod:`importlib` to import test modules. This gives full control over the import process, and doesn't require changing :py:data:`sys.path`.
For this reason this doesn't require test module names to be unique.

View File

@@ -22,7 +22,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
pytest 7.2.0
pytest 7.2.2
.. _`simpletest`:

View File

@@ -109,6 +109,18 @@ When a warning matches more than one option in the list, the action for the last
is performed.
.. note::
The ``-W`` flag and the ``filterwarnings`` ini option use warning filters that are
similar in structure, but each configuration option interprets its filter
differently. For example, *message* in ``filterwarnings`` is a string containing a
regular expression that the start of the warning message must match,
case-insensitively, while *message* in ``-W`` is a literal string that the start of
the warning message must contain (case-insensitively), ignoring any whitespace at
the start or end of message. Consult the `warning filter`_ documentation for more
details.
.. _`filterwarnings`:
``@pytest.mark.filterwarnings``
@@ -270,20 +282,34 @@ which works in a similar manner to :ref:`raises <assertraises>` (except that
warnings.warn("my warning", UserWarning)
The test will fail if the warning in question is not raised. Use the keyword
argument ``match`` to assert that the warning matches a text or regex::
argument ``match`` to assert that the warning matches a text or regex.
To match a literal string that may contain regular expression metacharacters like ``(`` or ``.``, the pattern can
first be escaped with ``re.escape``.
>>> with warns(UserWarning, match='must be 0 or None'):
Some examples:
.. code-block:: pycon
>>> with warns(UserWarning, match="must be 0 or None"):
... warnings.warn("value must be 0 or None", UserWarning)
...
>>> with warns(UserWarning, match=r'must be \d+$'):
>>> with warns(UserWarning, match=r"must be \d+$"):
... warnings.warn("value must be 42", UserWarning)
...
>>> with warns(UserWarning, match=r'must be \d+$'):
>>> with warns(UserWarning, match=r"must be \d+$"):
... warnings.warn("this is not here", UserWarning)
...
Traceback (most recent call last):
...
Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted...
>>> with warns(UserWarning, match=re.escape("issue with foo() func")):
... warnings.warn("issue with foo() func")
...
You can also call :func:`pytest.warns` on a function or code string:
.. code-block:: python

View File

@@ -167,13 +167,8 @@ it in your ``pyproject.toml`` file.
"Framework :: Pytest",
]
[tool.setuptools]
packages = ["myproject"]
[project.entry_points]
pytest11 = [
"myproject = myproject.pluginmodule",
]
[project.entry-points.pytest11]
myproject = "myproject.pluginmodule"
If a package is installed this way, ``pytest`` will load
``myproject.pluginmodule`` as a plugin which can define

View File

@@ -2,8 +2,7 @@
.. sidebar:: Next Open Trainings
- Professionelles Testen für Python mit pytest, part of `enterPy <https://www.enterpy.de/>`__ (German), `October 28th <https://www.enterpy.de/veranstaltung-15409-se-0-professionelles-testen-fuer-python-mit-pytest.html>`__ (sold out) and `November 4th <https://www.enterpy.de/veranstaltung-15557-se-0-professionelles-testen-fuer-python-mit-pytest-zusatztermin.html>`__, online
- `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 7th to 9th 2023 (3 day in-depth training), Remote and Leipzig, Germany
- `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 7th to 9th 2023 (3 day in-depth training), Remote
Also see :doc:`previous talks and blogposts <talks>`.

View File

@@ -335,7 +335,7 @@ For example:
.. literalinclude:: /example/fixtures/test_fixtures_order_dependencies.py
If we map out what depends on what, we get something that look like this:
If we map out what depends on what, we get something that looks like this:
.. image:: /example/fixtures/test_fixtures_order_dependencies.*
:align: center

View File

@@ -1047,6 +1047,14 @@ Environment Variables
Environment variables that can be used to change pytest's behavior.
.. envvar:: CI
When set (regardless of value), pytest acknowledges that is running in a CI process. Alterative to ``BUILD_NUMBER`` variable.
.. envvar:: BUILD_NUMBER
When set (regardless of value), pytest acknowledges that is running in a CI process. Alterative to CI variable.
.. envvar:: PYTEST_ADDOPTS
This contains a command-line (parsed by the py:mod:`shlex` module) that will be **prepended** to the command line given

View File

@@ -1,7 +1,11 @@
pallets-sphinx-themes
pluggy>=1.0
pygments-pytest>=2.2.0
pygments-pytest>=2.3.0
sphinx-removed-in>=0.2.0
sphinx>=5,<6
sphinxcontrib-trio
sphinxcontrib-svg2pdfconverter
# Pin packaging because it no longer handles 'latest' version, which
# is the version that is assigned to the docs.
# See https://github.com/pytest-dev/pytest/pull/10578#issuecomment-1348249045.
packaging <22

View File

@@ -114,3 +114,8 @@ template = "changelog/_template.rst"
[tool.black]
target-version = ['py37']
# check-wheel-contents is executed by the build-and-inspect-python-package action.
[tool.check-wheel-contents]
# W009: Wheel contains multiple toplevel library entries
ignore = "W009"

View File

@@ -21,6 +21,7 @@ classifiers =
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Topic :: Software Development :: Libraries
Topic :: Software Development :: Testing
Topic :: Utilities

View File

@@ -275,7 +275,12 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
if sys.version_info >= (3, 10):
def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore
if sys.version_info >= (3, 12):
from importlib.resources.abc import TraversableResources
else:
from importlib.abc import TraversableResources
def get_resource_reader(self, name: str) -> TraversableResources: # type: ignore
if sys.version_info < (3, 11):
from importlib.readers import FileReader
else:

View File

@@ -32,7 +32,6 @@ from _pytest.python import Module
from _pytest.python import Package
from _pytest.reports import TestReport
README_CONTENT = """\
# pytest cache directory #
@@ -492,7 +491,7 @@ def pytest_addoption(parser: Parser) -> None:
def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
if config.option.cacheshow:
if config.option.cacheshow and not config.option.help:
from _pytest.main import wrap_session
return wrap_session(config, cacheshow)

View File

@@ -998,6 +998,8 @@ class Config:
self.hook.pytest_addoption.call_historic(
kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager)
)
self.args_source = Config.ArgsSource.ARGS
self.args: List[str] = []
if TYPE_CHECKING:
from _pytest.cacheprovider import Cache
@@ -1337,8 +1339,8 @@ class Config:
def parse(self, args: List[str], addopts: bool = True) -> None:
# Parse given cmdline arguments into this config object.
assert not hasattr(
self, "args"
assert (
self.args == []
), "can only parse cmdline args at most once per Config object"
self.hook.pytest_addhooks.call_historic(
kwargs=dict(pluginmanager=self.pluginmanager)

View File

@@ -203,8 +203,7 @@ def determine_setup(
else:
cwd = Path.cwd()
rootdir = get_common_ancestor([cwd, ancestor])
is_fs_root = os.path.splitdrive(str(rootdir))[1] == "/"
if is_fs_root:
if is_fs_root(rootdir):
rootdir = ancestor
if rootdir_cmd_arg:
rootdir = absolutepath(os.path.expandvars(rootdir_cmd_arg))
@@ -216,3 +215,11 @@ def determine_setup(
)
assert rootdir is not None
return rootdir, inipath, inicfg or {}
def is_fs_root(p: Path) -> bool:
r"""
Return True if the given path is pointing to the root of the
file system ("/" on Unix and "C:\\" on Windows for example).
"""
return os.path.splitdrive(str(p))[1] == os.sep

View File

@@ -58,6 +58,7 @@ from _pytest.mark import Mark
from _pytest.mark import ParameterSet
from _pytest.mark.structures import MarkDecorator
from _pytest.outcomes import fail
from _pytest.outcomes import skip
from _pytest.outcomes import TEST_OUTCOME
from _pytest.pathlib import absolutepath
from _pytest.pathlib import bestrelpath
@@ -1129,6 +1130,10 @@ def pytest_fixture_setup(
except TEST_OUTCOME:
exc_info = sys.exc_info()
assert exc_info[0] is not None
if isinstance(
exc_info[1], skip.Exception
) and not fixturefunc.__name__.startswith("xunit_setup"):
exc_info[1]._use_item_location = True # type: ignore[attr-defined]
fixturedef.cached_result = (None, my_cache_key, exc_info)
raise
fixturedef.cached_result = (result, my_cache_key, None)

View File

@@ -645,8 +645,8 @@ class LogXML:
def pytest_sessionfinish(self) -> None:
dirname = os.path.dirname(os.path.abspath(self.logfile))
if not os.path.isdir(dirname):
os.makedirs(dirname)
# exist_ok avoids filesystem race conditions between checking path existence and requesting creation
os.makedirs(dirname, exist_ok=True)
with open(self.logfile, "w", encoding="utf-8") as logfile:
suite_stop_time = timing.time()

View File

@@ -157,8 +157,12 @@ def skip(
The message to show the user as reason for the skip.
:param allow_module_level:
Allows this function to be called at module level, skipping the rest
of the module. Defaults to False.
Allows this function to be called at module level.
Raising the skip exception at module level will stop
the execution of the module and prevent the collection of all tests in the module,
even those defined before the `skip` call.
Defaults to False.
:param msg:
Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead.

View File

@@ -464,14 +464,14 @@ def import_path(
* `mode == ImportMode.prepend`: the directory containing the module (or package, taking
`__init__.py` files into account) will be put at the *start* of `sys.path` before
being imported with `__import__.
being imported with `importlib.import_module`.
* `mode == ImportMode.append`: same as `prepend`, but the directory will be appended
to the end of `sys.path`, if not already in `sys.path`.
* `mode == ImportMode.importlib`: uses more fine control mechanisms provided by `importlib`
to import the module, which avoids having to use `__import__` and muck with `sys.path`
at all. It effectively allows having same-named test modules in different places.
to import the module, which avoids having to muck with `sys.path` at all. It effectively
allows having same-named test modules in different places.
:param root:
Used as an anchor when mode == ImportMode.importlib to obtain

View File

@@ -848,7 +848,7 @@ class Class(PyCollector):
other fixtures (#517).
"""
setup_class = _get_first_non_fixture_func(self.obj, ("setup_class",))
teardown_class = getattr(self.obj, "teardown_class", None)
teardown_class = _get_first_non_fixture_func(self.obj, ("teardown_class",))
if setup_class is None and teardown_class is None:
return
@@ -885,12 +885,12 @@ class Class(PyCollector):
emit_nose_setup_warning = True
setup_method = _get_first_non_fixture_func(self.obj, (setup_name,))
teardown_name = "teardown_method"
teardown_method = getattr(self.obj, teardown_name, None)
teardown_method = _get_first_non_fixture_func(self.obj, (teardown_name,))
emit_nose_teardown_warning = False
if teardown_method is None and has_nose:
teardown_name = "teardown"
emit_nose_teardown_warning = True
teardown_method = getattr(self.obj, teardown_name, None)
teardown_method = _get_first_non_fixture_func(self.obj, (teardown_name,))
if setup_method is None and teardown_method is None:
return

View File

@@ -8,7 +8,7 @@ from types import TracebackType
from typing import Any
from typing import Callable
from typing import cast
from typing import Generic
from typing import ContextManager
from typing import List
from typing import Mapping
from typing import Optional
@@ -269,10 +269,16 @@ class ApproxMapping(ApproxBase):
max_abs_diff = max(
max_abs_diff, abs(approx_value.expected - other_value)
)
max_rel_diff = max(
max_rel_diff,
abs((approx_value.expected - other_value) / approx_value.expected),
)
if approx_value.expected == 0.0:
max_rel_diff = math.inf
else:
max_rel_diff = max(
max_rel_diff,
abs(
(approx_value.expected - other_value)
/ approx_value.expected
),
)
different_ids.append(approx_key)
message_data = [
@@ -957,7 +963,7 @@ raises.Exception = fail.Exception # type: ignore
@final
class RaisesContext(Generic[E]):
class RaisesContext(ContextManager[_pytest._code.ExceptionInfo[E]]):
def __init__(
self,
expected_exception: Union[Type[E], Tuple[Type[E], ...]],

View File

@@ -48,6 +48,10 @@ def pytest_configure(config: Config) -> None:
def pytest_sessionfinish(session: Session) -> None:
if not session.config.getoption("stepwise"):
assert session.config.cache is not None
if hasattr(session.config, "workerinput"):
# Do not update cache if this process is a xdist worker to prevent
# race conditions (#10641).
return
# Clear the list of failing tests if the plugin is not active.
session.config.cache.set(STEPWISE_CACHE_DIR, [])
@@ -119,4 +123,8 @@ class StepwisePlugin:
return None
def pytest_sessionfinish(self) -> None:
if hasattr(self.config, "workerinput"):
# Do not update cache if this process is a xdist worker to prevent
# race conditions (#10641).
return
self.cache.set(STEPWISE_CACHE_DIR, self.lastfailed)

View File

@@ -694,7 +694,14 @@ class TestInvocationVariants:
# mixed module and filenames:
monkeypatch.chdir("world")
result = pytester.runpytest("--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world")
# pgk_resources.declare_namespace has been deprecated in favor of implicit namespace packages.
# While we could change the test to use implicit namespace packages, seems better
# to still ensure the old declaration via declare_namespace still works.
ignore_w = r"-Wignore:Deprecated call to `pkg_resources.declare_namespace"
result = pytester.runpytest(
"--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world", ignore_w
)
assert result.ret == 0
result.stdout.fnmatch_lines(
[

View File

@@ -157,6 +157,7 @@ def color_mapping():
"number": "\x1b[94m",
"str": "\x1b[33m",
"print": "\x1b[96m",
"endline": "\x1b[90m\x1b[39;49;00m",
}
RE_COLORS = {k: re.escape(v) for k, v in COLORS.items()}

View File

@@ -254,7 +254,7 @@ class TestTerminalWriterLineWidth:
pytest.param(
True,
True,
"{kw}assert{hl-reset} {number}0{hl-reset}\n",
"{kw}assert{hl-reset} {number}0{hl-reset}{endline}\n",
id="with markup and code_highlight",
),
pytest.param(

View File

@@ -630,6 +630,19 @@ class TestApprox:
def test_dict_vs_other(self):
assert 1 != approx({"a": 0})
def test_dict_for_div_by_zero(self, assert_approx_raises_regex):
assert_approx_raises_regex(
{"foo": 42.0},
{"foo": 0.0},
[
r" comparison failed. Mismatched elements: 1 / 1:",
rf" Max absolute difference: {SOME_FLOAT}",
r" Max relative difference: inf",
r" Index \| Obtained\s+\| Expected ",
rf" foo | {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
],
)
def test_numpy_array(self):
np = pytest.importorskip("numpy")

View File

@@ -3338,6 +3338,10 @@ class TestShowFixtures:
config = pytester.parseconfigure("--funcargs")
assert config.option.showfixtures
def test_show_help(self, pytester: Pytester) -> None:
result = pytester.runpytest("--fixtures", "--help")
assert not result.ret
def test_show_fixtures(self, pytester: Pytester) -> None:
result = pytester.runpytest("--fixtures")
result.stdout.fnmatch_lines(

View File

@@ -1664,15 +1664,7 @@ def test_raise_assertion_error_raising_repr(pytester: Pytester) -> None:
"""
)
result = pytester.runpytest()
if sys.version_info >= (3, 11):
# python 3.11 has native support for un-str-able exceptions
result.stdout.fnmatch_lines(
["E AssertionError: <exception str() failed>"]
)
else:
result.stdout.fnmatch_lines(
["E AssertionError: <unprintable AssertionError object>"]
)
result.stdout.fnmatch_lines(["E AssertionError: <exception str() failed>"])
def test_issue_1944(pytester: Pytester) -> None:

View File

@@ -1249,3 +1249,8 @@ def test_cachedir_tag(pytester: Pytester) -> None:
cache.set("foo", "bar")
cachedir_tag_path = cache._cachedir.joinpath("CACHEDIR.TAG")
assert cachedir_tag_path.read_bytes() == CACHEDIR_TAG_CONTENT
def test_clioption_with_cacheshow_and_help(pytester: Pytester) -> None:
result = pytester.runpytest("--cache-show", "--help")
assert result.ret == 0

View File

@@ -1,3 +1,4 @@
import os
from pathlib import Path
from textwrap import dedent
@@ -5,6 +6,7 @@ import pytest
from _pytest.config import UsageError
from _pytest.config.findpaths import get_common_ancestor
from _pytest.config.findpaths import get_dirs_from_args
from _pytest.config.findpaths import is_fs_root
from _pytest.config.findpaths import load_config_dict_from_file
@@ -133,3 +135,18 @@ def test_get_dirs_from_args(tmp_path):
assert get_dirs_from_args(
[str(fn), str(tmp_path / "does_not_exist"), str(d), option, xdist_rsync_option]
) == [fn.parent, d]
@pytest.mark.parametrize(
"path, expected",
[
pytest.param(
f"e:{os.sep}", True, marks=pytest.mark.skipif("sys.platform != 'win32'")
),
(f"{os.sep}", True),
(f"e:{os.sep}projects", False),
(f"{os.sep}projects", False),
],
)
def test_is_fs_root(path: Path, expected: bool) -> None:
assert is_fs_root(Path(path)) is expected

View File

@@ -425,6 +425,9 @@ def test_context_classmethod() -> None:
assert A.x == 1
@pytest.mark.filterwarnings(
"ignore:Deprecated call to `pkg_resources.declare_namespace"
)
def test_syspath_prepend_with_namespace_packages(
pytester: Pytester, monkeypatch: MonkeyPatch
) -> None:

View File

@@ -496,3 +496,24 @@ def test_nose_setup_skipped_if_non_callable(pytester: Pytester) -> None:
)
result = pytester.runpytest(p, "-p", "nose")
assert result.ret == 0
@pytest.mark.parametrize("fixture_name", ("teardown", "teardown_class"))
def test_teardown_fixture_not_called_directly(fixture_name, pytester: Pytester) -> None:
"""Regression test for #10597."""
p = pytester.makepyfile(
f"""
import pytest
class TestHello:
@pytest.fixture
def {fixture_name}(self):
yield
def test_hello(self, {fixture_name}):
assert True
"""
)
result = pytester.runpytest(p, "-p", "nose")
assert result.ret == 0

View File

@@ -1439,6 +1439,27 @@ def test_relpath_rootdir(pytester: Pytester) -> None:
)
def test_skip_from_fixture(pytester: Pytester) -> None:
pytester.makepyfile(
**{
"tests/test_1.py": """
import pytest
def test_pass(arg):
pass
@pytest.fixture
def arg():
condition = True
if condition:
pytest.skip("Fixture conditional skip")
""",
}
)
result = pytester.runpytest("-rs", "tests/test_1.py", "--rootdir=tests")
result.stdout.fnmatch_lines(
["SKIPPED [[]1[]] tests/test_1.py:2: Fixture conditional skip"]
)
def test_skip_using_reason_works_ok(pytester: Pytester) -> None:
p = pytester.makepyfile(
"""

View File

@@ -1,6 +1,10 @@
from pathlib import Path
import pytest
from _pytest.cacheprovider import Cache
from _pytest.monkeypatch import MonkeyPatch
from _pytest.pytester import Pytester
from _pytest.stepwise import STEPWISE_CACHE_DIR
@pytest.fixture
@@ -278,3 +282,76 @@ def test_stepwise_skip_is_independent(pytester: Pytester) -> None:
def test_sw_skip_help(pytester: Pytester) -> None:
result = pytester.runpytest("-h")
result.stdout.fnmatch_lines("*Implicitly enables --stepwise.")
def test_stepwise_xdist_dont_store_lastfailed(pytester: Pytester) -> None:
pytester.makefile(
ext=".ini",
pytest=f"[pytest]\ncache_dir = {pytester.path}\n",
)
pytester.makepyfile(
conftest="""
import pytest
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config) -> None:
config.workerinput = True
"""
)
pytester.makepyfile(
test_one="""
def test_one():
assert False
"""
)
result = pytester.runpytest("--stepwise")
assert result.ret == pytest.ExitCode.INTERRUPTED
stepwise_cache_file = (
pytester.path / Cache._CACHE_PREFIX_VALUES / STEPWISE_CACHE_DIR
)
assert not Path(stepwise_cache_file).exists()
def test_disabled_stepwise_xdist_dont_clear_cache(pytester: Pytester) -> None:
pytester.makefile(
ext=".ini",
pytest=f"[pytest]\ncache_dir = {pytester.path}\n",
)
stepwise_cache_file = (
pytester.path / Cache._CACHE_PREFIX_VALUES / STEPWISE_CACHE_DIR
)
stepwise_cache_dir = stepwise_cache_file.parent
stepwise_cache_dir.mkdir(exist_ok=True, parents=True)
stepwise_cache_file_relative = f"{Cache._CACHE_PREFIX_VALUES}/{STEPWISE_CACHE_DIR}"
expected_value = '"test_one.py::test_one"'
content = {f"{stepwise_cache_file_relative}": expected_value}
pytester.makefile(ext="", **content)
pytester.makepyfile(
conftest="""
import pytest
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config) -> None:
config.workerinput = True
"""
)
pytester.makepyfile(
test_one="""
def test_one():
assert True
"""
)
result = pytester.runpytest()
assert result.ret == 0
assert Path(stepwise_cache_file).exists()
with stepwise_cache_file.open() as file_handle:
observed_value = file_handle.readlines()
assert [expected_value] == observed_value

View File

@@ -1265,14 +1265,14 @@ def test_color_yes(pytester: Pytester, color_mapping) -> None:
"=*= FAILURES =*=",
"{red}{bold}_*_ test_this _*_{reset}",
"",
" {kw}def{hl-reset} {function}test_this{hl-reset}():",
"> fail()",
" {kw}def{hl-reset} {function}test_this{hl-reset}():{endline}",
"> fail(){endline}",
"",
"{bold}{red}test_color_yes.py{reset}:5: ",
"_ _ * _ _*",
"",
" {kw}def{hl-reset} {function}fail{hl-reset}():",
"> {kw}assert{hl-reset} {number}0{hl-reset}",
" {kw}def{hl-reset} {function}fail{hl-reset}():{endline}",
"> {kw}assert{hl-reset} {number}0{hl-reset}{endline}",
"{bold}{red}E assert 0{reset}",
"",
"{bold}{red}test_color_yes.py{reset}:2: AssertionError",
@@ -1292,9 +1292,9 @@ def test_color_yes(pytester: Pytester, color_mapping) -> None:
"=*= FAILURES =*=",
"{red}{bold}_*_ test_this _*_{reset}",
"{bold}{red}test_color_yes.py{reset}:5: in test_this",
" fail()",
" fail(){endline}",
"{bold}{red}test_color_yes.py{reset}:2: in fail",
" {kw}assert{hl-reset} {number}0{hl-reset}",
" {kw}assert{hl-reset} {number}0{hl-reset}{endline}",
"{bold}{red}E assert 0{reset}",
"{red}=*= {red}{bold}1 failed{reset}{red} in *s{reset}{red} =*={reset}",
]
@@ -2472,8 +2472,8 @@ class TestCodeHighlight:
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}",
" {kw}def{hl-reset} {function}test_foo{hl-reset}():{endline}",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}{endline}",
"{bold}{red}E assert 1 == 10{reset}",
]
)
@@ -2494,9 +2494,9 @@ class TestCodeHighlight:
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
" {kw}def{hl-reset} {function}test_foo{hl-reset}():{endline}",
" {print}print{hl-reset}({str}'''{hl-reset}{str}{hl-reset}",
"> {str} {hl-reset}{str}'''{hl-reset}); {kw}assert{hl-reset} {number}0{hl-reset}",
"> {str} {hl-reset}{str}'''{hl-reset}); {kw}assert{hl-reset} {number}0{hl-reset}{endline}",
"{bold}{red}E assert 0{reset}",
]
)
@@ -2517,8 +2517,8 @@ class TestCodeHighlight:
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}",
" {kw}def{hl-reset} {function}test_foo{hl-reset}():{endline}",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}{endline}",
"{bold}{red}E assert 1 == 10{reset}",
]
)

View File

@@ -3,6 +3,11 @@
This file is not executed, it is only checked by mypy to ensure that
none of the code triggers any mypy errors.
"""
import contextlib
from typing import Optional
from typing_extensions import assert_type
import pytest
@@ -22,3 +27,9 @@ def check_fixture_ids_callable() -> None:
@pytest.mark.parametrize("func", [str, int], ids=lambda x: str(x.__name__))
def check_parametrize_ids_callable(func) -> None:
pass
def check_raises_is_a_context_manager(val: bool) -> None:
with pytest.raises(RuntimeError) if val else contextlib.nullcontext() as excinfo:
pass
assert_type(excinfo, Optional[pytest.ExceptionInfo[RuntimeError]])

17
tox.ini
View File

@@ -9,6 +9,7 @@ envlist =
py39
py310
py311
py312
pypy3
py37-{pexpect,xdist,unittestextras,numpy,pluggymain,pylib}
doctesting
@@ -29,7 +30,11 @@ commands =
doctesting: {env:_PYTEST_TOX_COVERAGE_RUN:} pytest --doctest-modules --pyargs _pytest
coverage: coverage combine
coverage: coverage report -m
passenv = USER USERNAME COVERAGE_* PYTEST_ADDOPTS TERM SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
passenv =
COVERAGE_*
PYTEST_ADDOPTS
TERM
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
setenv =
_PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_DOCTESTING:} {env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_XDIST:}
@@ -92,13 +97,14 @@ commands =
[testenv:regen]
changedir = doc/en
basepython = python3
passenv = SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
passenv =
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
deps =
dataclasses
PyYAML
regendoc>=0.8.1
sphinx
whitelist_externals =
allowlist_externals =
make
commands =
make regen
@@ -160,7 +166,10 @@ commands = python scripts/prepare-release-pr.py {posargs}
description = create GitHub release after deployment
basepython = python3
usedevelop = True
passenv = GH_RELEASE_NOTES_TOKEN GITHUB_REF GITHUB_REPOSITORY
passenv =
GH_RELEASE_NOTES_TOKEN
GITHUB_REF
GITHUB_REPOSITORY
deps =
github3.py
pypandoc