Compare commits

...

800 Commits

Author SHA1 Message Date
Bruno Oliveira
9eecdc7dae Merge pull request #12260 from nicoddemus/cherry-pick-release
Cherry-pick release pytest-dev/release-8.2.0
2024-04-27 20:41:36 -03:00
Bruno Oliveira
79ca819e59 Merge pull request #12257 from pytest-dev/release-8.2.0
Prepare release 8.2.0

(cherry picked from commit 69c3bcea36)
2024-04-27 20:36:02 -03:00
Bruno Oliveira
835765c9d3 Merge pull request #12130 from bluetech/fixtures-inline
fixtures: inline some functions to streamline the code
2024-04-27 10:01:36 -03:00
Daniel Miller
7e7503c0b0 unittest: report class cleanup exceptions (#12250)
Fixes #11728

---------

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2024-04-27 09:49:05 -03:00
Ran Benita
882c4da2f3 fixtures: inline fail_fixturefunc
Doesn't add much.
2024-04-27 09:48:14 -03:00
Ran Benita
2e8fb9f140 fixtures: extract a _check_fixturedef method
This stuff is less interesting when reading `_get_active_fixturedef`.
2024-04-27 09:48:14 -03:00
Ran Benita
acf2971f46 fixtures: inline _getnextfixturedef into _get_active_fixturedef 2024-04-27 09:48:14 -03:00
Ran Benita
3c77aec1da fixtures: move "request" check early 2024-04-27 09:48:14 -03:00
Ran Benita
d217d68cde fixtures: inline _compute_fixture_value 2024-04-27 09:48:14 -03:00
Ran Benita
530be28575 fixtures: use early return in _get_active_fixturedef 2024-04-27 09:48:14 -03:00
Bruno Oliveira
d208c1d4a5 Merge pull request #12256 from bluetech/misc2
2 small cleanups
2024-04-27 09:39:16 -03:00
Ran Benita
80ca255d42 pathlib: make absolutepath support os.PathLike[str]
This slightly simplifies a bit of path.
2024-04-27 11:53:01 +03:00
Ran Benita
1a332802ff Avoid slicing sys.version_info in version conditionals
It is unnecessary, and some static analyzers don't handle it.
2024-04-27 01:14:21 +03:00
Bruno Oliveira
93c2cdf6d6 cherry-pick release-8.1.2 (#12252)
(cherry picked from commit 7df3dbc545)
2024-04-26 15:25:44 -03:00
Shekhar verma
4eb8b6d525 Changed importError to ModuleNotFoundError (#12220)
* Changed importError to ModuleNotFoundError

* added testing for importorskip

* added exc_types parameter in importorskip

* Added warning and Test Cases

* Improve tests and docs

* Improve deprecation docs

* Change exc_type to kw only

* Apply suggestions from code review

Co-authored-by: Florian Bruhin <me@the-compiler.org>

* Fix check

---------

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2024-04-26 09:48:57 +02:00
pre-commit-ci[bot]
fafab1dbfd [pre-commit.ci] pre-commit autoupdate (#12238)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.7 → v0.4.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.7...v0.4.1)
- [github.com/tox-dev/pyproject-fmt: 1.7.0 → 1.8.0](https://github.com/tox-dev/pyproject-fmt/compare/1.7.0...1.8.0)

* noqa a test

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
2024-04-23 11:59:12 -03:00
poulami-sau
5cffef7f07 Fixed Bug Regarding Attribute Error in pytest.approx For Types Implicitly Convertible to Numpy Arrays (#12232)
* added test case in testing/python/approx.py based on test case provided by reporter in issue #12114
* test cases pass for pytest testing/python/approx.py
* expanded the type annotation to include objects which may cast to a array and renamed other_side to other_side_as_array and asserted that it is not none
2024-04-23 10:45:33 +02:00
Florian Bruhin
a830a3e98d Update events/trainings (#12236) 2024-04-22 19:52:25 +02:00
dependabot[bot]
1d322ffb48 build(deps): Bump peter-evans/create-pull-request from 6.0.3 to 6.0.4 (#12233)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.3 to 6.0.4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](c55203cfde...9153d834b6)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 11:54:48 +02:00
github-actions[bot]
63d985c6d3 [automated] Update plugin list (#12230)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-04-21 10:57:36 -03:00
Ran Benita
3617ef1c79 Merge pull request #12227 from bluetech/deprecate-legacy-path-impls
hookspec: deprecate hookimpls requesting py.path parameters
2024-04-21 11:52:16 +03:00
Ran Benita
58136c5376 hookspec: deprecate hookimpls requesting py.path parameters 2024-04-21 11:37:56 +03:00
Bruno Oliveira
042625957a Fully type annotate pathlib.py (#12229)
Add full type annotations to `pathlib.py` and remove the `allow-untyped-defs` directive.
2024-04-20 16:32:36 -03:00
Bruno Oliveira
6fb474a3eb Refactor insert_missing_modules function (#12210)
Makes the logic more straightforward IMO.
2024-04-20 11:58:14 +00:00
Bruno Oliveira
ff806b239e importlib: set children as attribute of parent modules (#12208)
Now `importlib` mode will correctly set the imported modules as an attribute of their parent modules.

As helpfully posted on #12194, that's how the Python import module works so we should follow suit.

In addition, we also try to import the parent modules as part of the process of importing a child module, again mirroring how Python importing works.

Fix #12194
2024-04-20 11:31:33 +00:00
dj
ad95d59d61 Use monkeypatch in test_pytest_version_env_var
Follow up to #12190
2024-04-18 23:05:29 -03:00
dj
48b6d18834 Add PYTEST_VERSION environment variable (#12190)
Among other things, it can be used to check if a code is running from within a pytest session.

Fixes #9502
2024-04-18 07:45:47 -03:00
pre-commit-ci[bot]
58844247f7 [pre-commit.ci] pre-commit autoupdate (#12218)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.5 → v0.3.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.5...v0.3.7)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-04-15 23:04:19 +00:00
dependabot[bot]
b56b294f54 build(deps): Bump peter-evans/create-pull-request from 6.0.2 to 6.0.3 (#12215)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](70a41aba78...c55203cfde)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 13:08:38 -03:00
Ran Benita
6e248818b9 Merge pull request #12212 from pytest-dev/update-plugin-list/patch-089116bdf
[automated] Update plugin list
2024-04-15 17:59:30 +03:00
dependabot[bot]
0644e467fb build(deps): Bump hynek/build-and-inspect-python-package (#12214)
Bumps [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) from 2.2.1 to 2.4.0.
- [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases)
- [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v2.2.1...v2.4.0)

---
updated-dependencies:
- dependency-name: hynek/build-and-inspect-python-package
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 10:33:41 +02:00
pytest bot
5f6e825a26 [automated] Update plugin list 2024-04-14 00:21:52 +00:00
HolyMagician03-UMich
089116bdff short test summary: do not truncate text when -vv is given
Fix #11777

---------

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2024-04-10 08:07:18 -03:00
Ran Benita
1f001cd105 Merge pull request #12199 from tamird/mkdir-test-init
Add test for Cache.mkdir
2024-04-09 22:26:36 +03:00
Bruno Oliveira
99890636bf Refine how we detect namespace packages (#12169)
Previously we used a hand crafted approach to detect namespace packages, however we should rely on ``importlib`` to detect them for us.

Fix #12112

---------

Co-authored-by: Ran Benita <ran@unusedvar.com>
2024-04-09 13:21:51 -03:00
dependabot[bot]
17fc20af78 build(deps): Bump hynek/build-and-inspect-python-package (#12195)
Bumps [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) from 2.0.2 to 2.2.1.
- [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases)
- [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v2.0.2...v2.2.1)

---
updated-dependencies:
- dependency-name: hynek/build-and-inspect-python-package
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
2024-04-09 10:04:42 -03:00
pre-commit-ci[bot]
1ca59dfd6b [pre-commit.ci] pre-commit autoupdate (#12200)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-04-09 09:55:05 -03:00
Tamir Duberstein
e06c337bd8 Add test for Cache.mkdir 2024-04-08 15:08:18 +01:00
Tamir Duberstein
a02cc0ad1b Add types 2024-04-08 15:08:17 +01:00
dependabot[bot]
74f05648d5 build(deps): Bump django in /testing/plugins_integration (#12196)
Bumps [django](https://github.com/django/django) from 5.0.3 to 5.0.4.
- [Commits](https://github.com/django/django/compare/5.0.3...5.0.4)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 12:15:01 +02:00
github-actions[bot]
f75dd87eb7 [automated] Update plugin list (#12193)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-04-07 08:57:04 -03:00
Ran Benita
5acc3f86ac Merge pull request #12168 from tamird/fix-gitignore-missing
Initialize cache directory in isolation
2024-04-06 23:18:19 +03:00
Florian Bruhin
4e3dd21506 Improve stale bot messages (#12185)
To avoid confusion, see e.g. https://github.com/pytest-dev/pytest/issues/12123#issuecomment-2035283472

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2024-04-04 00:24:34 +02:00
Tamir Duberstein
2e65f4e3ac Initialize cache directory in isolation
Creating and initializing the cache directory is interruptible; this
avoids a pathological case where interrupting a cache write can cause
the cache directory to never be properly initialized with its supporting
files.

Unify `Cache.mkdir` with `Cache.set` while I'm here so the former also
properly initializes the cache directory.

Closes #12167.
2024-04-03 16:26:43 +01:00
Manuel López-Ibáñez
cc588d1a1a Doc: import pytest in conftest.py example in doctest.rst (#12181) 2024-04-03 09:02:09 -03:00
Ran Benita
b63bea9523 Merge pull request #11910 from bluetech/move-show-fixtures
Move show-fixtures code from python.py to fixtures.py
2024-04-02 23:28:32 +03:00
Ran Benita
a10ddad774 Merge pull request #12171 from pytest-dev/update-plugin-list/patch-12e061e2e
[automated] Update plugin list
2024-04-02 23:15:16 +03:00
Ran Benita
1188ea2608 Move show-fixtures code from python.py to fixtures.py
It makes more sense, also, we have a long term idea of generalizing
fixture support to items defined by other plugins, not just python, in
which case `--fixtures` would definitely not be python-plugin
specific.
2024-04-02 23:02:10 +03:00
Ran Benita
aa5324560b Merge pull request #12159 from pytest-dev/dependabot/pip/testing/plugins_integration/pytest-cov-5.0.0
build(deps): Bump pytest-cov from 4.1.0 to 5.0.0 in /testing/plugins_integration
2024-04-02 22:59:20 +03:00
Ronny Pfannschmidt
381593ccf0 Merge pull request #12176 from pytest-dev/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-04-02 08:41:02 +02:00
pre-commit-ci[bot]
9d6b5f8772 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.4 → v0.3.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.4...v0.3.5)
2024-04-01 22:13:25 +00:00
Pierre Sassoulas
44895289c7 Merge pull request #12170 from Pierre-Sassoulas/small-performance-improvments
Small performance/readability improvments when iterating dictionnary with ``keys()``
2024-03-31 15:15:03 +02:00
Pierre Sassoulas
1125296b53 Small performance/readability improvments when iterating dictionnary with `keys()`
Based on pylint's message ``consider-iterating-dictionary`` suggestion.
Surprisingly using a dict or set comprehension instead of a new temp var is
actually consistently slower here, which was not intuitive for me.

```python
from timeit import timeit

families = {1: {"testcase": [1, 2, 3, 5, 8]}}
attrs = {1: "a", 2: "b", 3: "c", 4: "d", 5: "e", 6: "f", 7: "g", 8: "h"}

class Old:
    def old(self):
        self.attrs = attrs
        temp_attrs = {}
        for key in self.attrs.keys():
            if key in families[1]["testcase"]:
                temp_attrs[key] = self.attrs[key]
        self.attrs = temp_attrs

class OldBis:
    def old(self):
        self.attrs = attrs
        temp_attrs = {}
        for key in self.attrs:
            if key in families[1]["testcase"]:
                temp_attrs[key] = self.attrs[key]
        self.attrs = temp_attrs

class New:
    def new(self):
        self.attrs = attrs
        self.attrs = { # Even worse with k: v for k in self.attrs.items()
            k: self.attrs[k] for k in self.attrs if k in families[1]["testcase"]
        }

if __name__ == "__main__":
    n = 1000000
    print(f"Old: {timeit(Old().old, number=n)}")
    print(f"Just removing the keys(): {timeit(OldBis().old, number=n)}")
    print(f"List comp, no temp var: {timeit(New().new, number=n)}")
```

Result:
Old: 0.9493889989680611
Just removing the keys(): 0.9042672360083088
List comp, no temp var: 0.9916125109884888

It's also true for the other example with similar benchmark, but the exact
code probably does not need to be in the commit message.
2024-03-31 14:43:07 +02:00
Pierre Sassoulas
bd9b62161a [tooling] Add a manual step to run pylint in pre-commit 2024-03-31 14:43:07 +02:00
John Litborn
e64efd8653 Don't reregister subfixture finalizer in requested fixture if value is cached (#12136) 2024-03-31 15:02:09 +03:00
pytest bot
2dd58e827e [automated] Update plugin list 2024-03-31 00:20:45 +00:00
pre-commit-ci[bot]
12e061e2e8 [pre-commit.ci] pre-commit autoupdate (#12162)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.3 → v0.3.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.3...v0.3.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-03-25 23:37:36 +01:00
dependabot[bot]
5d345f6d7f build(deps): Bump pytest-cov in /testing/plugins_integration
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 4.1.0 to 5.0.0.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v4.1.0...v5.0.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-25 06:32:55 +00:00
dependabot[bot]
2cba2237cd build(deps): Bump pytest-twisted in /testing/plugins_integration (#12158)
Bumps [pytest-twisted](https://github.com/pytest-dev/pytest-twisted) from 1.14.0 to 1.14.1.
- [Release notes](https://github.com/pytest-dev/pytest-twisted/releases)
- [Commits](https://github.com/pytest-dev/pytest-twisted/compare/v1.14.0...v1.14.1)

---
updated-dependencies:
- dependency-name: pytest-twisted
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 07:32:29 +01:00
dependabot[bot]
e7b048e92d build(deps): Bump pytest-mock in /testing/plugins_integration (#12160)
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.12.0 to 3.14.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.12.0...v3.14.0)

---
updated-dependencies:
- dependency-name: pytest-mock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 07:30:45 +01:00
dependabot[bot]
4a8cefbf64 build(deps): Bump pytest-asyncio in /testing/plugins_integration (#12161)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.23.5 to 0.23.6.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.23.5...v0.23.6)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 07:30:08 +01:00
tserg
909759de2d Improve sentence in marks documentation (#12157) 2024-03-24 15:59:07 +01:00
Ran Benita
85ff5d1b54 Merge pull request #12156 from pytest-dev/update-plugin-list/patch-c650e3a94
[automated] Update plugin list
2024-03-24 16:15:46 +02:00
Ran Benita
cfc4cf074e Merge pull request #12154 from bluetech/fixtures-cache-key-idx
fixtures: stop using `request.param_index` in fixture cache key
2024-03-24 15:40:52 +02:00
pytest bot
aeae91e27d [automated] Update plugin list 2024-03-24 00:20:37 +00:00
Ran Benita
3eb16b34be fixtures: stop using request.param_index in fixture cache key
When `param` is not defined, `param_index` is always 0 (see
`_compute_fixture_value`), so no point in using it besides adding some
confusion.
2024-03-23 12:07:24 +02:00
Linghao Zhang
c650e3a94f Add research item in doc (#12147) 2024-03-21 11:21:43 -03:00
Ran Benita
470edc5884 Merge pull request #12133 from pytest-dev/dependabot/github_actions/hynek/build-and-inspect-python-package-2.0.2
build(deps): Bump hynek/build-and-inspect-python-package from 2.0.1 to 2.0.2
2024-03-20 11:21:40 +02:00
Ran Benita
07a08028de Merge pull request #12132 from pytest-dev/dependabot/github_actions/peter-evans/create-pull-request-6.0.2
build(deps): Bump peter-evans/create-pull-request from 6.0.0 to 6.0.2
2024-03-20 11:20:50 +02:00
Ran Benita
42d3960fea Merge pull request #12131 from pytest-dev/dependabot/pip/testing/plugins_integration/pytest-rerunfailures-14.0
build(deps): Bump pytest-rerunfailures from 13.0 to 14.0 in /testing/plugins_integration
2024-03-20 11:20:09 +02:00
Sebastian Meyer
e7bf216516 doc: add versionadded to ExceptionInfo.group_contains (#12141) 2024-03-19 19:54:26 -03:00
pre-commit-ci[bot]
532782a228 [pre-commit.ci] pre-commit autoupdate (#12137)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.2 → v0.3.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.2...v0.3.3)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-03-18 22:51:23 +00:00
dependabot[bot]
bf8b088bbe build(deps): Bump hynek/build-and-inspect-python-package
Bumps [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases)
- [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: hynek/build-and-inspect-python-package
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 03:12:49 +00:00
dependabot[bot]
027464975f build(deps): Bump peter-evans/create-pull-request from 6.0.0 to 6.0.2
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.0 to 6.0.2.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](b1ddad2c99...70a41aba78)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 03:12:45 +00:00
dependabot[bot]
6be5c9d88c build(deps): Bump pytest-rerunfailures in /testing/plugins_integration
Bumps [pytest-rerunfailures](https://github.com/pytest-dev/pytest-rerunfailures) from 13.0 to 14.0.
- [Changelog](https://github.com/pytest-dev/pytest-rerunfailures/blob/master/CHANGES.rst)
- [Commits](https://github.com/pytest-dev/pytest-rerunfailures/compare/13.0...14.0)

---
updated-dependencies:
- dependency-name: pytest-rerunfailures
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 03:02:28 +00:00
Ran Benita
2607fe8b47 Merge pull request #12126 from pytest-dev/update-plugin-list/patch-70c11582a
[automated] Update plugin list
2024-03-17 21:22:45 +02:00
pytest bot
2e69f31444 [automated] Update plugin list 2024-03-17 00:20:04 +00:00
John Litborn
70c11582aa Don't add fixture finalizer if the value is cached (#11833)
Fixes #1489
2024-03-16 23:45:56 +02:00
Ran Benita
c203f1615c Merge pull request #12121 from jakkdl/test_scope_fixture_caching
Add tests to ensure setup&finalization for scoped fixtures only run once.
2024-03-16 12:21:53 +02:00
jakkdl
bec0e9caf8 Add tests to ensure setup&finalization for scoped fixtures only run once. 2024-03-15 12:26:28 +01:00
Tobias Stoeckmann
2e5da5d2fb doc: fix typos (#12118)
* doc: add missing word

* doc: fix typos

Typos found with codespell
2024-03-14 16:36:11 +00:00
pre-commit-ci[bot]
c0532dda18 [pre-commit.ci] pre-commit autoupdate (#12115)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Co-authored-by: Ran Benita <ran@unusedvar.com>
2024-03-13 15:30:18 +02:00
Ran Benita
14437788f0 Merge pull request #12108 from pytest-dev/bluetech-patch-1
doc: add versionadded to `Stash` and `StashKey`
2024-03-11 18:36:16 +02:00
Ran Benita
7eaaf370bb doc: add versionadded to Stash and StashKey
Fixes #12107
2024-03-11 18:22:16 +02:00
dependabot[bot]
6c9e107681 build(deps): Bump softprops/action-gh-release from 1 to 2 (#12106)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 11:48:06 -03:00
dependabot[bot]
122b43439c build(deps): Bump django in /testing/plugins_integration (#12103)
Bumps [django](https://github.com/django/django) from 5.0.2 to 5.0.3.
- [Commits](https://github.com/django/django/compare/5.0.2...5.0.3)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 07:05:41 +01:00
dependabot[bot]
a29ea1bc32 build(deps): Bump pypa/gh-action-pypi-publish from 1.8.12 to 1.8.14 (#12105)
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.12 to 1.8.14.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.12...v1.8.14)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 07:04:19 +01:00
Ran Benita
0a442a9599 doc/flaky: remove box/flaky plugin suggestion (#12100)
The plugin is abandoned and no longer working with new pytest versions.

I also reordered a bit to put pytest-rerunfailures first since it seems most maintained and is under pytest-dev.
2024-03-10 11:51:04 -03:00
Ran Benita
520ff29c07 Merge pull request #12096 from bluetech/staticmethod-instance
python: fix instance handling in static and class method tests
2024-03-10 16:29:06 +02:00
github-actions[bot]
b777b05c0e [automated] Update plugin list (#12098)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-03-10 09:57:13 -03:00
Ran Benita
b90da34a86 Merge pull request #12095 from nicoddemus/cherry-pick-release
Cherry pick release 8.1.1
2024-03-09 19:39:15 +02:00
Ran Benita
0dc0360351 python: fix instance handling in static and class method tests
and also fixes a regression in pytest 8.0.0 where `setup_method` crashes
if the class has static or class method tests.

It is allowed to have a test class with static/class methods which
request non-static/class method fixtures (including `setup_method`
xunit-fixture). I take it as a given that we need to support this
somewhat odd scenario (stdlib unittest also supports it).

This raises a question -- when a staticmethod test requests a bound
fixture, what is that fixture's `self`?

stdlib unittest says - a fresh instance for the test.

Previously, pytest said - some instance that is shared by all
static/class methods. This is definitely broken since it breaks test
isolation.

Change pytest to behave like stdlib unittest here.

In practice, this means stopping to rely on `self.obj.__self__` to get
to the instance from the test function's binding. This doesn't work
because staticmethods are not bound to anything.

Instead, keep the instance explicitly and use that.

BTW, I think this will allow us to change `Class`'s fixture collection
(`parsefactories`) to happen on the class itself instead of a class
instance, allowing us to avoid one class instantiation. But needs more
work.

Fixes #12065.
2024-03-09 19:35:54 +02:00
Bruno Oliveira
140c777590 Merge pull request #12094 from pytest-dev/release-8.1.1
Prepare release 8.1.1

(cherry picked from commit abb0cf4922)
2024-03-09 08:52:31 -03:00
Ran Benita
774f0c44e6 fixtures: only call instance property once in function
No need to compute the property multiple times.
2024-03-09 10:16:41 +02:00
Ran Benita
006058f1f9 fixtures: update outdated comment
No longer does unittest stuff. Also the rest of the sentence is not
really necessary for a docstring.
2024-03-09 10:16:41 +02:00
Ran Benita
437eb86edd Merge pull request #12092 from bluetech/fixture-cleanup
fixtures: a few more cleanups
2024-03-09 08:55:37 +02:00
Levon Saldamli
9033d4d3ff Parse args from file (#12085)
Co-authored-by: Ran Benita <ran@unusedvar.com>
Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2024-03-09 08:51:52 +02:00
Bruno Oliveira
2ccc73be9a Merge pull request #12087 from nicoddemus/revert-path-deprecations
Revert legacy path removals
2024-03-08 20:06:47 -03:00
Ran Benita
ff551b7685 fixtures: simplify a bit of code 2024-03-09 00:02:06 +02:00
Ran Benita
f5de111357 fixtures: check scope mismatch in getfixturevalue already-cached case
This makes sure the scope is always compatible, and also allows using
`getfixturevalue` in `pytest_fixture_setup` so less internal magic.
2024-03-09 00:02:06 +02:00
Ran Benita
71671f60b5 fixtures: improve fixture scope mismatch message
- Separate the requesting from the requested.

- Avoid the term "factory", I think most people don't distinguish
  between "fixture" and "fixture function" (i.e. "factory") and would
  find the term "factory" unfamiliar.
2024-03-09 00:02:06 +02:00
Ran Benita
a9d1f55a0f fixtures: simplify scope checking
There are two non-optimal things in the current way scope checking is
done:

- It runs on `SubRequest`, but doesn't use the `SubRequest's scope,
  which is confusing. Instead it takes `invoking_scope` and
  `requested_scope`.

- Because `_check_scope` is only defined on `SubRequest` and not
  `TopRequest`, `_compute_fixture_value` first creates the `SubRequest`
  only then checks the scope (hence the need for the previous point).

Instead, also define `_check_scope` on `TopRequest` (always valid), and
remove `invoking_scope`, using `self._scope` instead.
2024-03-09 00:02:06 +02:00
Ran Benita
83887c066b Merge pull request #12089 from bluetech/unittest-obj
unittest: make `obj` work more like `Function`/`Class`
2024-03-08 20:50:27 +02:00
Ran Benita
4a8bd5f2e2 Merge pull request #12057 from pytest-dev/dependabot/github_actions/pypa/gh-action-pypi-publish-1.8.12
build(deps): Bump pypa/gh-action-pypi-publish from 1.8.11 to 1.8.12
2024-03-08 14:07:30 +02:00
Ran Benita
51595d9000 Merge pull request #12056 from pytest-dev/dependabot/pip/testing/plugins_integration/twisted-24.3.0
build(deps): Bump twisted from 23.10.0 to 24.3.0 in /testing/plugins_integration
2024-03-08 14:07:02 +02:00
Ran Benita
1a5e0eb71d unittest: make obj work more like Function/Class
Previously, the `obj` of a `TestCaseFunction` (the unittest plugin item
type) was the unbound method. This is unlike regular `Class` where the
`obj` is a bound method to a fresh instance.

This difference necessitated several special cases in in places outside
of the unittest plugin, such as `FixtureDef` and `FixtureRequest`, and
made things a bit harder to understand.

Instead, match how the python plugin does it, including collecting
fixtures from a fresh instance.

The downside is that now this instance for fixture-collection is kept
around in memory, but it's the same as `Class` so nothing new. Users
should only initialize stuff in `setUp`/`setUpClass` and similar
methods, and not in `__init__` which is generally off-limits in
`TestCase` subclasses.

I am not sure why there was a difference in the first place, though I
will say the previous unittest approach is probably the preferable one,
but first let's get consistency.
2024-03-08 14:03:26 +02:00
Bruno Oliveira
221097517b Add changelog entry for #12069 2024-03-07 19:50:33 -03:00
Bruno Oliveira
dacee1f11d Revert "Remove deprecated py.path hook arguments"
This reverts commit a98f02d423.
2024-03-07 19:50:33 -03:00
Bruno Oliveira
303cd0d48a Revert "Remove deprecated py.path (fspath) node constructor arguments"
This reverts commit 6c89f9261c.
2024-03-07 19:50:33 -03:00
Bruno Oliveira
86945f9a1f Rename 'testing' extra to 'dev' (#12052)
Minor, but seems `dev` is more standard for the development extras than `testing`, being the default for tools like `poetry`.
2024-03-07 19:12:19 -03:00
Bruno Oliveira
03e54712dd Do not import duplicated modules with --importmode=importlib (#12074)
Regression brought up by #11475.
2024-03-04 12:44:56 -03:00
Bruno Oliveira
18c0e5075f Merge pull request #12075 from nicoddemus/yank-8.1.0
Yank version 8.1.0
2024-03-04 12:21:12 -03:00
Bruno Oliveira
6ee02a3e6c Yank version 8.1.0
Related to #12069
2024-03-04 12:18:14 -03:00
Bruno Oliveira
0951cbc6e4 Merge pull request #12070 from RonnyPfannschmidt/lift
add myself as tidelifter
2024-03-04 10:01:53 -03:00
Ronny Pfannschmidt
37b3401091 add myself to tidelift 2024-03-04 12:59:54 +01:00
dependabot[bot]
13558b9f53 build(deps): Bump pypa/gh-action-pypi-publish from 1.8.11 to 1.8.12
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.11 to 1.8.12.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.11...v1.8.12)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 03:47:21 +00:00
dependabot[bot]
23bdc643c9 build(deps): Bump twisted in /testing/plugins_integration
Bumps [twisted](https://github.com/twisted/twisted) from 23.10.0 to 24.3.0.
- [Release notes](https://github.com/twisted/twisted/releases)
- [Changelog](https://github.com/twisted/twisted/blob/trunk/NEWS.rst)
- [Commits](https://github.com/twisted/twisted/compare/twisted-23.10.0...twisted-24.3.0)

---
updated-dependencies:
- dependency-name: twisted
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 03:25:34 +00:00
Ran Benita
71849cc05c Merge pull request #12055 from bluetech/cherry-pick-release
Cherry-pick 8.1.0 release notes
2024-03-03 23:29:47 +02:00
Ran Benita
e410705561 Cherry-pick 8.1.0 release notes
(cherry picked from commit 0a536810dc)
2024-03-03 23:27:02 +02:00
Ran Benita
00043f7f10 Merge pull request #12038 from bluetech/fixtures-rm-arg2index
fixtures: avoid mutable arg2index state in favor of looking up the request chain
2024-03-03 15:45:34 +02:00
Ran Benita
f4e10251a4 Merge pull request #12048 from bluetech/fixture-teardown-excgroup
fixtures: use exception group when multiple finalizers raise in fixture teardown
2024-03-03 15:09:36 +02:00
Ran Benita
43492f5707 Merge pull request #12051 from jakkdl/test_debugging_pythonbreakpoint
[minor/QoL] monkeypatch.delenv PYTHONBREAKPOINT in two tests that previously failed/skipped
2024-03-03 15:07:19 +02:00
github-actions[bot]
82fe28dae4 [automated] Update plugin list (#12049)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-03-03 12:50:42 +00:00
jakkdl
5e2ee7175c monkeypatch.delenv PYTHONBREAKPOINT in two tests that previously failed/skipped 2024-03-03 13:48:29 +01:00
Bruno Oliveira
89ee4493cc Merge pull request #11997 from nicoddemus/11475-importlib
Change importlib to first try to import modules using the standard mechanism
2024-03-03 09:43:14 -03:00
mrbean-bremen
8248946a55 Do not collect symlinked tests under Windows (#12050)
The check for short paths under Windows via os.path.samefile, introduced in #11936, also found similar tests in symlinked tests in the GH Actions CI.

Fixes #12039.

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2024-03-03 09:41:31 -03:00
Ran Benita
434282e17f fixtures: use exception group when multiple finalizers raise in fixture teardown
Previously, if more than one fixture finalizer raised, only the first
was reported, and the other errors were lost.

Use an exception group to report them all. This is similar to the change
we made in node teardowns (in `SetupState`).
2024-03-02 23:39:11 +02:00
Bruno Oliveira
d6134bc21e doc: document consider_namespace_packages option 2024-03-02 16:13:48 -03:00
Bruno Oliveira
aac720abc9 testing/test_pathlib: parametrize namespace package option
Test with namespace packages support even when it will not find namespace packages to ensure it will at least not give weird results or crashes.
2024-03-02 16:13:48 -03:00
Bruno Oliveira
111c0d910e Add consider_namespace_packages ini option
Fix #11475
2024-03-02 16:13:48 -03:00
Bruno Oliveira
199d4e2b73 pathlib: import signature and docs for import_path 2024-03-02 16:13:48 -03:00
Bruno Oliveira
5746b8e696 doc: update and improve import mode docs 2024-03-02 16:13:48 -03:00
Bruno Oliveira
c85fce39b6 Change importlib to first try to import modules using the standard mechanism
As detailed in
https://github.com/pytest-dev/pytest/issues/11475#issuecomment-1937043670,
currently with `--import-mode=importlib` pytest will try to import every
file by using a unique module name, regardless if that module could be
imported using the normal import mechanism without touching `sys.path`.

This has the consequence that non-test modules available in `sys.path`
(via other mechanism, such as being installed into a virtualenv,
PYTHONPATH, etc) would end up being imported as standalone modules,
instead of imported with their expected module names.

To illustrate:

```
.env/
  lib/
    site-packages/
      anndata/
        core.py
```

Given `anndata` is installed into the virtual environment, `python -c
"import anndata.core"` works, but pytest with `importlib` mode would
import that module as a standalone module named
`".env.lib.site-packages.anndata.core"`, because importlib module was
designed to import test files which are not reachable from `sys.path`,
but now it is clear that normal modules should be imported using the
standard mechanisms if possible.

Now `imporlib` mode will first try to import the module normally,
without changing `sys.path`, and if that fails it falls back to
importing the module as a standalone module.

This also makes `importlib` respect namespace packages.

This supersedes #11931.

Fix #11475
Close #11931
2024-03-02 16:13:48 -03:00
Bruno Oliveira
067daf9f7d pathlib: consider namespace packages in resolve_pkg_root_and_module_name
This applies to `append` and `prepend` import modes; support for
`importlib` mode will be added in a separate change.
2024-03-02 16:13:48 -03:00
Bruno Oliveira
5867426455 pathlib: handle filenames starting with . in module_name_from_path 2024-03-02 16:13:48 -03:00
Bruno Oliveira
4dea18308b pathlib: extract a function _import_module_using_spec
Will be reused.
2024-03-02 16:13:48 -03:00
Bruno Oliveira
7524e60d8f pathlib: extract a function resolve_pkg_root_and_module_name
Will be reused.
2024-03-02 16:13:48 -03:00
Bruno Oliveira
dcf01fd39a testing/test_pathlib: add an importlib test
Ensure the implementation isn't changed to trigger such a bug.
2024-03-02 16:13:48 -03:00
Bruno Oliveira
300ceb435e testing/test_doctest: make test_importmode more realistic 2024-03-02 16:13:48 -03:00
Bruno Oliveira
887e251abb testing/test_pathlib: remove test_issue131_on__init__
The test seems wrong, and we haven't been able to figure out what it's
trying to test (the original issue is lost in time).
2024-03-02 16:13:48 -03:00
Ran Benita
6ed005161d Merge pull request #12043 from bluetech/pyargs-root
Fix collection failures due to permission errors when using `--pyargs`
2024-03-02 21:09:20 +02:00
Ran Benita
31026a2df2 main: only include package parents in collection tree for --pyargs collection arguments
(diff better viewed ignoring whitespace)

In pytest<8, the collection tree for `pyargs` arguments in an invocation
like this:

    pytest --collect-only --pyargs pyflakes.test.test_undefined_names

looked like this:

```
<Package test>
  <Module test_undefined_names.py>
    <UnitTestCase Test>
      <TestCaseFunction test_annotationUndefined>
      ... snipped ...
```

The pytest 8 collection improvements changed it to this:

```
<Dir pytest>
  <Dir .tox>
    <Dir venv>
      <Dir lib>
        <Dir python3.11>
          <Dir site-packages>
            <Package pyflakes>
              <Package test>
                <Module test_undefined_names.py>
                  <UnitTestCase Test>
                    <TestCaseFunction test_annotationUndefined>
                    ... snipped ...
```

Besides being egregious (and potentially even worse than the above,
going all the way to the root, for system-installed packages, as is
apparently common in CI), this also caused permission errors when trying
to probe some of those intermediate directories.

This change makes `--pyargs` arguments no longer try to add parent
directories to the collection tree according to the `--confcutdir` like
they're regular arguments. Instead, only add the parents that are in the
import path. This now looks like this:

```
<Package .tox/venv/lib/python3.11/site-packages/pyflakes>
  <Package test>
    <Module test_undefined_names.py>
      <UnitTestCase Test>
        <TestCaseFunction test_annotationUndefined>
        ... snipped ...
```

Fix #11904.
2024-03-02 20:26:02 +02:00
Ran Benita
f20e32c982 main: slight refactor to collection argument parents logic
No logical change, preparation for the next commit.
2024-03-02 20:26:02 +02:00
Ran Benita
1612d4e393 main: add module_name to CollectionArgument
This is available when the argument is a `--pyargs` argument (resolved
from a python module path). Will be used in an upcoming commit.
2024-03-02 20:26:02 +02:00
Ran Benita
5e0d11746c main: model the result of resolve_collection_arguments as a dataclass
In preparation of adding more info to it.
2024-03-02 20:25:57 +02:00
Ran Benita
b6bf58abe8 Merge pull request #12042 from donhui/docs-0301
docs: update plugins number
2024-03-01 15:20:33 +02:00
Ran Benita
ff4c3b2873 main: add missing import importlib.util
Used in `resolve_collection_argument`. It's implicitly imported by some
other import, but some type checkers don't recognize this.
2024-03-01 13:28:27 +02:00
donghui
4db5e53709 docs: update plugins number 2024-03-01 05:43:57 +08:00
Ran Benita
c967d508d6 Merge pull request #12037 from bluetech/fixtures-getnextfixturedef-parent
fixtures: remove unneeded optimization from `_getnextfixturedef`
2024-02-28 09:28:15 +02:00
Ran Benita
bd45ccd2ca fixtures: avoid mutable arg2index state in favor of looking up the request chain
pytest allows a fixture to request its own name (directly or
indirectly), in which case the fixture with the same name but one level
up is used.

To know which fixture should be used next, pytest keeps a mutable
item-global dict `_arg2index` which maintains this state. This is not
great:

- Mutable state like this is hard to understand and reason about.

- It is conceptually buggy; the indexing is global (e.g. if requesting
  `fix1` and `fix2`, the indexing is shared between them), but actually
  different branches of the subrequest tree should not affect each
  other.

  This is not an issue in practice because pytest keeps a cache of the
  fixturedefs it resolved anyway (`_fixture_defs`), but if the cache is
  removed it becomes evident.

Instead of the `_arg2index` state, count how many `argname`s deep we are
in the subrequest tree ("the fixture stack") and use that for the index.

This way, no global mutable state and the logic is very localized and
easier to understand.

This is slower, however fixture stacks should not be so deep that this
matters much, I hope.
2024-02-27 22:24:26 +02:00
Ran Benita
c83c1c4bda fixtures: add _iter_chain helper method
Will be reused in the next commit.
2024-02-27 22:24:26 +02:00
Ran Benita
686f9e0720 fixtures: remove unneeded optimization from _getnextfixturedef
According to my understanding, this code, which handles obtaining the
relevant fixturedefs when a dynamic `getfixturevalue` is used, has an
optimization where it only grabs fixturedefs that are visible to the
*parent* of the item, instead of the item itself, under the assumption
that a fixturedef can't be visible to a single item, only to a
collector.

Remove this optimization for the following reasons:
- It doesn't save much (one loop iteration in `matchfactories`)
- It slightly complicates the complex fixtures code
- If some plugin wants to make a fixture visible only to a single item,
  why not let it?
- In the static case (`getfixtureclosure`), this optimization is not
  done (despite the confusing name `parentnode`, it is *not* the parent
  node). This is inconsistent.
2024-02-27 22:22:07 +02:00
dependabot[bot]
98b008ff6c build(deps): Bump anyio[curio,trio] in /testing/plugins_integration (#12033)
Bumps [anyio[curio,trio]](https://github.com/agronholm/anyio) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/agronholm/anyio/releases)
- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/anyio/compare/4.2.0...4.3.0)

---
updated-dependencies:
- dependency-name: anyio[curio,trio]
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 10:51:07 -03:00
Bruno Oliveira
73edefdd64 Merge pull request #12031 from pytest-dev/update-plugin-list/patch-affc652f1
[automated] Update plugin list
2024-02-24 21:50:44 -03:00
Bruno Oliveira
ffd727e9d6 Fix mention of the prefix for pytest plugins in plugin_list 2024-02-24 21:35:51 -03:00
pytest bot
b6eb985d55 [automated] Update plugin list 2024-02-25 00:19:33 +00:00
Ran Benita
affc652f1c Merge pull request #12030 from bluetech/cherry-pick-release
Cherry pick 8.0.2 release notes
2024-02-25 00:31:52 +02:00
Ran Benita
7460b1aa31 Cherry pick 8.0.2 release notes
(cherry picked from commit e53f798932)
2024-02-25 00:25:49 +02:00
Patrick Lannigan
84bd31de64 New verbosity_test_case ini option (#11653)
Allow for the output of test case execution to be controlled independently from the application verbosity level. 

`verbosity_test_case` is the new ini setting to adjust this functionality.

Fix #11639
2024-02-24 16:27:54 -03:00
Ran Benita
a2a9aa6cde Merge pull request #12027 from bluetech/sys-last-exc
runner: add support for `sys.last_exc` for post-mortem debugging on Python>=3.12
2024-02-23 22:41:14 +02:00
robotherapist
c09f74619b runner: add support for sys.last_exc for post-mortem debugging on Python>=3.12
Fix #11850
2024-02-23 15:59:32 +02:00
Ran Benita
b510adf9ef Merge pull request #12023 from bluetech/fixtures-cleanups-2
fixtures: remove an unneeded suppress
2024-02-23 15:35:17 +02:00
Ran Benita
93cd7ba857 Merge pull request #12022 from bluetech/revert-11721
Revert "Fix teardown error reporting when `--maxfail=1` (#11721)"
2024-02-23 15:34:32 +02:00
Bruno Oliveira
8d9b95dcdb Fix collection of short paths on Windows (#11936)
Passing a short path in the command line was causing the matchparts check to fail, because ``Path(short_path) != Path(long_path)``.

Using ``os.path.samefile`` as fallback ensures the comparsion works on Windows when comparing short/long paths.

Fix #11895
2024-02-23 07:51:15 -03:00
Ran Benita
ad651ddfce fixtures: remove an unneeded suppress
In `CallSpec2.setmulti` the `params` and `_arg2scope` dicts are always
set together.

Further, the `get_parametrized_fixture_keys` accesses `_arg2scope` for
all argnames without a check, which I think rules out that the code
protects against plugin shenanigans.

After removing the suppress, adjust the comment and code to make more
sense.
2024-02-23 11:51:49 +02:00
Ran Benita
00d9640abc Revert "Fix teardown error reporting when --maxfail=1 (#11721)"
Fix #12021.
Reopens #11706.

This reverts commit 12b9bd5801.

This change caused a bad regression in pytest-xdist:
https://github.com/pytest-dev/pytest-xdist/issues/1024

pytest-xdist necessarily has special handling of `--maxfail` and session
fixture teardown get executed multiple times with the change.

Since I'm not sure how to adapt pytest-xdist myself, revert for now.

I kept the sticky `shouldstop`/`shouldfail` changes as they are good
ideas regardless I think.
2024-02-23 11:45:26 +02:00
Ran Benita
010ce2ab0f Add typing to from_parent return values (#11916)
Up to now the return values of `from_parent` were untyped, this is an
attempt to make it work with `typing.Self`.
2024-02-22 23:35:57 -08:00
Eric Larson
1640f2e454 ENH: Improve warning stacklevel (#12014)
* ENH: Improve warning stacklevel

* TST: Add test

* TST: Ping

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* MAINT: Changelog

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-22 22:11:05 -08:00
Bruno Oliveira
59e9a58cc9 Remove Anthony from Tidelift participants (#12020)
As discussed in the core development channels, @asottile asked to no longer be a Tidelift participant, at least for the time being.
2024-02-22 21:04:11 -03:00
Ran Benita
691d8fcafb Merge pull request #12019 from bluetech/fixtures-simplify
fixtures: remove a no longer needed sort
2024-02-22 21:52:56 +02:00
Ben Leith
c5c729e27a Add --log-file-mode option to the logging plugin, enabling appending to log-files (#11979)
Previously, the mode was hard-coded to be "w" which truncates the file before logging.

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2024-02-21 12:02:19 +00:00
Ran Benita
9bea1be215 fixtures: remove a no longer needed sort
Dicts these days preserve order, so the sort is no longer needed to
achieve determinism.

As shown by the `test_dynamic_parametrized_ordering` test, this can
change the ordering of items, but only in equivalent ways (same number
of setups/teardowns per scope), it will just respect the user's given
ordering better (hence `vxlan` items now ordered before `vlan` items
compared to the previous ordering).
2024-02-21 10:17:25 +02:00
Ran Benita
2007cf6296 fixtures: remove a level of indentation
A bit easier to follow.
2024-02-21 10:17:24 +02:00
Ran Benita
79def57cc6 python: small code cleanup 2024-02-21 10:17:24 +02:00
Ran Benita
8a410d0ba6 Merge pull request #12013 from bluetech/doctest-test
testing: add a regression test for `setup_module` + `--doctest-modules`
2024-02-20 22:22:01 +02:00
Ran Benita
a37cff3ca8 testing: add a regression test for setup_module + --doctest-modules
Refs #12011 (only fails on 8.0.1, not main).
2024-02-20 09:36:00 +02:00
pre-commit-ci[bot]
95f21f96cc [pre-commit.ci] pre-commit autoupdate (#12012)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.1 → v0.2.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.1...v0.2.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-19 21:36:03 -03:00
Bruno Oliveira
998fee1679 Clarify PytestPluginManager._is_in_confcutdir (#12007)
Follow up to #12006, let's put some comments clarifying `is_in_confcutdir` semantics, as this is not the first time someone misunderstands it.

Also removed an obsolete comment in `_loadconftestmodules`: we already set the `confcutdir` based on `rootdir`/`initfile` if not explicitly given.

Co-authored-by: Ran Benita <ran@unusedvar.com>
2024-02-18 17:27:47 -03:00
Bruno Oliveira
40011b838b Allow Sphinx 7.x (#12002)
Thanks to https://github.com/pytest-dev/pytest/issues/11988#issuecomment-1950318888, the problem was our custom template.

The solution was to copy the template from Sphinx 7 and remove the header.
2024-02-18 07:21:05 -03:00
Bruno Oliveira
b37696703b Merge pull request #12003 from pytest-dev/update-plugin-list/patch-cefb3e227
[automated] Update plugin list
2024-02-17 22:35:26 -03:00
Bruno Oliveira
abf6a60567 Fix 'pytest_' mention: it was being considered a rst reference 2024-02-17 22:21:30 -03:00
pytest bot
52da8dd66c [automated] Update plugin list 2024-02-18 00:19:26 +00:00
Bruno Oliveira
cefb3e2277 Disallow Sphinx 6 and 7 (#12000)
Using Sphinx 6.x and 7.x the search bar disappears. Restrict to Sphinx 5.x for now until we find a solution.

Reverts #11568
Fixes #11988
2024-02-17 17:46:58 -03:00
Bruno Oliveira
5f241f388b Revert sys.platform verification to simple comparison (#11998)
As the comment above it states, we need to keep the comparison simple so mypy can understand it, otherwise it will fail to properly handle this on Windows and will flag ``os.getuid()`` missing.
2024-02-17 16:10:21 -03:00
Ran Benita
aebeb33137 Merge pull request #11996 from bluetech/getstatementrange-index-error
code: fix `IndexError` crash in `getstatementrange_ast`
2024-02-17 18:59:10 +02:00
Ran Benita
9f13d41d7b code: fix IndexError crash in getstatementrange_ast
Fix #11953.
2024-02-17 18:43:55 +02:00
Ran Benita
984478109f Merge pull request #11995 from bluetech/cherry-pick-release
Cherry pick 8.0.1 release notes
2024-02-17 00:27:55 +02:00
Ran Benita
22b541e4eb Merge pull request #11993 from pytest-dev/release-8.0.1
Prepare release 8.0.1

(cherry picked from commit 68524d4858)
2024-02-17 00:11:27 +02:00
Ran Benita
fbe18fc7a9 Merge pull request #11991 from bluetech/warns-fix
recwarn: fix pytest.warns handling of Warnings with multiple arguments
2024-02-16 14:29:19 +02:00
Reagan Lee
9b838f491f recwarn: fix pytest.warns handling of Warnings with multiple arguments
Fix #11906
2024-02-16 14:14:24 +02:00
Ran Benita
6ef0cf150a Merge pull request #11959 from eerovaher/warn-message-type
Allow using `warnings.warn()` with a `Warning`
2024-02-16 14:00:37 +02:00
Eero Vaher
0475b1c925 Allow using warnings.warn() with Warnings
Test:

`warnings.warn()` expects that its first argument is a `str` or a
`Warning`, but since 9454fc38d3
`pytest.warns()` no longer allows `Warning` instances unless the first
argument the `Warning` was initialized with is a `str`. Furthermore, if
the `Warning` was created without arguments then `pytest.warns()` raises
an unexpected `IndexError`. The new tests reveal the problem.

Fix:

`pytest.warns()` now allows using `warnings.warn()` with a `Warning`
instance, as is required by Python, with one exception. If the warning
used is a `UserWarning` that was created by passing it arguments and the
first argument was not a `str` then `pytest.raises()` still considers
that an error. This is because if an invalid type was used in
`warnings.warn()` then Python creates a `UserWarning` anyways and it
becomes impossible for `pytest` to figure out if that was done
automatically or not.

[ran: rebased on previous commit]
2024-02-16 13:41:59 +02:00
Ran Benita
dcf9da92be recwarn: minor style improvements
In preparation for next commit.
2024-02-16 13:41:27 +02:00
Ran Benita
8e56795b77 Merge pull request #11989 from bluetech/plugin-list-underscore
scripts/update-plugin-list: include packages starting with "pytest_" (underscore)
2024-02-16 13:01:25 +02:00
Ran Benita
718cd40015 Merge pull request #11920 from bluetech/warn-skip
recwarn: let base exceptions propagate through `pytest.warns` again
2024-02-16 12:22:52 +02:00
Ran Benita
288201b8f5 recwarn: let base exceptions propagate through pytest.warns again
Fix #11907.
2024-02-16 12:07:56 +02:00
Ran Benita
c6313a06fb scripts/update-plugin-list: include packages starting with "pytest_" (underscore)
Fix #11985.
2024-02-16 12:03:38 +02:00
dependabot[bot]
5d7a5a9343 build(deps): Bump codecov/codecov-action from 3 to 4 (#11921)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-14 16:11:30 -03:00
dependabot[bot]
cbb5c82c39 build(deps): Bump peter-evans/create-pull-request from 5.0.2 to 6.0.0 (#11922)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](153407881e...b1ddad2c99)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-14 16:11:20 -03:00
Bruno Oliveira
acafd003aa Consider pyproject.toml files for config if no other config files were found (#11962)
Today `pyproject.toml` is the standard for declaring a Python project root, so seems reasonable to consider it for the ini configuration (and specially `rootdir`) in case we do not find other suitable candidates.

Related to #11311
2024-02-14 16:08:45 -03:00
Bruno Oliveira
46e6fb12c7 Consider paths and pathlists relative to cwd in case of an absent ini-file (#11963)
Previously this would trigger an `AssertionError`.

While it could be considered a bug-fix, but given it now can be relied upon, it is probably better to consider it an improvement.

Fix #11311
2024-02-14 15:53:28 -03:00
Dave Hall
fe7907d78c Add logot to plugin list (#11972) 2024-02-14 15:50:34 -03:00
Ran Benita
5bb1363435 Merge pull request #11957 from bluetech/fix-session-collect-order
main: fix reversed collection order in Session
2024-02-13 09:44:13 +02:00
pre-commit-ci[bot]
ca84327f15 [pre-commit.ci] pre-commit autoupdate (#11967)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.0 → v0.2.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.0...v0.2.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-13 06:19:40 +01:00
dependabot[bot]
3b798e5422 build(deps): Bump pytest-asyncio in /testing/plugins_integration (#11965)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.23.3 to 0.23.5.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.23.3...v0.23.5)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-12 11:06:14 -03:00
Pierre Sassoulas
526b971221 Merge pull request #11961 Add some autofixable refactor rules from pylint 2024-02-11 19:52:29 +01:00
github-actions[bot]
23dfb52974 [automated] Update plugin list (#11964)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-02-10 21:50:24 -03:00
Pierre Sassoulas
7da04c963f [ruff] Add unwanted pylint message to the ignore list 2024-02-10 23:42:36 +01:00
Pierre Sassoulas
b922270ce7 [performance] Micro-optimization in '_traceback_filter'
Should be around 40% faster according to this simplified small benchmark:

python -m timeit "a=[0, 1, 2, 3, 4];b=list((e if i in {0, len(a) -1} else str(e)) for i, e in enumerate(a))"
200000 loops, best of 5: 1.12 usec per loop
python -m timeit "a=[0, 1, 2, 3, 4];b=list((a[0], *(str(e) for e in a[1:-1]), a[-1]))"
500000 loops, best of 5: 651 nsec per loop

python -m timeit "a=[0, 1, 2, 3, 4,5,6,7,8,9,10,11,12,13,14,15,16];b=list((e if i in {0, len(a) -1} else str(e)) for i, e in enumerate(a))"
100000 loops, best of 5: 3.31 usec per loop
python -m timeit "a=[0, 1, 2, 3, 4,5,6,7,8,9,10,11,12,13,14,15,16];b=list((a[0], *(str(e) for e in a[1:-1]), a[-1]))"
200000 loops, best of 5: 1.72 usec per loop
2024-02-10 20:23:48 +01:00
Pierre Sassoulas
1180348303 [ruff] Add 'consider-using-in' from pylint
See https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/consider-using-in.html
An automated fix from ruff is available (but it's unsafe for now).
2024-02-10 15:47:44 +01:00
Florian Bruhin
7690a0ddf1 Improve error message when using @pytest.fixture twice (#11670)
* Improve error message when using @pytest.fixture twice

While obvious in hindsight, this error message confused me. I thought my fixture
function was used in a test function twice, since the wording is ambiguous.

Also, the error does not tell me *which* function is the culprit.

Finally, this adds a test, which wasn't done in
cfd16d0dac where this was originally implemented.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-09 14:59:04 +01:00
Ran Benita
29a5f94428 Merge pull request #11956 from bluetech/ruff-warning
Fix ruff deprecation warning + enable few more rules
2024-02-09 15:32:11 +02:00
Ran Benita
ea57c40c43 main: fix reversed collection order in Session
Since we're working with a stack (last in first out), we need to append
to it in reverse to preserve the order when popped.

Fix #11937.
2024-02-09 15:24:44 +02:00
Ran Benita
a182e10b06 Enable lint PGH004 - Use specific rule codes when using noqa 2024-02-09 11:14:36 +02:00
Ran Benita
d1ee6d154f Enable flake8-pie 2024-02-09 11:08:33 +02:00
Ran Benita
d02618d173 Fix ruff deprecation warning
warning: The top-level linter settings are deprecated in favour of their counterparts in the `lint` section. Please update the following options in `pyproject.toml`:
  - 'ignore' -> 'lint.ignore'
  - 'select' -> 'lint.select'
2024-02-09 10:48:05 +02:00
whysage
9454fc38d3 closes: 10865 Fix muted exception (#11804)
* feat: 10865

* feat: 10865 refactor code and tests

* feat: 10865 add test skip for pypy

* feat: 10865 add test with valid warning

* feat: 10865 fix v2 for codecov

* feat: 10865 fix conflict
2024-02-07 16:47:56 -08:00
Ran Benita
101328aba5 Merge pull request #11947 from bluetech/hypothesis-revert
Revert "testing: temporarily disable test due to hypothesis issue (#1836)"
2024-02-07 22:44:58 +02:00
Ran Benita
42785cca44 Revert "testing: temporarily disable test due to hypothesis issue (#11836)"
This reverts commit 5cd0535395.
2024-02-07 22:13:23 +02:00
Ran Benita
6c0b6c2f92 Merge pull request #11941 from bluetech/doctest-parsefactories
doctest: fix autouse fixtures possibly not getting picked up
2024-02-07 22:09:17 +02:00
Ran Benita
9cd14b4ffb doctest: fix autouse fixtures possibly not getting picked up
Fix #11929.

Figured out what's going on. We have the following collection tree:

```
<Dir pyspacewar>
  <Dir src>
    <Package pyspacewar>
      <Package tests>
        <DoctestModule test_main.py>
          <DoctestItem pyspacewar.tests.test_main.doctest_main>
```

And the `test_main.py` contains an autouse fixture (`fake_game_ui`) that
`doctest_main` needs in order to run properly. The fixture doesn't run!
It doesn't run because nothing collects the fixtures from (calls
`parsefactories()` on) the `test_main.py` `DoctestModule`.

How come it only started happening with commit
ab63ebb3dc07b89670b96ae97044f48406c44fa0? Turns out it mostly only
worked accidentally. Each `DoctestModule` is also collected as a normal
`Module`, with the `Module` collected after the `DoctestModule`. For
example, if we add a non-doctest test to `test_main.py`, the collection
tree looks like this:

```
<Dir pyspacewar>
  <Dir src>
    <Package pyspacewar>
      <Package tests>
        <DoctestModule test_main.py>
          <DoctestItem pyspacewar.tests.test_main.doctest_main>
        <Module test_main.py>
          <Function test_it>
```

Now, `Module` *does* collect fixtures. When autouse fixtures are
collected, they are added to the `_nodeid_autousenames` dict.

Before ab63ebb3dc, `DoctestItem` consults
`_nodeid_autousenames` at *setup* time. At this point, the `Module` has
collected and so it ended up picking the autouse fixture (this relies on
another "accident", that the `DoctestModule` and `Module` have the same
node ID).

After ab63ebb3dc, `DoctestItem` consults
`_nodeid_autousenames` at *collection* time (= when it's created). At
this point, the `Module` hasn't collected yet, so the autouse fixture is
not picked out.

The fix is simple -- have `DoctestModule.collect()` call
`parsefactories`. From some testing I've done it shouldn't have negative
consequences (I hope).
2024-02-07 21:53:51 +02:00
dependabot[bot]
4c894f20a1 build(deps): Bump django in /testing/plugins_integration (#11946)
Bumps [django](https://github.com/django/django) from 5.0 to 5.0.2.
- [Commits](https://github.com/django/django/compare/5.0...5.0.2)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-07 15:37:56 -03:00
Ran Benita
6e5008f19f doctest: don't open code the module import
Currently, `DoctestModule` does `import_path` on its own. This changes
it to use `importtestmodule` as `Module` does. The behavioral changes
are:

- Much better error messages on import errors.

- Handles a few more error cases (see `importtestmodule`). This
  technically expands the cover of `--doctest-ignore-import-errors` but
  I think it makes sense.

- Considers `pytest_plugins` in the module.

- Populates `self.obj` as properly (without double-imports) as is
  expected from a `PyCollector`.

This is also needed for the next commit.
2024-02-06 23:46:23 +02:00
Pierre Sassoulas
b9d02c5b53 Merge pull request #11932 Add pre-commit hook and fix pyproject.toml
- [pyproject-fmt] Add pre-commit hook and autofix existing
- Proper setuptools version for pyproject.toml
2024-02-06 15:14:07 +01:00
Pierre Sassoulas
d1095426c1 Update setuptools version to the one that support pyproject.toml 2024-02-06 14:40:31 +01:00
Pierre Sassoulas
757778f5f6 [pyproject-fmt] Add pre-commit hook and autofix existing 2024-02-06 14:40:31 +01:00
Pierre Sassoulas
404d31a942 Merge pull request #11930 from Pierre-Sassoulas/setup.cfg-to-pyproject.toml
Migration from ``setup.cfg`` to ``pyproject.toml``
2024-02-05 22:40:44 +01:00
Pierre Sassoulas
0d91539614 Merge pull request #11935 from pytest-dev/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-02-05 21:46:11 +01:00
pre-commit-ci[bot]
835e8032f4 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.15 → v0.2.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.15...v0.2.0)
2024-02-05 20:29:38 +00:00
Pierre Sassoulas
c76ea72331 [pyproject.toml] Moving 'package_data' (py.typed) from setup.cfg 2024-02-05 21:04:33 +01:00
Pierre Sassoulas
dab1583ce1 [pyproject.toml] Remove setup_requires / package_dir in setup.cfg already exists 2024-02-05 21:04:12 +01:00
Pierre Sassoulas
411c2cbf9d [pyproject.toml] Translate dynamic option to pyproject.toml 2024-02-05 21:03:28 +01:00
Pierre Sassoulas
c3583dee0b [pyproject.toml] Translate 'metadata:platforms' to pyproject.toml 2024-02-05 21:03:26 +01:00
Pierre Sassoulas
a1d99e4bdd [pyproject.toml] Move information from setup.cfg to pyproject.toml 2024-02-05 21:02:32 +01:00
Ran Benita
aaa9ca7327 Merge pull request #11918 from pytest-dev/update-plugin-list/patch-20b18f0f9
[automated] Update plugin list
2024-02-05 13:49:09 +02:00
Ran Benita
29094983d7 Merge pull request #11923 from pytest-dev/dependabot/pip/testing/plugins_integration/pytest-django-4.8.0
build(deps): Bump pytest-django from 4.7.0 to 4.8.0 in /testing/plugins_integration
2024-02-05 13:32:11 +02:00
Ran Benita
b8e56557c6 Merge pull request #11925 from pytest-dev/dependabot/pip/testing/plugins_integration/pytest-sugar-1.0.0
build(deps): Bump pytest-sugar from 0.9.7 to 1.0.0 in /testing/plugins_integration
2024-02-05 13:31:50 +02:00
Ran Benita
304ccb4ad7 Merge pull request #11928 from bluetech/setup-cfg-cleanups
Some setup.cfg cleanups
2024-02-05 13:29:49 +02:00
Ran Benita
90634a6060 setup.cfg: remove zip_safe
The setuptools docs say it's obsolete and no longer needed:
https://setuptools.pypa.io/en/latest/deprecated/zip_safe.html#understanding-the-zip-safe-flag
2024-02-05 12:21:37 +02:00
Ran Benita
ccbae95ad4 setup.cfg: remove redundant packages/py_modules
The `package_dir` already achieves this.
2024-02-05 12:16:52 +02:00
Ran Benita
cd9b241047 setup.cfg: remove [devpi:upload] section
Not needed since bfe2cbe875.
2024-02-05 12:08:21 +02:00
Ran Benita
5c67cb2cf5 setup.cfg: remove [check-manifest] section
Not used since 731c35fcab.
2024-02-05 11:59:48 +02:00
Ran Benita
2fc7926bae setup.cfg: remove [build_sphinx] section
Legacy thing that is no longer needed.
2024-02-05 11:59:32 +02:00
Ran Benita
79de84941a setup.cfg: move mypy configuration from setup.cfg to pyproject.toml
TOML is a nicer format than the INI format setup.cfg uses.
2024-02-05 11:59:27 +02:00
Pierre Sassoulas
0d1f4c63fa Merge pull request #11914 - Activate flake8-bugbear and flake8-pyi 2024-02-05 09:37:37 +01:00
dependabot[bot]
2d4e27daf2 build(deps): Bump pytest-sugar in /testing/plugins_integration
Bumps [pytest-sugar](https://github.com/Teemu/pytest-sugar) from 0.9.7 to 1.0.0.
- [Release notes](https://github.com/Teemu/pytest-sugar/releases)
- [Changelog](https://github.com/Teemu/pytest-sugar/blob/main/CHANGES.rst)
- [Commits](https://github.com/Teemu/pytest-sugar/compare/v0.9.7...v1.0.0)

---
updated-dependencies:
- dependency-name: pytest-sugar
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 03:39:30 +00:00
dependabot[bot]
2e50788b6d build(deps): Bump pytest-django in /testing/plugins_integration
Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.7.0 to 4.8.0.
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.7.0...v4.8.0)

---
updated-dependencies:
- dependency-name: pytest-django
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 03:39:23 +00:00
Pierre Sassoulas
3101c026b9 [flake8-bugbear] Remove hidden global state to import only once 2024-02-04 23:08:38 +01:00
Pierre Sassoulas
e193a263c7 [flake8-pyi] Add checks for flake8-pyi and fix existing 2024-02-04 19:27:23 +01:00
Pierre Sassoulas
4eb246d4e1 [flake8-bugbear] noqa B023 not bound by design 2024-02-04 19:27:23 +01:00
Pierre Sassoulas
41ff3584d7 [flake8-bugbear] Fixes a B017 we can actually fix and noqa the two others 2024-02-04 19:27:23 +01:00
Pierre Sassoulas
b62d4b3527 [flake8-bugbear] Remove misleading multiple characters in lstrip
See https://pylint.readthedocs.io/en/stable/user_guide/messages/error/bad-str-strip-call.html
2024-02-04 19:27:23 +01:00
Pierre Sassoulas
e7bab63537 [flake8-bugbear] noqa all the useless comparison that are justified 2024-02-04 19:27:23 +01:00
Pierre Sassoulas
52fba25ff9 [flake8-bugbear] Fix all the useless expressions that are justified 2024-02-04 19:27:23 +01:00
Pierre Sassoulas
fcb818b73c [flake8-bugbear] Re-raise all exceptions with proper exception chaining 2024-02-04 19:27:23 +01:00
Pierre Sassoulas
7eef4619d5 [flake8-bugbear] Add checks from flake8 bugbear 2024-02-04 19:27:16 +01:00
Ran Benita
e28f35c296 Merge pull request #11915 from bluetech/compat-string-types
compat: a couple of minor cleanups
2024-02-04 16:51:43 +02:00
pytest bot
b28bb01c4e [automated] Update plugin list 2024-02-04 00:19:52 +00:00
Ran Benita
3ba4095400 compat: inline helpers into ascii_escaped
The helpers don't add much.
2024-02-03 18:42:05 +02:00
Ran Benita
99e8129ba3 compat: get rid of STRING_TYPES
I think it only obfuscates the code, also calling `bytes` a string type
is pretty misleading in Python 3.
2024-02-03 18:38:38 +02:00
Ran Benita
20b18f0f9a Merge pull request #11913 from bluetech/ruff-version-ignore
Ignore isort on _version.py
2024-02-02 21:55:40 +02:00
Ran Benita
cb5f738858 Ignore isort on _version.py
The file is generated. This makes `ruff src/` run cleanly (when not
running through pre-commit).
2024-02-02 21:29:30 +02:00
Pierre Sassoulas
5be64c31cb Merge pull request #11912 from Pierre-Sassoulas/activate-ruff-checks
[pre-commit] Activate ruff checks and fix existing issues
2024-02-02 20:22:18 +01:00
Pierre Sassoulas
233ab89f13 [ruff] Fix all consider [*cats, garfield] instead of cats + [garfield] 2024-02-02 15:18:38 +01:00
Pierre Sassoulas
8967c527ff [ruff] Activate use next(iter(x)) instead of list(x)[0] and fix issue 2024-02-02 15:18:38 +01:00
Pierre Sassoulas
180a16a344 [ruff] Fix ambiguous characters found in string and comment 2024-02-02 15:18:38 +01:00
Pierre Sassoulas
514376fe29 [ruff] Add ruff's check and autofix existing issues 2024-02-02 15:18:38 +01:00
Pierre Sassoulas
bdfc5c80d8 Merge pull request #11901 from Pierre-Sassoulas/migrate-from-isort-to-ruff
Migrate from ``autoflake``, ``black``, ``isort``, ``pyupgrade``, ``flake8`` and ``pydocstyle``, to ``ruff``
2024-02-02 09:42:07 +01:00
Pierre Sassoulas
9ef905e7a0 [.git-blame-ignore-revs] Add migration to ruff/ruff format and blacken-docs 2024's style 2024-02-02 09:28:09 +01:00
Pierre Sassoulas
4588653b24 Migrate from autoflake, black, isort, pyupgrade, flake8 and pydocstyle, to ruff
ruff is faster and handle everything we had prior.

isort configuration done based on the indication from
https://github.com/astral-sh/ruff/issues/4670, previousely based on
reorder-python-import (#11896)

flake8-docstrings was a wrapper around pydocstyle (now archived) that
explicitly asks to use ruff in https://github.com/PyCQA/pydocstyle/pull/658.

flake8-typing-import is useful mainly for project that support python 3.7
and the one useful check will be implemented in https://github.com/astral-sh/ruff/issues/2302

We need to keep blacken-doc because ruff does not handle detection
of python code inside .md and .rst. The direct link to the repo is
now used to avoid a redirection.

Manual fixes:
- Lines that became too long
- % formatting that was not done automatically
- type: ignore that were moved around
- noqa of hard to fix issues (UP031 generally)
- fmt: off and fmt: on that is not really identical
  between black and ruff
- autofix re-order in pre-commit from faster to slower

Co-authored-by: Ran Benita <ran@unusedvar.com>
2024-02-02 09:27:00 +01:00
Pierre Sassoulas
046f64751b Fix a duplicate assignment in test_config.py
Taken from https://github.com/pytest-dev/pytest/pull/11885 that was closed.
2024-01-31 13:59:25 +01:00
Pierre Sassoulas
4546d5445a Upgrade blacken-doc to black's 2024 style (#11899) 2024-01-31 13:53:21 +01:00
Bruno Oliveira
de161f8791 Merge pull request #11896 from nicoddemus/isort
Replace reorder-python-imports by isort due to black incompatibility
2024-01-31 08:04:39 -03:00
Bruno Oliveira
3be2a9d655 Update and rename .gitblameignore to .git-blame-ignore-revs
Seems like `.git-blame-ignore-revs` is the standard used and also automatically detected by GitHub:

https://github.blog/changelog/2022-03-24-ignore-commits-in-the-blame-view-beta/
2024-01-31 07:50:49 -03:00
John Litborn
e885013c6b fix incorrect example for group_contains (#11892) 2024-01-30 12:00:38 -08:00
Bruno Oliveira
8b54596639 Run pre-commit on all files
Running pre-commit on all files after replacing reorder-python-imports by isort.
2024-01-30 16:35:46 -03:00
Bruno Oliveira
899a6cf2ce Replace reorder-python-imports by isort due to black incompatibility
Unfortunately black and reorder-python-imports are no longer compatible, and from the looks of it probably will not be compatible anytime soon:

https://github.com/asottile/reorder-python-imports/issues/367
https://github.com/asottile/reorder-python-imports/issues/366
https://github.com/psf/black/issues/4175

This replaces `reorder-python-imports` by `isort` configured in a way to yield roughtly the same results.

Closes #11885
2024-01-30 16:35:45 -03:00
Clément Robert
407d984142 Fix an edge case where ExceptionInfo._stringify_exception could crash pytest.raises (#11879)
Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
Co-authored-by: Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
2024-01-30 17:20:30 +02:00
Bruno Oliveira
21bec6cfbe Add changelog entry about FixtureManager.getfixtureclosure changing (#11887)
As discussed in #11868.
2024-01-30 09:41:18 -03:00
Bruno Oliveira
cb57bf50b1 Pin back pytest-asyncio to 8.0.0 compatible release (#11889)
The current version (0.23.4) explicitly does not support pytest 8 yet, so we fallback to the previous release in the hope that at least our integration tests pass.
2024-01-30 06:58:22 -03:00
dependabot[bot]
c0dfc45186 build(deps): Bump hynek/build-and-inspect-python-package (#11877)
Bumps [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases)
- [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: hynek/build-and-inspect-python-package
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-29 10:42:51 -03:00
dependabot[bot]
5855f65d0f build(deps): Bump pytest-asyncio in /testing/plugins_integration (#11878)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.23.3 to 0.23.4.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.23.3...v0.23.4)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-29 10:42:27 -03:00
Russell Martin
14d3707818 Catch OSError from getpass.getuser() (#11875)
- Previously, `getpass.getuser()` would leak an ImportError if the
  USERNAME environment variable was not set on Windows because the `pwd`
  module cannot be imported.
- Starting in Python 3.13.0a3, it only raises `OSError`.

Fixes #11874
2024-01-28 23:07:18 -03:00
github-actions[bot]
8853a57532 [automated] Update plugin list (#11867)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-01-28 13:28:28 +00:00
Bruno Oliveira
878af85aef mypy: disallow untyped defs by default (#11862)
Change our mypy configuration to disallow untyped defs by default, which ensures *new* files added to the code base are fully typed.

To avoid having to type-annotate everything now, add `# mypy: allow-untyped-defs` to files which are not fully type annotated yet.

As we fully type annotate those modules, we can then just remove that directive from the top.
2024-01-28 10:12:42 -03:00
Ran Benita
e7b43b2121 Merge pull request #11859 from bluetech/numbered-dir-scandir
pathlib: speed up `make_numbered_dir` given a large tmp root
2024-01-28 00:05:39 +02:00
Ran Benita
d0f427aec4 Merge pull request #11865 from bluetech/cherry-pick-release
Cherry pick 8.0.0 release notes
2024-01-28 00:03:06 +02:00
Ran Benita
c6da0d20d2 Merge pull request #11864 from bluetech/release-8.0.0
Prepare release version 8.0.0

(cherry picked from commit 24c681d4ee)
2024-01-28 00:00:15 +02:00
Dương Quốc Khánh
a164ed6400 logging: avoid rounding microsecond to 1_000_000 (#11861)
Rounding microsecond might cause it to reach `1_000_000`, which raises a TypeError.
2024-01-27 10:40:31 -03:00
Ran Benita
eb9013d42c pathlib: speed up make_numbered_dir given a large tmp root
The function currently uses `find_suffixes` which iterates the entire
directory searching for files with the given suffix. In some cases
though, like in pytest's selftest, the directory can get big:

    $ ls /tmp/pytest-of-ran/pytest-0/
    7686

and iterating it many times can get slow.

This doesn't fix the underlying issue (iterating the directory) but at
least speeds it up a bit by using `os.scandir` instead of
`path.iterdir`. So `make_numbered_dir` is still slow for pytest's
selftests, but reduces ~10s for me.
2024-01-25 19:19:02 +02:00
Ran Benita
ac2cd72e5f Merge pull request #11856 from bluetech/pluggy-unblock
config: use `pluginmanager.unblock` instead of accessing pluggy's internals
2024-01-25 10:42:13 +02:00
Ran Benita
bca4bb0738 config: use pluginmanager.unblock instead of accessing pluggy's internals
The function was added in pluggy 1.4.0.
2024-01-25 10:20:44 +02:00
Ran Benita
2a77f8d88b Merge pull request #11854 from bluetech/runner-inline-2
runner: inline `call_runtest_hook`
2024-01-24 10:36:28 +02:00
Ran Benita
d972957303 hookspec: document conftest behavior for all hooks (#9496)
Have each hook explain how implementing it in conftests works. This is part of the functional specification of a hook.
2024-01-23 16:08:16 +02:00
Joachim B Haga
44bf7a2ec0 Mark some xfails from #10042 as non-strict (#11832)
Related to #10042, some tests in `test_debugging.py` are actually flaky and should not be considered strict xfailures.
2024-01-22 18:29:14 -03:00
Ran Benita
5ab8972bb5 runner: inline call_runtest_hook
- Reduce the common stacktrace by an entry - this is mostly for benefit
  of devs looking at crash logs.

- Reduce 6 slow `ihook` calls per test to 3.
2024-01-22 16:26:55 +02:00
github-actions[bot]
21440521fa [automated] Update plugin list (#11848)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-01-22 10:14:58 -03:00
dependabot[bot]
79ae968131 build(deps): Bump actions/cache from 3 to 4 (#11852)
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-22 10:11:09 -03:00
Ran Benita
c3fc717ff7 Merge pull request #11843 from bluetech/writing-plugins
doc/writing_plugins: correct inaccuracies re. initial conftest loading
2024-01-19 14:30:20 +02:00
clee2000
d71ef04f11 Escape skip reason in junitxml (#11842)
Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2024-01-18 22:08:26 -03:00
Ran Benita
111ad26f71 doc/writing_plugins: correct inaccuracies re. initial conftest loading 2024-01-18 22:17:55 +02:00
Ran Benita
2178ee86d7 Merge pull request #11826 from bluetech/no-cwd
Prefer using the invocation dir over CWD
2024-01-18 19:02:37 +02:00
Ran Benita
a6dd90a414 python: use invocation dir instead of cwd in fixture-printing code
We should aim to remove all `cwd()` calls except one, otherwise things
will go bad if the working directory changes. Use the invocation dir
instead.
2024-01-18 12:35:32 +02:00
Ran Benita
676f38d04a findpaths: rely on invocation_dir instead of cwd
We should aim to remove all `cwd()` calls except one, otherwise things
will go bad if the working directory changes. Use the invocation dir
instead.
2024-01-18 12:35:32 +02:00
Ran Benita
212c55218b helpconfig: add invocation dir to debug output
The current WD is not supposed to matter, the invocation dir is what
should be relevant. But keep them both for debugging.
2024-01-18 12:35:32 +02:00
Ran Benita
34fafe4c6b config: avoid Path.cwd() call in _set_initial_conftests
We should aim to remove all `cwd()` calls except one, otherwise things
will go bad if the working directory changes. Use the invocation dir
instead.
2024-01-18 12:35:32 +02:00
faph
eefc9d47fc [DOCS] Clarify tmp_path directory location and retention (#11830)
Fixes #11789 and #11790
2024-01-18 07:21:49 -03:00
Bruno Oliveira
7fd561e4ba Properly attach packages to the GH release notes (#11839)
Follow up to https://github.com/pytest-dev/pytest/pull/11754, noticed that the latest GitHub release does not contain the attached files.

Output log from the action:

```
🤔 Pattern 'dist/*' does not match any files.
```
2024-01-17 22:11:10 +00:00
Ran Benita
da9749cd97 Merge pull request #11838 from bluetech/cherry-pick-release
Prepare release version 8.0.0rc2
2024-01-17 23:53:41 +02:00
Ran Benita
ca5bbd0a9f Merge pull request #11835 from pytest-dev/release-8.0.0rc2
Prepare release version 8.0.0rc2

(cherry picked from commit 97960bdd14)
2024-01-17 23:45:21 +02:00
Ran Benita
5cd0535395 testing: temporarily disable test due to hypothesis issue (#11836)
Ref: https://github.com/pytest-dev/pytest/pull/11825#issuecomment-1894094641
2024-01-17 22:53:04 +02:00
Ran Benita
0f5aa5a7d2 Merge pull request #11825 from woutdenolf/fix_missing_fixture_issue
avoid using __file__ in pytest_plugin_registered as can be wrong on Windows
2024-01-17 15:29:29 +02:00
Ran Benita
9ea2e0a79f fixtures: avoid slow pm.get_name(plugin) call by using the new plugin_name hook parameter 2024-01-17 15:06:45 +02:00
Ran Benita
0f5ecd83c4 hookspecs: add plugin_name parameter to the pytest_plugin_registered hook
We have a use case for this in the next commit.

The name can be obtained by using `manager.get_name(plugin)`, however
this is currently O(num plugins) in pluggy, which would be good to
avoid. Besides, it seems generally useful.
2024-01-17 15:06:42 +02:00
Ran Benita
6b9bba2edb pre-commit: add pluggy to mypy deps
Otherwise mypy doesn't fully recognize pluggy's typing for some reason
or another.
2024-01-17 15:01:55 +02:00
woutdenolf
6e9f566d79 avoid using __file__ in pytest_plugin_registered as can be wrong on Windows 2024-01-17 15:01:04 +02:00
Ran Benita
a6708b9254 Merge pull request #11822 from bluetech/doc-hookspec
hookspec: minor doc tweaks
2024-01-16 18:34:33 +02:00
Florian Bruhin
e895c9d38c doc: Remove sold out training (#11823) 2024-01-16 14:53:10 +01:00
Ran Benita
c973ccb622 hookspec: modernize a reference 2024-01-15 23:47:19 +02:00
Ran Benita
dd1447cfe5 hookspec: move pytest_load_initial_conftests up
Reflect the order in which the plugins are called.
2024-01-15 23:46:07 +02:00
Ran Benita
9ad8b9fc36 hookspec: remove explicit :param types
Duplicates info in the type annotations which sphinx understands.
2024-01-15 23:35:53 +02:00
Florian Bruhin
348e6de102 doc: Update training dates and add pytest sprint (#11819) 2024-01-15 21:04:08 +01:00
Ran Benita
9af6d46371 Merge pull request #11817 from bluetech/conftesterror-cleanup
config: stop using exception triplets in `ConftestImportError`
2024-01-15 13:26:46 +02:00
Ran Benita
e1074f9c3d config: stop using exception triplets in ConftestImportError
In recent python versions all of the info is on the exception object
itself so no reason to deal with the annoying tuple.
2024-01-15 09:47:55 +02:00
Ran Benita
6e74601466 Merge pull request #11815 from bluetech/iter_parents-rename
nodes: rename `iterparents()` -> `iter_parents()`
2024-01-15 09:46:59 +02:00
Ronny Pfannschmidt
3acbdc2f79 Merge pull request #11814 from bluetech/pycache-ignore-collect
main,python: move `__pycache__` ignore to `pytest_ignore_collect`
2024-01-14 17:26:34 +01:00
Ran Benita
707642ad35 nodes: rename iterparents() -> iter_parents()
After the fact I remembered there is `node.iter_markers()` so let's be
consistent with that rather than with `listchain()`.
2024-01-14 15:17:41 +02:00
Ran Benita
2413d1b214 main,python: move __pycache__ ignore to pytest_ignore_collect
This removes one thing that directory collectors need to worry about.

This adds one hook dispatch per `__pycache__` file, but I think it's
worth it for consistency.
2024-01-14 15:05:15 +02:00
Ran Benita
2bb0eca347 Merge pull request #11795 from lesteve/improve-assert-mod-not-in-mods-error-message
Improve assert mod not in mods error message
2024-01-14 13:39:14 +02:00
Loïc Estève
1c9d6834fd Improve assert mod not in mods error message
[ran: tweaked message, made the formatting lazy]
2024-01-14 13:21:54 +02:00
github-actions[bot]
c6ed86453f [automated] Update plugin list (#11811)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-01-14 01:04:53 -03:00
Ran Benita
e403bbf1a9 Merge pull request #11708 from fcharras/FIX/crash_during_conftest_collection
FIX key formating divergence when inspecting plugin dictionary.
2024-01-13 21:45:36 +02:00
Franck Charras
a7c2549321 Fix assert mod not in mods crash
Fix #27806.

Co-authored-by: Loïc Estève <loic.esteve@ymail.com>
Co-authored-by: Ran Benita <ran@unusedvar.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2024-01-13 20:19:28 +02:00
Ran Benita
d65bcd9a3b Merge pull request #11808 from bluetech/doctest-conftest
doctest: remove special conftest handling
2024-01-13 19:50:20 +02:00
Ran Benita
06dbd3c21c doctest: remove special conftest handling
(Diff better viewed ignoring whitespace)

Since e1c66ab0ad, conftest loading is
handled at the directory level before sub-nodes are collected, so there
is no need for the doctest plugin to handle it specially.

This was probably the case even before
e1c66ab0ad, but I haven't verified this.
2024-01-13 11:18:41 +02:00
Ran Benita
1b78de4e21 Merge pull request #11803 from pytest-dev/package-scope-note
Add note about package scope
2024-01-12 22:15:33 +02:00
mrbean-bremen
82fda31e99 Clarify package scope
The behavior of package scope is surprising to some
(as seen by related questions on SO), this should clarify it a bit.
2024-01-12 20:03:30 +01:00
Ran Benita
5645fa45fb Merge pull request #11801 from bluetech/node-iterchain
nodes: add `Node.iterchain()` function
2024-01-12 11:01:48 +02:00
Ran Benita
5bd5b80afd nodes: add Node.iterparents() function
This is a useful addition to the existing `listchain`. While `listchain`
returns top-to-bottom, `iterparents` is bottom-to-top and doesn't require
an internal full iteration + `reverse`.
2024-01-11 23:19:45 +02:00
Ran Benita
bd58c09500 Merge pull request #11799 from bluetech/rm-nose-compat_co_firstlineno
python: remove support for nose's `compat_co_firstlineno`
2024-01-11 13:13:30 +02:00
Faisal Fawad
996e45d66a Slight change to tmp_path documentation to more clearly illustrate its behavior (#11800) 2024-01-11 11:01:07 +00:00
Ran Benita
c7d85c5dc6 python: remove support for nose's compat_co_firstlineno
Since we're removing nose support, let's also drop support for this
attribute.

From doing a code search on github, this seems completely unused outside
of nose, except for some projects which used to use it, but no longer
do.
2024-01-10 19:22:19 +02:00
Ronny Pfannschmidt
b1c430820f Merge pull request #11794 from bluetech/fixturedef-ref-cycle
A few cleanups
2024-01-10 06:44:14 +01:00
Ran Benita
35a3863b15 config: clarify a bit of code in _importconftest 2024-01-09 23:49:03 +02:00
Ran Benita
368fa2c03e fixtures: remove unhelpful FixtureManager.{FixtureLookupError,FixtureLookupErrorRepr}
Couldn't find any reason for this indirection, nor any plugins which
rely on it. Seems like historically it was done to avoid some imports...
2024-01-09 23:33:07 +02:00
Ran Benita
372c17e228 fixtures: avoid FixtureDef <-> FixtureManager reference cycle
There is no need to store the FixtureManager on each FixtureDef.
2024-01-09 23:29:58 +02:00
Ran Benita
c4a356eaee Merge pull request #11718 from pytest-dev/dependabot/github_actions/hynek/build-and-inspect-python-package-2.0.0
build(deps): Bump hynek/build-and-inspect-python-package from 1.5.4 to 2.0.0
2024-01-09 21:44:43 +02:00
dependabot[bot]
2270cab1c2 build(deps): Bump actions/download-artifact from 3 to 4
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 21:12:42 +02:00
dependabot[bot]
956d0e5e9d build(deps): Bump hynek/build-and-inspect-python-package
Bumps [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) from 1.5.4 to 2.0.0.
- [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases)
- [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v1.5.4...v2.0.0)

---
updated-dependencies:
- dependency-name: hynek/build-and-inspect-python-package
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 21:12:27 +02:00
pre-commit-ci[bot]
7bc8385924 [pre-commit.ci] pre-commit autoupdate (#11792)
updates:
- [github.com/PyCQA/flake8: 6.1.0 → 7.0.0](https://github.com/PyCQA/flake8/compare/6.1.0...7.0.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-08 21:19:35 +00:00
Ran Benita
9b7e10a3c0 Merge pull request #11788 from pytest-dev/dependabot/pip/testing/plugins_integration/pytest-asyncio-0.23.3
build(deps): Bump pytest-asyncio from 0.23.2 to 0.23.3 in /testing/plugins_integration
2024-01-08 22:40:47 +02:00
dependabot[bot]
913d93debb build(deps): Bump pytest-asyncio in /testing/plugins_integration
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.23.2 to 0.23.3.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.23.2...v0.23.3)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 20:24:22 +00:00
Ran Benita
97dfc3429e Merge pull request #11785 from bluetech/matchfactories-nodes
fixtures: match fixtures based on actual node hierarchy, not textual nodeids
2024-01-08 22:23:08 +02:00
Ran Benita
992d0f082f fixtures: match fixtures based on actual node hierarchy, not textual nodeids
Refs #11662.

--- Problem

Each fixture definition has a "visibility", the `FixtureDef.baseid`
attribute. This is nodeid-like string. When a certain `node` requests a
certain fixture name, we match node's nodeid against the fixture
definitions with this name.

The matching currently happens on the *textual* representation of the
nodeid - we split `node.nodeid` to its "parent nodeids" and then check
if the fixture's `baseid` is in there.

While this has worked so far, we really should try to avoid textual
manipulation of nodeids as much as possible. It has also caused problem
in an odd case of a `Package` in the root directory: the `Package` gets
nodeid `.`, while a `Module` in it gets nodeid `test_module.py`. And
textually, `.` is not a parent of `test_module.py`.

--- Solution

Avoid this entirely by just checking the node hierarchy itself. This is
made possible by the fact that we now have proper `Directory` nodes
(`Dir` or `Package`) for the entire hierarchy.

Also do the same for `_getautousenames` which is a similar deal.

The `iterparentnodeids` function is no longer used and is removed.
2024-01-08 21:36:51 +02:00
Ran Benita
b968f63ca5 Merge pull request #11780 from bluetech/register-fixture
Add an internal "register fixture" API and use it replace object patching for fixture injection
2024-01-08 21:24:54 +02:00
Ran Benita
c8792bd080 python,unittest: replace obj fixture patching with FixtureManager._register_fixture
Instead of modifying user objects like modules and classes that we
really shouldn't be touching, use the new `_register_fixture` internal
API to do it directly.
2024-01-08 21:02:59 +02:00
Ran Benita
3234c79ee5 fixtures: add an internal API for registering a fixture
Add a function on the `FixtureManager` to register a fixture with
pytest. Currently this can only be done through `parsefactories`.

My aim is to eventually make something like this available to plugins,
as it's a pretty common need.
2024-01-08 21:02:59 +02:00
Ran Benita
851b72f289 Merge pull request #11776 from bluetech/unittest-xunit-inline
unittest: inline `_make_xunit_fixture`
2024-01-08 21:02:24 +02:00
Ran Benita
1d7349d18c Merge pull request #11774 from bluetech/fspath-cleanups
Small `fspath` cleanups
2024-01-08 21:01:56 +02:00
github-actions[bot]
5747a6c06e [automated] Update plugin list (#11784)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2024-01-07 10:20:38 -03:00
Fabian Sturm
13eacdad8a Add summary for xfails with -rxX option (#11574)
Co-authored-by: Brian Okken <1568356+okken@users.noreply.github.com>
2024-01-05 09:59:19 -03:00
Ran Benita
a616adf3ae unittest: inline _make_xunit_fixture
The indirection makes things harder to follow in this case IMO.
2024-01-05 14:37:03 +02:00
Ran Benita
685e52ec30 nodes: fix attribute name fspath -> path in get_fslocation_from_item 2024-01-04 22:32:34 +02:00
Ran Benita
7b4ab8134e fixtures: remove unnecessary fspath workaround 2024-01-04 22:32:34 +02:00
Ran Benita
c2a4a8d518 Merge pull request #11769 from neutrinoceros/fix_warns_docstring
Fix a mistake in pytest.warns' docstring (expect_warning accepts tuples, not any sequence)
2024-01-04 14:27:49 +02:00
Clément Robert
ac96256272 Fix a mistake in pytest.warns' docstring (expect_warning accepts tuples, not any sequence) 2024-01-04 11:51:12 +01:00
Bruno Oliveira
d38193646d Update docstring of scripts/generate-gh-release-notes.py (#11767)
Follow up to #11754.
2024-01-04 07:29:20 -03:00
Bruno Oliveira
cd07177906 Merge pull request #11754 from nicoddemus/release-notes
Improve GitHub release workflow
2024-01-03 20:14:48 -03:00
Bruno Oliveira
6321b74fae Enable type-checking in scripts/ 2024-01-03 19:47:56 -03:00
Bruno Oliveira
5aa289e478 Improve GitHub release workflow
This changes the existing script to just generate the release notes and delegate the actual publishing to the `softprops/action-gh-release@v1` action.

This allows us to delete the custom code, which failed recently in https://github.com/pytest-dev/pytest/actions/runs/7370258570/job/20056477756.
2024-01-03 19:47:56 -03:00
Ben Brown
12b9bd5801 Fix teardown error reporting when --maxfail=1 (#11721)
Co-authored-by: Ran Benita <ran@unusedvar.com>
2024-01-03 19:39:24 +02:00
Ran Benita
f017df443a Merge pull request #11757 from bluetech/rm-removed-in-8
Remove pytest 8 deprecations
2024-01-03 16:53:10 +02:00
Ran Benita
1ba07450e4 doc/deprecations: fix incorrect title level 2024-01-03 14:29:45 +02:00
Ran Benita
215f4d1fab Remove PytestRemovedIn8Warning
Per our deprecation policy.
2024-01-03 14:29:45 +02:00
Ran Benita
6c89f9261c Remove deprecated py.path (fspath) node constructor arguments 2024-01-03 14:29:45 +02:00
Ran Benita
a98f02d423 Remove deprecated py.path hook arguments 2024-01-03 14:29:42 +02:00
Marc Bresson
effc2b0529 Clarified markers ini property. Fix #11738 (#11739) 2024-01-03 14:20:54 +02:00
Ran Benita
2c5c97b6d1 Merge pull request #11760 from bluetech/fix-highlight-empty-source
terminalwriter: fix crash trying to highlight empty source
2024-01-03 09:38:29 +02:00
Ran Benita
cb5a42c836 terminalwriter: fix crash trying to highlight empty source
For quick checking I don't know how we can reach here with an empty
source, so test just checks the function directly.

Fix #11758.
2024-01-02 19:37:24 +02:00
Ran Benita
0f18a7fe5e Remove deprecated nose support 2024-01-02 12:20:47 +02:00
Ran Benita
0591569b4b Remove deprecated pytest.{exit,fail,skip}(msg=...) argument 2024-01-02 12:20:47 +02:00
Ran Benita
477959ef7d Remove deprecated pytest.Instance backward compat 2024-01-02 12:20:47 +02:00
Ran Benita
4147c92b21 Remove deprecated pytest.warns(None) 2024-01-02 12:20:47 +02:00
Ran Benita
10fbb2325f Remove deprecated Parser.addoption backward compatibilities 2024-01-02 12:20:47 +02:00
Ran Benita
1f8b39ed32 Remove deprecated --strict option 2024-01-02 12:20:47 +02:00
Ran Benita
f4e7b0d6e0 Remove deprecated pytest_cmdline_preparse hook 2024-01-02 12:20:47 +02:00
Ran Benita
f13724e2e3 Remove deprecated {FSCollector,Package}.{gethookproxy,isinitpath} 2024-01-02 12:20:47 +02:00
Ran Benita
a53984a55b Merge pull request #11756 from pytest-dev/cherry-pick-release
Cherry pick 8.0.0rc1 release notes
2024-01-02 11:20:03 +02:00
Ran Benita
d3c7ba310c Merge pull request #11744 from pytest-dev/release-8.0.0rc1
Prepare release 8.0.0rc1

(cherry picked from commit 665e4e58d3)
2024-01-02 10:59:26 +02:00
Ran Benita
6bec880283 Merge pull request #11753 from bluetech/cherry-pick-release
Cherry-pick 7.4.4 release notes
2023-12-31 14:26:50 +02:00
Ran Benita
a1b6b7473b Merge pull request #11752 from pytest-dev/release-7.4.4
Prepare release 7.4.4

(cherry picked from commit 18dcd9d38d)
2023-12-31 14:15:46 +02:00
Ran Benita
3701d1218b Merge pull request #11746 from pytest-dev/update-plugin-list/patch-acd445a3f
[automated] Update plugin list
2023-12-31 10:26:34 +02:00
Ran Benita
d220880924 nodes: fix tracebacks from collection errors are not getting pruned (#11711)
Fix #11710.
2023-12-31 10:14:23 +02:00
Ran Benita
640f84a5aa Merge pull request #11745 from bluetech/change-marked-fixture-removal
Change "Marks applied to fixtures" removal from 8 to 9
2023-12-31 10:10:20 +02:00
pytest bot
460c38915d [automated] Update plugin list 2023-12-31 00:20:30 +00:00
Ran Benita
a71a95b54c Change "Marks applied to fixtures" removal from 8 to 9
The deprecation has only been added in 8.0, so can't be removed in 8.
That will have to wait for 9.
2023-12-30 22:14:40 +02:00
Ran Benita
acd445a3f3 Merge pull request #11646 from bluetech/pkg-collect
Rework Session and Package collection
2023-12-30 12:51:48 +02:00
Ran Benita
c7ee55993b Merge pull request #11736 from pytest-dev/update-plugin-list/patch-52db918a2
[automated] Update plugin list
2023-12-30 12:49:17 +02:00
Ran Benita
b9855b244d Merge pull request #11737 from pytest-dev/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-12-30 12:35:31 +02:00
pre-commit-ci[bot]
1e5aab1b2b [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/psf/black: 23.12.0 → 23.12.1](https://github.com/psf/black/compare/23.12.0...23.12.1)
- [github.com/pre-commit/mirrors-mypy: v1.7.1 → v1.8.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.1...v1.8.0)
2023-12-25 20:43:18 +00:00
pytest bot
f93c0fc34e [automated] Update plugin list 2023-12-24 00:20:08 +00:00
Michał Górny
52db918a27 Fix handling empty values of NO_COLOR and FORCE_COLOR (#11712)
* Fix handling empty values of NO_COLOR and FORCE_COLOR

Fix handling NO_COLOR and FORCE_COLOR environment variables to correctly
be ignored when they are set to an empty value, as defined
in the specification:

> Command-line software which adds ANSI color to its output by default
> should check for a NO_COLOR environment variable that, when present
> *and not an empty string* (regardless of its value), prevents
> the addition of ANSI color.

(emphasis mine, https://no-color.org/)

The same is true of FORCE_COLOR, https://force-color.org/.

* Streamline testing for FORCE_COLOR and NO_COLOR

Streamline the tests for FORCE_COLOR and NO_COLOR variables, and cover
all possible cases (unset, set to empty, set to "1").  Combine the two
assert functions into one taking boolean parameters.  Mock file.isatty
in all circumstances to ensure that the environment variables take
precedence over the fallback value resulting from isatty check (or that
the fallback is actually used, in the case of both FORCE_COLOR
and NO_COLOR being unset).
2023-12-23 10:12:13 +02:00
Ran Benita
54a0ee02ea Merge pull request #11732 from bluetech/typing-tweaks
Some minor typing tweaks
2023-12-22 13:00:52 +02:00
Benjamin Schubert
88ae27da08 Add syntactic highlights to the error explanations (#11661)
* Put a 'reset' color in front of the highlighting

When doing the highlighting, some lexers will not set the initial color
explicitly, which may lead to the red from the errors being propagated
to the start of the expression

* Add syntactic highlighting to the error explanations

This updates the various error reporting to highlight python code when
displayed, to increase readability and make it easier to understand
2023-12-21 17:11:56 +00:00
Ran Benita
e06a3d02f8 Merge pull request #11715 from pytest-dev/update-plugin-list/patch-047ba83da
[automated] Update plugin list
2023-12-21 17:16:29 +02:00
Ran Benita
75f292d9df Some minor typing tweaks 2023-12-19 23:29:27 +02:00
pre-commit-ci[bot]
581762fcba [pre-commit.ci] pre-commit autoupdate (#11722)
updates:
- [github.com/psf/black: 23.11.0 → 23.12.0](https://github.com/psf/black/compare/23.11.0...23.12.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-18 21:43:27 +00:00
Benjamin Schubert
803b190a17 Merge pull request #11660 from BenjaminSchubert/bschubert/simplify-pprint
Remove more unused pprint features
2023-12-18 09:04:35 +00:00
Benjamin Schubert
283a746dad pprint: Remove conversion to int, we only accept those 2023-12-18 08:35:57 +00:00
Benjamin Schubert
64b5b665cf pprint: Remove the option to add underscore for numbers
This is never used, we can remove this. If we wanted instead, we could
always enable it
2023-12-18 08:35:57 +00:00
Benjamin Schubert
6aa35f772f pprint: Remove the option to sort dictionaries, we always do it 2023-12-18 08:35:57 +00:00
Benjamin Schubert
03b24e5b30 pprint: Remove the format method, it's not used outside of pprint
Let's reduce the API surface for the bundled PrettyPrinter to what we
really need and use
2023-12-18 08:35:57 +00:00
dependabot[bot]
7541c5a999 build(deps): Bump anyio[curio,trio] in /testing/plugins_integration (#11717)
Bumps [anyio[curio,trio]](https://github.com/agronholm/anyio) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/agronholm/anyio/releases)
- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/anyio/compare/4.1.0...4.2.0)

---
updated-dependencies:
- dependency-name: anyio[curio,trio]
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 06:33:59 +01:00
pytest bot
27f7cee238 [automated] Update plugin list 2023-12-17 00:20:43 +00:00
Arthur Richard
047ba83dab Improve pytest.exit docs (#11698)
Fixes #11695
2023-12-14 08:14:36 -03:00
Tom Mortimer-Jones
2b86d2bddc Typo in fixtures.rst (#11699) 2023-12-13 13:24:43 +01:00
dependabot[bot]
dfc910ee90 build(deps): Bump django from 4.2.7 to 5.0 in /testing/plugins_integration (#11692)
* build(deps): Bump django in /testing/plugins_integration

Bumps [django](https://github.com/django/django) from 4.2.7 to 5.0.
- [Commits](https://github.com/django/django/compare/4.2.7...5.0)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump python version on the plugin job

https://github.com/pytest-dev/pytest/pull/11692#issuecomment-1849963332

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
2023-12-11 14:18:43 +00:00
dependabot[bot]
ab307b3402 build(deps): Bump actions/setup-python from 4 to 5 (#11690)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-11 09:46:13 +01:00
dependabot[bot]
8ce76c307e build(deps): Bump actions/stale from 8 to 9 (#11691)
Bumps [actions/stale](https://github.com/actions/stale) from 8 to 9.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v8...v9)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-11 09:28:50 +01:00
dependabot[bot]
ef8bf82a78 build(deps): Bump pytest-asyncio in /testing/plugins_integration (#11693)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.23.1 to 0.23.2.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.23.1...v0.23.2)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-11 09:24:52 +01:00
Ran Benita
e1c66ab0ad Different fix for conftest loading
--- Current main

In current main (before pervious commit), calls to gethookproxy/ihook
are the trigger for loading non-initial conftests. This basically means
that conftest loading is done almost as a random side-effect,
uncontrolled and very non-obvious. And it also dashes any hope of making
gethookproxy faster (gethookproxy shows up prominently in pytest
profiles).

I've wanted to improve this for a while, #11268 was the latest step
towards that.

--- PR before change

In this PR, I ran into a problem.

Previously, Session and Package did all of the directory traversals
inside of their collect, which loaded the conftests as a side effect. If
the conftest loading failed, it will occur inside of the collect() and
cause it to be reported as a failure.

Now I've changed things such that Session.collect and Package.collect no
longer recurse, but just collect their immediate descendants, and
genitems does the recursive expansion work.

The problem though is that genitems() doesn't run inside of specific
collector's collect context. So when it loads a conftest, and the
conftest loading fails, the exception isn't handled by any CollectReport
and causes an internal error instead.

The way I've fixed this problem is by loading the conftests eagerly in a
pytest_collect_directory post-wrapper, but only during genitems to make
sure the directory is actually selected.

This solution in turn caused the conftests to be collected too early;
specifically, the plugins are loaded during the parent's collect(), one
after the other as the directory entries are collected. So when the
ihook is hoisted out of the loop, new plugins are loaded inside the
loop, and due to the way the hook proxy works, they are added to the
ihook even though they're supposed to be scoped to the child collectors.
So no hoisting.

--- PR after change

Now I've come up with a better solution: since now the collection tree
actually reflects the filesystem tree, what we really want is to load
the conftest of a directory right before we run its collect(). A
conftest can affect a directory's collect() (e.g. with a
pytest_ignore_collect hookimpl), but it cannot affect how the directory
node itself is collected. So I just moved the conftest loading to be
done right before calling collect, but still inside the CollectReport
context.

This allows the hoisting, and also removes conftest loading from
gethookproxy since it's no longer necessary. And it will probably enable
further cleanups. So I'm happy with it.
2023-12-10 17:01:39 +02:00
Ran Benita
385796ba49 Rework Session and Package collection
Fix #7777.
2023-12-10 17:01:39 +02:00
Ran Benita
f411c8d6d7 main: add with_parents parameter to isinitpath
Will be used in upcoming commit.
2023-12-10 16:32:54 +02:00
Ran Benita
c7fcb3f281 Merge pull request #11689 from pytest-dev/update-plugin-list/patch-d1675646f
[automated] Update plugin list
2023-12-10 09:59:06 +02:00
Ran Benita
c1339628d6 Merge pull request #11684 from bluetech/docs-nitpicky
docs: enable Sphinx nitpicky mode
2023-12-10 09:42:30 +02:00
Ran Benita
397769c45e Merge pull request #11677 from bluetech/nodes-abc
nodes,python: mark abstract node classes as ABCs
2023-12-10 09:41:46 +02:00
pytest bot
5381cd083f [automated] Update plugin list 2023-12-10 00:20:38 +00:00
Ran Benita
0ae02e2165 nodes,python: mark abstract node classes as ABCs
Fixes #11676
2023-12-07 16:41:07 +02:00
Ran Benita
2aa8743bbe doc: enable Sphinx nitpicky mode
See:
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-nitpicky

This ensures we have no more broken references.
2023-12-07 12:14:45 +02:00
Ran Benita
ee91d095f6 doc: fix more broken Sphinx references 2023-12-07 11:50:02 +02:00
Ran Benita
f76af423b0 doc/reference: document FixtureLookupError 2023-12-07 11:50:02 +02:00
Ran Benita
4918883336 python_api: remove unused function _non_numeric_type_error 2023-12-07 11:03:52 +02:00
Ran Benita
d1675646f2 Merge pull request #11678 from pytest-dev/doc-nitpicks
doc: fix some broken Sphinx references
2023-12-07 09:40:52 +02:00
Ran Benita
9056db4de5 doc: fix some broken Sphinx references 2023-12-07 00:30:35 +02:00
Ran Benita
a5ee9f2ecd doc: document pytest.{hookspec,hookimpl} in the API Reference
Makes sense for them to be there; also allows for Sphinx refs.
2023-12-07 00:11:42 +02:00
Benjamin Schubert
a536f49d91 Separate the various parts of the error report with newlines (#11659)
Previously the error report would have all sections glued together:

- The assertion representation
- The error explanation
- The full diff

This makes it hard to see at a glance where which one starts and ends.

One of the representation (dataclasses, tuples, attrs) does display a
newlines at the start already.

Let's add a newlines before the error explanation and before the full
diff, so we get an easier to read report.

This has one disadvantage: we get one line less in the least verbose
mode, where the output gets truncated.
2023-12-06 09:25:00 +00:00
Ran Benita
cd269f0e6d Merge pull request #11668 from bluetech/rm-setup-py
Remove `setup.py`
2023-12-05 17:29:43 +02:00
Ran Benita
b8118ab70d Remove setup.py
Fix #11667.
2023-12-04 22:45:59 +02:00
dependabot[bot]
022f1b4de5 build(deps): Bump pytest-bdd in /testing/plugins_integration (#11665)
Bumps [pytest-bdd](https://github.com/pytest-dev/pytest-bdd) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/pytest-dev/pytest-bdd/releases)
- [Changelog](https://github.com/pytest-dev/pytest-bdd/blob/master/CHANGES.rst)
- [Commits](https://github.com/pytest-dev/pytest-bdd/compare/7.0.0...7.0.1)

---
updated-dependencies:
- dependency-name: pytest-bdd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-12-04 13:58:18 +00:00
dependabot[bot]
db8c6f1da8 build(deps): Bump pytest-asyncio in /testing/plugins_integration (#11664)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.21.1 to 0.23.1.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.21.1...v0.23.1)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-04 10:41:34 -03:00
dependabot[bot]
3e14c4b3c4 build(deps): Bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11 (#11663)
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.10 to 1.8.11.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.10...v1.8.11)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-04 10:41:20 -03:00
github-actions[bot]
714ce2e872 [automated] Update plugin list (#11658)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-12-03 11:49:36 -03:00
touilleWoman
5689d806cf Fix "Customizing Colors" documentation section (#11652)
Fixes #11573
2023-12-01 11:25:01 -03:00
Ran Benita
0f6c17ca83 Merge pull request #11654 from pytest-dev/testing-unnecessary-skip
testing: remove a no longer necessary skip
2023-12-01 00:28:23 +02:00
Ran Benita
ef699f8c17 testing: remove a no longer necessary skip
pytest-xdist was released at 2019-02-15, seems enough time.
2023-11-30 19:53:31 +02:00
Ran Benita
81c06b3955 Merge pull request #11650 from bluetech/tr-test-isolation
testing: fix isolation issue in `tr` fixture
2023-11-28 20:14:20 +02:00
Ran Benita
968510b6aa testing: fix isolation issue in tr fixture
The default for `_prepareconfig` is to use `sys.argv`, which in this
case are the flags passed to (top-level) `pytest`. This is not the
intention, the tests themselves should not be affected by it.
2023-11-28 19:54:24 +02:00
Ran Benita
5782aab017 Merge pull request #11648 from bluetech/fix-locale-encoding
pytester: avoid EncodingWarning from `locale.getpreferredencoding`
2023-11-28 18:12:28 +02:00
Ran Benita
ad1bccdead pytester: avoid EncodingWarning from locale.getpreferredencoding
When running `tox -e py-lsof` I get a deluge of this warning:

```
src/pytest/.tox/py-lsof-numpy-pexpect/lib/python3.11/site-packages/_pytest/pytester.py:130: EncodingWarning: UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.
```

Use `locale.getencoding` instead.
2023-11-28 17:40:58 +02:00
Benjamin Schubert
172bf89ad1 Merge pull request #11644 from BenjaminSchubert/bschubert/pprint-cleanup
Various cleanups of the vendored pprint module
2023-11-27 22:54:46 +00:00
Benjamin Schubert
88c3546006 pprint: use a set instead of a dict for the context
This is really what the context is doing, we don't need to use a dict
for it
2023-11-27 22:40:09 +00:00
Benjamin Schubert
50607297f4 pprint: Remove tracking of whether an object is readable
This information is not used anywhere
2023-11-27 22:40:09 +00:00
Benjamin Schubert
767f08cecd pprint: Remove tracking of whether the object is recursive
This information is not used anywhere, we can simplify by just not
tracking it
2023-11-27 22:40:09 +00:00
Benjamin Schubert
e5a448cd5f pprint: Type annotate the module
This will make it easier to refactor
2023-11-27 22:40:09 +00:00
Benjamin Schubert
64e72b79f6 pprint: Remove unused arguments on PrettyPrinter 2023-11-27 22:40:09 +00:00
pre-commit-ci[bot]
c4375f14b8 [pre-commit.ci] pre-commit autoupdate (#11645)
updates:
- [github.com/pre-commit/mirrors-mypy: v1.7.0 → v1.7.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.0...v1.7.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-27 20:55:06 +00:00
Benjamin Schubert
2d1710e0e9 Improve the full diff by having more consistent indentation in the PrettyPrinter (#11571)
The normal default pretty printer is not great when objects are nested
and it can get hard to read the diff.

Instead, provide a pretty printer that behaves more like when json get
indented, which allows for smaller, more meaningful differences, at
the expense of a slightly longer diff.

This does not touch the other places where the pretty printer is used,
and only updated the full diff one.
2023-11-27 16:47:18 +02:00
Ran Benita
fe8cda051b Merge pull request #11642 from pytest-dev/dependabot/pip/testing/plugins_integration/anyio-curiotrio--4.1.0
build(deps): Bump anyio[curio,trio] from 4.0.0 to 4.1.0 in /testing/plugins_integration
2023-11-27 10:22:45 +02:00
Ran Benita
df963fded7 Merge pull request #11641 from pytest-dev/dependabot/pip/testing/plugins_integration/pytest-rerunfailures-13.0
build(deps): Bump pytest-rerunfailures from 12.0 to 13.0 in /testing/plugins_integration
2023-11-27 10:20:09 +02:00
dependabot[bot]
6053bb8d6a build(deps): Bump anyio[curio,trio] in /testing/plugins_integration
Bumps [anyio[curio,trio]](https://github.com/agronholm/anyio) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/agronholm/anyio/releases)
- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/anyio/compare/4.0.0...4.1.0)

---
updated-dependencies:
- dependency-name: anyio[curio,trio]
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:05:25 +00:00
dependabot[bot]
03220f7c9e build(deps): Bump pytest-rerunfailures in /testing/plugins_integration
Bumps [pytest-rerunfailures](https://github.com/pytest-dev/pytest-rerunfailures) from 12.0 to 13.0.
- [Changelog](https://github.com/pytest-dev/pytest-rerunfailures/blob/master/CHANGES.rst)
- [Commits](https://github.com/pytest-dev/pytest-rerunfailures/compare/12.0...13.0)

---
updated-dependencies:
- dependency-name: pytest-rerunfailures
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:05:20 +00:00
Michał Górny
85e0f676c5 Reset color-related envvars for testing (#11638)
Reset color-related environment variables in a fixture to prevent them
from affecting test results.  Otherwise, some of the tests fail
e.g. if NO_COLOR is set in the calling environment.
2023-11-26 11:09:18 -03:00
github-actions[bot]
e0d5754d5d [automated] Update plugin list (#11640)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-11-26 11:09:03 -03:00
Jens Tröger
acab13fcc9 Add new filtering() method to LogCaptureFixture class (#11625)
Fixes #11610
2023-11-24 09:38:34 -03:00
Simon Blanchard
a42530a09d Fix for operation on closed file in faulthandler teardown (#11584) 2023-11-22 22:05:00 +02:00
Ran Benita
fdb8bbf154 Merge pull request #11626 from BenjaminSchubert/bschubert/vendored-pprint
Vendor in and absorb the pprint module from upstream
2023-11-20 18:13:34 +02:00
Benjamin Schubert
53d7b5ed3e Add some tests for the pprint module 2023-11-20 13:00:08 +00:00
Benjamin Schubert
19934b2b0c Merge the AlwaysDispathPrettyPrinter into the now vendored PrettyPrinter
We don't need to keep the separation anymore, and this will make it
easier to extend
2023-11-20 13:00:00 +00:00
Benjamin Schubert
2953120003 Fix typing information for the pprint module
There is more type information that could be added. We can add those
later to make it easier, this is jsut the minimum to allow linting to
pass
2023-11-20 13:00:00 +00:00
Benjamin Schubert
5fae5ef73e Apply project-wide formatting standard to the pprint module (black) 2023-11-20 13:00:00 +00:00
Benjamin Schubert
66f2f20eff Run pyupgrade on the pprint module 2023-11-20 13:00:00 +00:00
Benjamin Schubert
2322668344 Remove unneeded pprint interfaces
There are parts of the original pprint module that we won't need, let's
limit the surface and remove the unnecessary code
2023-11-20 13:00:00 +00:00
Benjamin Schubert
eb6ad08e5d Vendor in the pprint module to allow further modifications
We already have the AlwaysDispatchingPrettyPrinter override of the
default pretty printer. In order to make more in depth changes, we
need to copy the upstream version in, as it doesn't lend itself well to
being extended.

This does a verbatime copy, adding provenance information at the top.
2023-11-20 13:00:00 +00:00
Anthony Sottile
0916191827 use name-independent github actions badge (#11628)
if we were ever to change the `name:` field in `test.yml` this would suddenly break -- this references the workflow file directly (and is what github generates now for badges)
2023-11-19 13:19:30 -03:00
github-actions[bot]
476bab84f7 [automated] Update plugin list (#11627)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-11-19 11:57:25 -03:00
Patrick Lannigan
9dc1fc4523 Add verbosity_assertions and config.get_verbosity
Fixes #11387
2023-11-19 11:56:29 -03:00
Avasam
80442ae2f2 Use False, instead of None as default for _XfailMarkDecorator's condition param and update doc (#11600) 2023-11-17 10:42:05 +02:00
Miro Hrončok
223e030604 XFAIL TestLocalPath.test_make_numbered_dir_multiprocess_safe (#11611)
The tested py.path.local.make_numbered_dir function is *not*
multiprocess safe, because is uses os.listdir which itself is not.

The os.listdir documentation explicitly states that:

> If a file is removed from or added to the directory during the call
> of this function, whether a name for that file be included is unspecified.

This can lead to a race when:

 1. process A attempts to create directory N
 2. the creation fails, as another process already created it in the meantime
 3. process A calls listdir to determine a more recent maxnum
 4. processes B+ repeatedly create newer directories and they delete directory N
 5. process A doesn't have directory N or any newer directory in listdir result
 6. process A attempts to create directory N again and raises

For details, see https://github.com/pytest-dev/pytest/issues/11603#issuecomment-1805708144
and bellow.

Additionally, the test itself has a race in batch_make_numbered_dirs.
When this functions attempts to write to repro-N/foo,
repro-N may have already been removed by another process.

For details, see https://github.com/pytest-dev/pytest/issues/11603#issuecomment-1804714313
and bellow.

---

The tested py.path.local.make_numbered_dir function is not used in pytest.
There is a different implementation in _pytest.pathlib.

Closes #11603
2023-11-14 11:41:35 -03:00
Bruno Oliveira
1eca302c4d Merge pull request #11613 from pytest-dev/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-11-14 07:50:59 -03:00
Bruno Oliveira
970d11cf34 Explicitly export error and path from py
Required by mypy 1.7.0
2023-11-14 07:29:40 -03:00
pre-commit-ci[bot]
d4c56c72d8 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/psf/black: 23.10.1 → 23.11.0](https://github.com/psf/black/compare/23.10.1...23.11.0)
- [github.com/pre-commit/mirrors-mypy: v1.6.1 → v1.7.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.6.1...v1.7.0)
2023-11-13 21:00:52 +00:00
dependabot[bot]
442b09ed9f build(deps): Bump pytest-django in /testing/plugins_integration (#11609)
Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.6.0...v4.7.0)

---
updated-dependencies:
- dependency-name: pytest-django
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-13 09:29:21 +01:00
dependabot[bot]
9417aeb2d8 build(deps): Bump pytest-html in /testing/plugins_integration (#11608)
Bumps [pytest-html](https://github.com/pytest-dev/pytest-html) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/pytest-dev/pytest-html/releases)
- [Changelog](https://github.com/pytest-dev/pytest-html/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-html/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: pytest-html
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-13 09:28:54 +01:00
github-actions[bot]
99f7738810 [automated] Update plugin list (#11607)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-11-12 10:41:08 -03:00
Sharad Nair
7c7bdf4574 Sanitize ini-options default handling #11282 (#11594)
Fixes #11282
2023-11-11 13:08:18 -03:00
Ran Benita
6fe43912be Merge pull request #11591 from pytest-dev/dependabot/pip/testing/plugins_integration/twisted-23.10.0
build(deps): Bump twisted from 23.8.0 to 23.10.0 in /testing/plugins_integration
2023-11-08 09:29:18 +02:00
github-actions[bot]
e701df5eb6 [automated] Update plugin list (#11587)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-11-06 18:40:44 -03:00
dependabot[bot]
92cd7950e6 build(deps): Bump pytest-django in /testing/plugins_integration (#11592)
Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.5.2 to 4.6.0.
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.5.2...v4.6.0)

---
updated-dependencies:
- dependency-name: pytest-django
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-06 09:26:10 +01:00
dependabot[bot]
ef2216c21b build(deps): Bump hynek/build-and-inspect-python-package (#11589)
Bumps [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) from 1.5.3 to 1.5.4.
- [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases)
- [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v1.5.3...v1.5.4)

---
updated-dependencies:
- dependency-name: hynek/build-and-inspect-python-package
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-06 07:50:49 +01:00
dependabot[bot]
01a248d2a9 build(deps): Bump pytest-html in /testing/plugins_integration (#11590)
Bumps [pytest-html](https://github.com/pytest-dev/pytest-html) from 4.0.2 to 4.1.0.
- [Release notes](https://github.com/pytest-dev/pytest-html/releases)
- [Changelog](https://github.com/pytest-dev/pytest-html/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-html/compare/4.0.2...4.1.0)

---
updated-dependencies:
- dependency-name: pytest-html
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-06 07:49:53 +01:00
dependabot[bot]
1a7641cf88 build(deps): Bump twisted in /testing/plugins_integration
Bumps [twisted](https://github.com/twisted/twisted) from 23.8.0 to 23.10.0.
- [Release notes](https://github.com/twisted/twisted/releases)
- [Changelog](https://github.com/twisted/twisted/blob/trunk/NEWS.rst)
- [Commits](https://github.com/twisted/twisted/compare/twisted-23.8.0...twisted-23.10.0)

---
updated-dependencies:
- dependency-name: twisted
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:58:57 +00:00
Bruno Oliveira
70f03dbc3e Adjustments to assert raises docs (#11586)
Followup from #11578.
2023-11-04 12:37:47 -03:00
Bruno Oliveira
1e02797d15 Improve pytest.raises docs (#11578) 2023-11-04 10:24:57 +00:00
neilmartin2000
13e5ef0102 Created link to PEP-8 in documentation (#11582) 2023-11-03 15:05:05 -03:00
dependabot[bot]
1ea10c20df build(deps): Bump django in /testing/plugins_integration (#11579)
Bumps [django](https://github.com/django/django) from 4.2.6 to 4.2.7.
- [Commits](https://github.com/django/django/compare/4.2.6...4.2.7)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-03 08:27:47 -03:00
Ran Benita
8fb7e8b31e Merge pull request #11567 from bluetech/fix-ref-tocdepth
doc/reference: fix sidebar TOC depth
2023-10-30 09:01:54 +02:00
Ran Benita
0d74a1c8a0 doc: allow Sphinx 6.x and 7.x (#11568)
They seem to work fine, let's allow them.
2023-10-29 23:00:27 +01:00
Ran Benita
730c7ca0b1 Merge pull request #11566 from pytest-dev/update-plugin-list/patch-738ae2da9
[automated] Update plugin list
2023-10-29 22:48:26 +02:00
Ran Benita
4ecf313604 doc/reference: fix sidebar TOC depth
Previously, the sidebar TOC had unlimited depth, making it useless and
interfering with the content. This seems to have regressed in pytest
7.2.x going by the RTD version selector.
2023-10-29 21:55:17 +02:00
pytest bot
d0a09d8627 [automated] Update plugin list 2023-10-29 00:19:06 +00:00
Zac Hatfield-Dodds
738ae2da9d Merge pull request #11564 from nicoddemus/empty-string-parametrize-11563
Fix crash using empty string for parametrized value more than once
2023-10-27 16:51:31 -04:00
Bruno Oliveira
7156a97f9a Fix crash using empty string for parametrized value more than once
Fixes #11563.
2023-10-27 17:26:12 -03:00
Ziad Kermadi
ed8701a57f Mention -q and -s in the docs (#11558)
Fixes #11507.
2023-10-27 14:35:45 -03:00
Bruno Oliveira
247436819a Update build-and-inspect-python-package action (#11561)
This should fix the action for Python 3.12.

Ref: hynek/build-and-inspect-python-package#72
2023-10-27 08:32:02 -03:00
Bruno Oliveira
c1728948ac Fix tag name generated by deploy workflow (#11550)
Traditionally pytest publishes tags in the form `X.Y.Z`, however the deploy workflow (copied from somewhere else) published tags in the form `vX.Y.Z`.

This is the root cause of #11548, because it tried to publish the release notes for tag `X.Y.Z` (which did not exist).

Fix #11548
2023-10-25 13:19:47 -03:00
Bruno Oliveira
dcd8b145d9 Add deploy instructions using the command-line (#11547)
Tested this to trigger the deploy of #11546.
2023-10-25 10:04:06 -03:00
Bruno Oliveira
c7e9b22f37 Merge pull request #11546 from pytest-dev/release-7.4.3 (#11549)
Prepare release 7.4.3

(cherry picked from commit 53df6164b4)
2023-10-24 16:50:13 -03:00
Benjamin Schubert
fbe3e29a55 Color the full diff that pytest shows as a diff (#11530)
Related to #11520
2023-10-24 08:42:21 -03:00
pre-commit-ci[bot]
667b9fd7fd [pre-commit.ci] pre-commit autoupdate (#11543)
updates:
- [github.com/psf/black: 23.9.1 → 23.10.1](https://github.com/psf/black/compare/23.9.1...23.10.1)
- [github.com/pre-commit/mirrors-mypy: v1.6.0 → v1.6.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.6.0...v1.6.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-10-24 03:42:43 +02:00
Carsten Grohmann
38f7c1e346 Use pytestconfig instead of request.config in cache example (#11542)
to be consistent with the API documentation.
2023-10-23 15:45:16 -03:00
Bruno Oliveira
bcd9664370 Merge pull request #11531 from nicoddemus/ensure-logging-cleanup
Ensure logging tests always cleanup after themselves
2023-10-23 10:55:18 -03:00
Bruno Oliveira
7e69ce7449 Add full type annotations to logging/test_fixture.py 2023-10-23 10:46:55 -03:00
Bruno Oliveira
395bbae8a2 Ensure logging tests always cleanup after themselves
Logging has many global states, and we did foresee this by creating a ``cleanup_disabled_logging`` fixture,
however one might still forget to use it and failures leak later -- sometimes not even in the same PR, because the order
of the tests might change in the future, specially when running under xdist.

This problem surfaced during pytest-dev/pytest#11530, where tests unrelated to the change started to fail.
2023-10-23 10:46:55 -03:00
Bruno Oliveira
ee53433542 Configure ReadTheDocs to fail on warnings (#11535)
* Configure ReadTheDocs to fail on warnings

Important to catch broken links and references.

* Remove dead link to distutils configuration docs
2023-10-23 09:56:33 -03:00
dependabot[bot]
304ab8495e build(deps): Bump pytest-mock in /testing/plugins_integration (#11539)
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.11.1 to 3.12.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.11.1...v3.12.0)

---
updated-dependencies:
- dependency-name: pytest-mock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-23 09:01:08 -03:00
pre-commit-ci[bot]
40e9abd66b [pre-commit.ci] pre-commit autoupdate (#11510)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/pre-commit/mirrors-mypy: v1.5.1 → v1.6.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.1...v1.6.0)

* Ignore two typing errors after updating to mypy 1.6.0

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2023-10-23 08:05:40 -03:00
github-actions[bot]
cac1eed0ea [automated] Update plugin list (#11534)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-10-21 23:43:14 -03:00
dependabot[bot]
cdddd6d695 build(deps): Bump pytest-bdd in /testing/plugins_integration (#11506)
Bumps [pytest-bdd](https://github.com/pytest-dev/pytest-bdd) from 6.1.1 to 7.0.0.
- [Release notes](https://github.com/pytest-dev/pytest-bdd/releases)
- [Changelog](https://github.com/pytest-dev/pytest-bdd/blob/master/CHANGES.rst)
- [Commits](https://github.com/pytest-dev/pytest-bdd/compare/6.1.1...7.0.0)

---
updated-dependencies:
- dependency-name: pytest-bdd
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-16 08:08:50 -03:00
github-actions[bot]
dd68f9c95a [automated] Update plugin list (#11504)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-10-15 10:03:38 -03:00
ryanpudd
3ab70cd561 Use hyphenated cmdline options in docs (#11490)
Fix #11091
2023-10-10 21:16:24 +00:00
dependabot[bot]
23825f2983 build(deps): Bump django in /testing/plugins_integration (#11491)
Bumps [django](https://github.com/django/django) from 4.2.5 to 4.2.6.
- [Commits](https://github.com/django/django/compare/4.2.5...4.2.6)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-10 17:50:54 -03:00
pre-commit-ci[bot]
fb3a46dd8a [pre-commit.ci] pre-commit autoupdate (#11492)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0)
- [github.com/asottile/pyupgrade: v3.14.0 → v3.15.0](https://github.com/asottile/pyupgrade/compare/v3.14.0...v3.15.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-10-10 06:33:25 +02:00
Zac Hatfield-Dodds
3d6d93d0c2 Merge pull request #11486 from pytest-dev/RonnyPfannschmidt-contributing-tags 2023-10-09 11:29:49 -07:00
github-actions[bot]
2401d76655 [automated] Update plugin list (#11487)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-10-09 08:32:49 -03:00
Tanya Agarwal
af9b1dcc24 Duplicated parameters in parametrize marker (#11489)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
2023-10-08 10:26:31 -07:00
Ronny Pfannschmidt
696859fc43 Update CONTRIBUTING.rst
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-10-07 16:16:18 +02:00
Ronny Pfannschmidt
e966dcd93c Update CONTRIBUTING.rst to mention tag fetches
closes #11485
2023-10-07 15:54:45 +02:00
pre-commit-ci[bot]
54623f0f33 [pre-commit.ci] pre-commit autoupdate (#11478)
updates:
- [github.com/asottile/reorder-python-imports: v3.11.0 → v3.12.0](https://github.com/asottile/reorder-python-imports/compare/v3.11.0...v3.12.0)
- [github.com/asottile/pyupgrade: v3.13.0 → v3.14.0](https://github.com/asottile/pyupgrade/compare/v3.13.0...v3.14.0)
- [github.com/asottile/setup-cfg-fmt: v2.4.0 → v2.5.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.4.0...v2.5.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-10-03 11:47:19 +00:00
Reagan Lee
9bbfe995ee Add more comprehensive set assertion rewrites (#11469)
Fixes #10617
2023-10-02 18:37:52 -03:00
github-actions[bot]
d015bc1b8f [automated] Update plugin list (#11472)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-10-02 08:39:53 -03:00
pre-commit-ci[bot]
b73b4c464c [pre-commit.ci] pre-commit autoupdate (#11468)
updates:
- [github.com/asottile/pyupgrade: v3.11.0 → v3.13.0](https://github.com/asottile/pyupgrade/compare/v3.11.0...v3.13.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-26 09:31:39 +00:00
Ran Benita
1a16bac131 Merge pull request #11315 from bluetech/pytest-monkeypatch-chdir
pytester: use `monkeypatch.chdir()` for dir changing
2023-09-25 12:10:14 +03:00
Ran Benita
81192ca85f pytester: use monkeypatch.chdir() for dir changing
The current method as the following problem, described by Sadra
Barikbin:

The tests that request both `pytester` and `monkeypatch` and use
`monkeypatch.chdir` without context, relying on `monkeypatch`'s teardown
to restore cwd. This doesn't work because the following sequence of
actions take place:

- `monkeypatch` is set up.
- `pytester` is set up. It saves the original cwd and changes it to a
  new one dedicated to the test function.
- Test function calls `monkeypatch.chdir()` without context.
  `monkeypatch` saves cwd, which is not the original one, before
  changing it.
- `pytester` is torn down. It restores the cwd to the original one.
- `monkeypatch` is torn down. It restores cwd to what it has saved.

The solution here is to have pytester use `monkeypatch.chdir()` itself,
then everything is handled correctly.
2023-09-25 11:31:09 +03:00
Ran Benita
486a9ed057 Merge pull request #11464 from pytest-dev/update-plugin-list/patch-d2b214220
[automated] Update plugin list
2023-09-24 16:03:45 +03:00
Ran Benita
4ae102c003 Merge pull request #11446 from bluetech/pluggy-typing
Improve pluggy-related typing
2023-09-24 15:42:58 +03:00
pytest bot
c614590ec9 [automated] Update plugin list 2023-09-24 00:18:30 +00:00
Warren Markham
d2b214220f Add class docstring to NodeMeta (#11427) 2023-09-20 09:08:07 -03:00
Simon Blanchard
a38ad254ef Handle ValueError raised during faulthandler teardown code (#11453)
Fixes #11439
2023-09-20 09:06:43 -03:00
pre-commit-ci[bot]
9f22d3281c [pre-commit.ci] pre-commit autoupdate (#11451)
updates:
- [github.com/asottile/reorder-python-imports: v3.10.0 → v3.11.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.11.0)
- [github.com/asottile/pyupgrade: v3.10.1 → v3.11.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.11.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-19 11:51:41 +02:00
Sharad Nair
9a58e6283d Fixes issue #11314 - log_file_format does not default to log_format (#11444)
* Fixes issue #11314 -

* Incorporated review comments for issue #11314

* Update changelog/11314.improvement.rst

Co-authored-by: Bruno Oliveira <bruno@soliv.dev>

---------

Co-authored-by: Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
2023-09-18 16:50:04 +00:00
github-actions[bot]
8bac8d7807 [automated] Update plugin list (#11443)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-09-18 13:20:47 -03:00
dependabot[bot]
5e081162df build(deps): Bump pytest-html in /testing/plugins_integration (#11449)
Bumps [pytest-html](https://github.com/pytest-dev/pytest-html) from 4.0.1 to 4.0.2.
- [Release notes](https://github.com/pytest-dev/pytest-html/releases)
- [Changelog](https://github.com/pytest-dev/pytest-html/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-html/compare/4.0.1...4.0.2)

---
updated-dependencies:
- dependency-name: pytest-html
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 11:10:48 -03:00
Chris Mahoney
8062743f6b Change deprecated_call to handle FutureWarning (#11448)
Fixes #11447
2023-09-18 09:34:05 -03:00
Zac Hatfield-Dodds
8b7f94f145 Merge pull request #11424 from lanzz/exceptioninfo-groupcontains 2023-09-17 16:51:57 -07:00
Mihail Milushev
5ace48ca5b Fix a minor mistake in docs ("`match method" is actually talking about the match` keyword parameter) 2023-09-17 22:28:32 +01:00
Mihail Milushev
e7caaa0b3e Document the new ExceptionInfo.group_contains() method 2023-09-17 22:28:32 +01:00
Mihail Milushev
a47fcb4873 code review: kwarg-only match, replace recursive with depth 2023-09-17 22:28:32 +01:00
Mihail Milushev
ab8f5ce7f4 Add new ExceptionInfo.group_contains assertion helper method
Tests if a captured exception group contains an expected exception.
Will raise `AssertionError` if the wrapped exception is not an exception group.
Supports recursive search into nested exception groups.
2023-09-17 22:28:32 +01:00
Ran Benita
f43a8db618 Improve pluggy-related typing 2023-09-17 21:32:55 +03:00
pomponchik
6c2feb75d2 Add flask_fixture to the manual plugin list
Fixes #11435
2023-09-12 19:17:20 -03:00
pre-commit-ci[bot]
fcb8e73288 [pre-commit.ci] pre-commit autoupdate (#11434)
updates:
- [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-12 08:37:19 -03:00
Bruno Oliveira
241f2a890e Force terminal width when running tests (#11425)
Related to #11423
2023-09-11 09:22:56 -03:00
dependabot[bot]
39f9306357 build(deps): Bump pytest-html in /testing/plugins_integration (#11431)
Bumps [pytest-html](https://github.com/pytest-dev/pytest-html) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/pytest-dev/pytest-html/releases)
- [Changelog](https://github.com/pytest-dev/pytest-html/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-html/compare/4.0.0...4.0.1)

---
updated-dependencies:
- dependency-name: pytest-html
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-11 06:50:46 -03:00
dependabot[bot]
e0d04bdfab build(deps): Bump django in /testing/plugins_integration (#11430)
Bumps [django](https://github.com/django/django) from 4.2.4 to 4.2.5.
- [Commits](https://github.com/django/django/compare/4.2.4...4.2.5)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-11 06:50:32 -03:00
dependabot[bot]
1949b09fd3 build(deps): Bump actions/checkout from 3 to 4 (#11429)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-11 06:50:08 -03:00
Ran Benita
3d1c52f203 Merge pull request #11428 from ShurikMen/fix_tests_signature
Fix invalid signature in TestSorting tests
2023-09-11 10:30:45 +03:00
Aleksandr Brodin
a60c23c3d8 fix invalid signature 2023-09-11 09:59:00 +07:00
github-actions[bot]
24a6ee1ffd [automated] Update plugin list (#11422)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-09-10 13:09:41 +00:00
Bruno Oliveira
e2acc1a99b Fix --import-mode=importlib when root contains __init__.py file (#11420)
We cannot have an empty module name when importing a `__init__.py` file that
is at the rootdir.

Fixes #11417
2023-09-10 09:57:40 -03:00
Warren Markham
71f265f1f3 Refactor: use division operator to join paths (#11413)
Starting with `resolve_package_path` and its associated tests,
this refactoring seeks to make path concatenation more
readable and consistent within tests/functions.

As discussed in #11413:

- code is free to use either `/` and `joinpath`
- consistency within a function is more important than consistency across the codebase
- it is nice to use `/` when it is more readable
- it is nice to use `joinpath` when there is little context
- be mindful that `joinpath` may be clearer when joining multiple segments
2023-09-09 09:16:22 -03:00
Marc Mueller
7259e8db98 Fix assert rewriting with assignment expressions (#11414)
Fixes #11239
2023-09-09 09:09:31 -03:00
Ronny Pfannschmidt
dd7beb39d6 Merge pull request #11416 from bluetech/fixtures-getfixtureclosure
fixtures: more tweaks
2023-09-08 19:48:34 +02:00
Ran Benita
6ad9499c9c doctest: some missing type annotations 2023-09-08 15:59:17 +03:00
Ran Benita
2ed2e9208d doctest: remove unnecessary Optionals 2023-09-08 15:59:17 +03:00
Ran Benita
ab63ebb3dc doctest: inline _setup_fixtures, make more similar to Function
There used to be two callers to `_setup_fixtures()`, now there's only
one, so inline it and make `DoctestItem` more similar to `Function`.

(Eventually we may want to generalize `TopRequest` from taking
`Function` directly to some "fixture-supporting item", removing the
remaining `type: ignore` here and allowing plugins to do it in a stable
manner).
2023-09-08 15:59:17 +03:00
Ran Benita
b3a981d385 fixtures: remove getfixtureinfo(funcargs) in favor of None func
Since we already broke plugins using this (private) interface in this
version (pytest-play, pytest-wdl), might as well do a cleanup.
2023-09-08 15:59:17 +03:00
Sadra Barikbin
48b0395648 fixtures: clean up getfixtureclosure()
Some code cleanups - no functional changes.
2023-09-08 15:53:49 +03:00
Ran Benita
9c11275553 fixtures: change getfixtureclosure(ignore_args) to a set
Only used for containment checks so a Set is more appropriate than a
list.
2023-09-08 15:53:49 +03:00
Bruno Oliveira
e5c81fa41a Adjustments to the release process (#11410)
As discussed in #11408:

* Improve documentation for the release process.
* Fix the description for the PRs created by the `prepare release pr` workflow.
* Fix pushing tag in the `deploy` workflow.
2023-09-08 07:22:16 -03:00
Bruno Oliveira
0a06db0729 Merge pull request #11408 from pytest-dev/release-7.4.2 (#11409)
Prepare release 7.4.2

(cherry picked from commit b0c4775a28)
2023-09-07 16:10:19 -03:00
Bruno Oliveira
5936a79fdb Use _pytest.pathlib.safe_exists in get_dirs_from_args (#11407)
Related to #11394
2023-09-07 15:44:47 -03:00
Bruno Oliveira
28ccf476b9 Fix crash when passing a very long cmdline argument (#11404)
Fixes #11394
2023-09-07 12:49:25 -03:00
Fraser Stark
333e4eba6b Change PytestReturnNotNoneWarning to return a normal warning (#11211)
Fixes #10465
2023-09-07 15:11:59 +00:00
Ronny Pfannschmidt
e787d2ed48 Merge pull request #11317 from tjsmart/fix-issue-11237
Fix doctest collection of `functools.cached_property` objects.
2023-09-07 14:39:02 +02:00
Florian Bruhin
f6b6478868 doc: Remove done training (#11399) 2023-09-06 15:22:27 +02:00
Stefaan Lippens
3ce63bc768 Improve plugin list disclaimer (#11397)
Closes #11391
2023-09-06 07:34:38 -03:00
Ran Benita
faa8f2ea08 Merge pull request #11393 from pytest-dev/fixtures-tweaks
Fixtures tweaks
2023-09-06 09:15:28 +03:00
Bruno Oliveira
194a782e38 Fix import_path for packages (#11390)
For packages, `import_path` receives the path to the package's `__init__.py` file, however module names (as they live in `sys.modules`) should not include the `__init__` part.

For example, `app/core/__init__.py` should be imported as `app.core`, not as `app.core.__init__`.

Fix #11306
2023-09-05 19:42:40 -03:00
Ran Benita
bc71561ad9 python: avoid an Any 2023-09-05 22:32:46 +03:00
Ran Benita
574e0f45d9 fixtures: avoid using the mildly expensive fixturenames property
Avoid creating a list copy + 2 sets + a linear search through the list
(in the common case).
2023-09-05 22:15:37 +03:00
Ran Benita
b8906b29a7 fixtures: require item.fixturenames to exist in _fillfixtures
I could find 2 plugins that would be broken by this (pytest-play and
pytest-wdl), but they will be better served by just copying
`_fillfixtures` instead of use the private function.
2023-09-05 22:15:37 +03:00
Ran Benita
d2b5177dd6 fixtures: avoid some redundant work in _fillfixtures 2023-09-05 22:15:37 +03:00
Ran Benita
65c01f531b fixtures: use the item fixturenames in request.fixturenames
`_pyfuncitem.fixturenames` is just an alias for
`_pyfuncitem._fixtureinfo.names_closure` (at least in core pytest), so
let's do the less abstraction-breaking thing.
2023-09-05 22:15:37 +03:00
Ran Benita
82bd63d318 doctest: add fixturenames field to DoctestItem
The field is used in `_fillfixtures`, in preference to
`request.fixturenames`, which also includes already-computed which is
not needed.
2023-09-05 22:15:37 +03:00
Ran Benita
d4872f5df7 fixtures: tiny code cleanup 2023-09-05 22:15:37 +03:00
Ran Benita
8d815ca55b python: type some CallSpec2 fields as immutable
Knowing that a field is immutable makes it easier to understand the
code.
2023-09-05 22:15:37 +03:00
pre-commit-ci[bot]
8032d21271 [pre-commit.ci] pre-commit autoupdate (#11389)
updates:
- [github.com/PyCQA/autoflake: v2.2.0 → v2.2.1](https://github.com/PyCQA/autoflake/compare/v2.2.0...v2.2.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-05 10:09:33 -03:00
dependabot[bot]
9c8937b480 build(deps): Bump pytest-html in /testing/plugins_integration (#11384)
Bumps [pytest-html](https://github.com/pytest-dev/pytest-html) from 3.2.0 to 4.0.0.
- [Release notes](https://github.com/pytest-dev/pytest-html/releases)
- [Changelog](https://github.com/pytest-dev/pytest-html/blob/master/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-html/compare/v3.2.0...4.0.0)

---
updated-dependencies:
- dependency-name: pytest-html
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-04 08:08:10 -03:00
dependabot[bot]
0d8b87f161 build(deps): Bump anyio[curio,trio] in /testing/plugins_integration (#11383)
Bumps [anyio[curio,trio]](https://github.com/agronholm/anyio) from 3.7.1 to 4.0.0.
- [Release notes](https://github.com/agronholm/anyio/releases)
- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/anyio/compare/3.7.1...4.0.0)

---
updated-dependencies:
- dependency-name: anyio[curio,trio]
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-04 08:08:01 -03:00
dependabot[bot]
65c73a09e7 build(deps): Bump twisted in /testing/plugins_integration (#11385)
Bumps [twisted](https://github.com/twisted/twisted) from 22.8.0 to 23.8.0.
- [Release notes](https://github.com/twisted/twisted/releases)
- [Changelog](https://github.com/twisted/twisted/blob/trunk/NEWS.rst)
- [Commits](https://github.com/twisted/twisted/compare/twisted-22.8.0...twisted-23.8.0)

---
updated-dependencies:
- dependency-name: twisted
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-04 08:07:56 -03:00
Israel Fruchter
917ce9aa01 Fix user_properties not saved to XML if fixture errors during teardown
Move handling of user_properties to `finalize()`.

Previously if a fixture failed during teardown, `pytest_runtest_logreport` would not be called with "teardown", resulting in the user properties not being saved on the JUnit XML file.

Fixes: #11367
2023-09-03 14:33:54 -03:00
github-actions[bot]
4e3a0874df [automated] Update plugin list (#11380)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-09-02 22:13:17 -03:00
Bruno Oliveira
ba0da81f88 Merge pull request #11379 from nicoddemus/cherry-pick-release
Merge pull request #11377 from pytest-dev/release-7.4.1
2023-09-02 13:21:07 -03:00
Bruno Oliveira
f08782d8d0 Merge pull request #11377 from pytest-dev/release-7.4.1
Prepare release 7.4.1

(cherry picked from commit 82eb86f707)
2023-09-02 12:45:58 -03:00
dependabot[bot]
5b528bd131 build(deps): Bump pypa/gh-action-pypi-publish from 1.8.8 to 1.8.10 (#11310)
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.8 to 1.8.10.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.8...v1.8.10)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-02 12:04:30 -03:00
Bruno Oliveira
e4794b26b2 Merge pull request #11378 from nicoddemus/improve-ci-workflow
Improve CI workflow
2023-09-02 11:59:25 -03:00
Bruno Oliveira
ab6cae2126 Improve CI workflow
* Build the package only once, and test on all platforms.
* Deploy is now triggered manually via an Action, which is then responsible for tagging the repository after the package has been uploaded successfully.
* Drop 'docs': we nowadays rely on readthedocs preview PR builds.
2023-09-02 10:29:02 -03:00
Sourabh Beniwal
afb8d66e42 Update CONTRIBUTING.rst (#11368)
Chnaged Status: easy to good first issue, and updated the URL
2023-08-30 11:52:14 +00:00
Sean Patrick Malloy
76ba7db6ce Improve docs for last-failed-no-failures
Improve documentation for last-failed-no-failures to make the different options and the functionality more clear.

Closes #11354
2023-08-29 00:14:45 +00:00
Ran Benita
941b203c94 Merge pull request #11360 from seanjedi/issue_11356-fixing-precommit-issue-with-flake8
fix: fixing an issue with pre-commit with mypy and flake8
2023-08-28 11:26:37 +03:00
Sean Malloy
19d6b12b2a fix: fixing an issue with pre-commit with mypy and flake8 2023-08-27 15:03:42 -07:00
github-actions[bot]
17e8f2b3fc [automated] Update plugin list (#11358)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-08-27 11:29:17 -03:00
Warren Markham
ff23347f1f Fix platform-dependent type-check errors (#11345)
Use more explicit `sys.platform` checks, instead of the previous check using `in`, which mypy understands.

Fixes #11343
2023-08-27 09:40:24 -03:00
Ran Benita
00fedcc439 Merge pull request #11353 from bluetech/pluggy-typing
Fixes for typed pluggy
2023-08-26 22:59:35 +03:00
Ran Benita
77f7f59b2a Fixes for typed pluggy
Since version 1.3 pluggy added typing, which requires some fixes to
please mypy.
2023-08-26 22:13:24 +03:00
Jon Parise
7500fe44b2 Correct the spelling of ArgSource.INVOCATION_DIR (#11333)
Config.ArgsSource.INCOVATION_DIR remains as a backwards compatibility
alias.
2023-08-23 09:21:17 +00:00
Ha Pam
23b899f31f Fix a typo in anatomy.rst (#11341) 2023-08-23 10:17:09 +02:00
Ran Benita
43d1398fc7 Merge pull request #11334 from WarrenTheRabbit/fix-docstring-spelling-in-pytester-1
doc: fix docstring spelling in pytester
2023-08-22 14:44:06 +03:00
Zac Hatfield-Dodds
03832fa31e Merge pull request #11326 from DetachHead/DetachHead-patch-1
use `if not TYPE_CHECKING` on `pytest.__getattr__` to prevent type checkers from using it
2023-08-22 03:53:46 -07:00
pre-commit-ci[bot]
8f36fd5454 [pre-commit.ci] pre-commit autoupdate (#11335)
updates:
- [github.com/asottile/blacken-docs: 1.15.0 → 1.16.0](https://github.com/asottile/blacken-docs/compare/1.15.0...1.16.0)
- [github.com/pre-commit/mirrors-mypy: v1.5.0 → v1.5.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.0...v1.5.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-08-22 08:10:48 +00:00
DetachHead
cada6c105a ignore mypy error on deprecated Instance usage 2023-08-22 17:57:59 +10:00
WarrenTheRabbit
3f446b68fd doc: fix docstring spelling in pytester 2023-08-22 14:36:39 +10:00
Zac Hatfield-Dodds
050f402816 Merge pull request #11308 from reaganjlee/iter-reporting
Improve reporting from __iter__ exceptions
2023-08-21 16:27:42 -07:00
Reagan Lee
d1722d5c18 fix test for codecov 2023-08-21 15:49:39 -07:00
github-actions[bot]
4deb38b2ed [automated] Update plugin list (#11329)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-08-21 13:19:58 +00:00
Ran Benita
370eacd3ca doc/reference: replace Unicode dashes with ascii - in cli flags (#11323) 2023-08-21 14:40:03 +02:00
DetachHead
010e1742d8 use python 3.11 for update-plugin-list (#11328) 2023-08-21 12:29:41 +00:00
Ran Benita
6e5f10b28f Merge pull request #11320 from ubaumann/add_nuts
add nuts to plugin list
2023-08-21 14:50:31 +03:00
pre-commit-ci[bot]
dd5ae0c3b8 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-08-21 08:03:06 +00:00
DetachHead
fc653d0d12 use if not TYPE_CHECKING on pytest.__getattr__ to prevent type checkers from using it 2023-08-21 18:00:28 +10:00
Tyler Smart
a357c7abc8 Ignore dip in branch coverage (since py3.13+ isn't tested in CI) 2023-08-20 20:55:30 -06:00
Reagan Lee
61133ba83d un-iterable fix 2023-08-20 14:46:09 -07:00
Reagan Lee
049eec8474 Revert iter raises checks
This reverts commit e938580257.

Revert "improve error msg and test"

This reverts commit c0cf822ca1.

Revert "error msg"

This reverts commit ec1053cc16.

Revert "changelog"

This reverts commit d2dc8a70b5.

Revert "simplify code / take out user-gen typeerror case"

This reverts commit b9cb87d862.
2023-08-20 14:06:42 -07:00
Ran Benita
37bb186175 Merge pull request #11322 from bluetech/testing-norecursedirs
testing: add `.*` to `norecursedirs`
2023-08-20 16:37:16 +03:00
Ran Benita
3cb3cd1a08 testing: add .* to norecursedirs
Setting `norecursedirs` overrides the default, so we end up scanning
dot-directories and such which slows down collection unnecessarily
(150ms on my working directory).
2023-08-20 12:16:38 +03:00
Tyler Smart
7a625481da PR suggestions 2023-08-19 22:20:40 -06:00
Ran Benita
0ddfdfcc04 Merge pull request #11321 from tjsmart/fix-doctesting
Add doctesting-coverage to envlist
2023-08-20 00:26:42 +03:00
Tyler Smart
87bfc83aa0 Add doctesting-coverage to envlist 2023-08-19 12:18:17 -06:00
Tyler Smart
ebd571bb18 Move _from_module override to pre-existsing DocTestFinder subclass 2023-08-19 12:04:59 -06:00
ubaumann
176d728b7b add nuts to plugin list
Adding https://github.com/network-unit-testing-system/nuts to the plugin list.
2023-08-18 23:34:40 +02:00
Tyler Smart
d4fb6ac9f7 Fix doctest collection of functools.cached_property objects. 2023-08-16 00:55:16 -06:00
Ran Benita
15fadd8c5c Merge pull request #11219 from bluetech/fixtures2
fixtures: make FixtureRequest abstract, add TopRequest subclass
2023-08-15 21:52:46 +03:00
pre-commit-ci[bot]
73d754bd74 [pre-commit.ci] pre-commit autoupdate (#11313)
updates:
- [github.com/pre-commit/mirrors-mypy: v1.4.1 → v1.5.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.4.1...v1.5.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-08-15 07:56:42 +00:00
Ran Benita
10056865d2 Merge pull request #11309 from bluetech/docs-xfail
doc: fix a few `xfail` nits
2023-08-12 18:58:37 +03:00
Ran Benita
1827d8d5f9 doc: fix a few pytest.mark.xfail nits
Refs #9027, #10094.
2023-08-12 18:30:58 +03:00
Ran Benita
9e164fc4fe fixtures: make FixtureRequest abstract, add TopRequest subclass
Fix #11218.
2023-08-12 11:55:08 +03:00
Reagan Lee
c0cf822ca1 improve error msg and test 2023-08-11 10:33:34 -07:00
Reagan Lee
ec1053cc16 error msg 2023-08-11 10:03:19 -07:00
Reagan Lee
d2dc8a70b5 changelog 2023-08-11 09:48:53 -07:00
Reagan Lee
b9cb87d862 simplify code / take out user-gen typeerror case 2023-08-10 17:43:01 -07:00
Reagan Lee
e938580257 check for user-generated exceptions 2023-08-10 17:37:48 -07:00
Reagan Lee
47c0fc3d78 tests 2023-08-10 16:36:22 -07:00
Ran Benita
556e075d23 Merge pull request #11301 from bluetech/fixtures-resolve-directness
python: use clearer terminology for `_resolve_arg_value_types`
2023-08-10 09:05:58 +03:00
Ran Benita
3ad3fc6b8f python: use clearer terminology for _resolve_arg_value_types 2023-08-09 20:36:24 +03:00
Sadra Barikbin
09b78737a5 Move fixtures.py::add_funcarg_pseudo_fixture_def to Metafunc.parametrize (#11220)
To remove fixtures.py::add_funcargs_pseudo_fixture_def and add its logic
i.e. registering funcargs as params and making corresponding fixturedefs,
right to Metafunc.parametrize in which parametrization takes place.

To remove funcargs from metafunc attributes as we populate metafunc
params and make pseudo fixturedefs simultaneously and there's no need to
keep funcargs separately.
2023-08-09 17:13:45 +00:00
Ran Benita
b2186e2455 Merge pull request #11268 from bluetech/conftest-load
config: split `_getconftestmodules` and `_loadconftestmodules`
2023-08-08 14:44:29 +03:00
Bruno Oliveira
18bc6c9a0e Merge pull request #11292 from pytest-dev/dependabot/pip/testing/plugins_integration/django-4.2.4
build(deps): Bump django from 4.2.3 to 4.2.4 in /testing/plugins_integration
2023-08-07 08:15:17 -03:00
Bruno Oliveira
24c9aa6c30 Merge pull request #11291 from calestyo/improve-duplicate-values-documentation
Improve duplicate values documentation
2023-08-07 08:14:39 -03:00
dependabot[bot]
9c67b7aeb6 build(deps): Bump django in /testing/plugins_integration
Bumps [django](https://github.com/django/django) from 4.2.3 to 4.2.4.
- [Commits](https://github.com/django/django/compare/4.2.3...4.2.4)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-07 03:39:31 +00:00
Christoph Anton Mitterer
1cc58ed67f improve exception message on duplicate parametrization
Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-08-06 17:43:37 +02:00
Christoph Anton Mitterer
84a342e27c doc: parametrize() can be called multiple times only on different args
Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-08-06 17:39:31 +02:00
Sadra Barikbin
e8a8a5f320 python: fix scope assignment for indirect parameter sets (#11277)
Previously, when assigning a scope for a fully-indirect parameter set,
when there are multiple fixturedefs for a param (i.e. same-name fixture
chain), the highest scope was used, but it should be the lowest scope,
since that's the effective scope of the fixture.
2023-08-06 13:59:54 +00:00
Florian Bruhin
1c04a92503 doc: Link pytest.main to how-to guide (#11287) 2023-08-06 12:39:11 +02:00
Christoph Anton Mitterer
cc0adf6bf3 doc: update information about assertion messages (#11285)
It was pointed out[0] that the previous behaviour has been obsoleted by
commit 37bd1e03cb.

[0] https://github.com/pytest-dev/pytest/issues/11265#issuecomment-1666581197

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-08-05 19:30:41 +00:00
Christoph Anton Mitterer
b8b74331b4 Improve docs for Parametrizing conditional raising (#11279)
What one typically actually wants in such a case is both, checking for some
resulting values *and* checking for some expected exception.

Since this is easily possible with the `nullcontext` context manager, adapt the
example accordingly (needlessly using a different name rather just confuses people).

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-08-03 13:31:17 -03:00
Sadra Barikbin
4797deab99 Add FixtureArgKey class to represent fixture deps in fixtures.py (#11231) 2023-08-02 14:28:31 +03:00
pre-commit-ci[bot]
c9163402e0 [pre-commit.ci] pre-commit autoupdate (#11269)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/PyCQA/flake8: 6.0.0 → 6.1.0](https://github.com/PyCQA/flake8/compare/6.0.0...6.1.0)
- [github.com/asottile/pyupgrade: v3.9.0 → v3.10.1](https://github.com/asottile/pyupgrade/compare/v3.9.0...v3.10.1)

* Use is instead of type comparison with equal to appease the linter

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
2023-08-01 23:52:09 +02:00
Ran Benita
01ac13a77d config: split _getconftestmodules and _loadconftestmodules
Previously, the `_getconftestmodules` function was used both to load
conftest modules for a path (during `pytest_load_initial_conftests`),
and to retrieve conftest modules for a path (during hook dispatch and
for fetching `collect_ignore`). This made things muddy - it is usually
nicer to have clear separation between "command" and "query" functions,
when they occur in separate phases.

So split into "load" and "get".

Currently, `gethookproxy` still loads conftest itself. I hope to change
this in the future.
2023-08-01 09:46:17 +03:00
Ran Benita
485c555812 Merge pull request #11138 from bluetech/pkg-mod
python: change `Package` to no longer be a `Module`/`File`
2023-07-28 23:15:08 +03:00
Ran Benita
a21fb87a90 python: change Package to no longer be a Module/File
Fix #11137.
2023-07-28 22:49:24 +03:00
Ran Benita
c754da10d2 Merge pull request #11256 from bluetech/scope-pkg-crash
fixtures: fix crash when `parametrize(scope="package")` is used without a Package
2023-07-28 22:48:47 +03:00
Ran Benita
71e627aa8f fixtures: fix crash when parametrize(scope="package") is used without a Package
There as handling for `scope="class"` without a class, but not for
`scope="package"` without a package. It would fail the assert.
2023-07-28 16:13:02 +03:00
Uday Kumar
d3552ef4c0 Clarify doc for running tests by nodeid section (#11249) 2023-07-28 07:06:38 +00:00
Ran Benita
448563caaa Merge pull request #11253 from bluetech/11243-cherry-picks
11243 cherry picks
2023-07-27 10:19:40 +03:00
Sadra Barikbin
e8aa906e06 fixtures: move _get_direct_parametrize_args to a standalone function
So it can be used independently of the FixtureManager.
2023-07-27 09:38:42 +03:00
Sadra Barikbin
12054a4972 config: avoid list[], set[], dict[]
Should wait with this until Python 3.8 is dropped.
2023-07-27 09:33:34 +03:00
Ran Benita
430ad145c1 Merge pull request #11244 from bluetech/rootdir-tweaks
Rootdir tweaks
2023-07-27 09:16:13 +03:00
Ran Benita
13e2b00258 config: don't pass the entire Config to determine_setup()
Seems better to make the function a bit more pure, and avoids the
circular import.
2023-07-24 00:00:34 +03:00
Ran Benita
4e42421ebf config: fix an incorrect type
Was a mistake in d97d44a97a.
2023-07-24 00:00:34 +03:00
Ran Benita
161ba87300 doc/usage: clarify "Run tests by node ids"
Fix #11107, #11235.
2023-07-24 00:00:25 +03:00
Ran Benita
f2b6040e9e Merge pull request #11238 from bluetech/doc-not-indirect
doc/example/parametrize: a few fixes/improvements
2023-07-23 13:07:40 +03:00
Florian Bruhin
e3247834e2 Remove ep2023 training (#11241) 2023-07-22 20:16:59 +02:00
bowugit
0b4a557087 Extend pytest.raises to support Exception having __repr__ method and initialized with kwargs (#11073)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-07-20 13:29:29 -03:00
Bruno Oliveira
ffdcce67f4 Merge pull request #10927 from RonnyPfannschmidt/pypi-json-for-plugin-list
update-plugin-list: use json, use http caching, use gh action caches
2023-07-20 10:42:32 -03:00
Ronny Pfannschmidt
1ded74739b update-plugin-list: use json, use http caching, use gh action caches
this change
* switches from html index usage to json index usage
* adds using requests-cache as http cache to trim down runtime
* adds gh action caches for pip and the new http cache
2023-07-20 15:04:41 +02:00
Ran Benita
497a1d798a doc/example/parametrize: a few fixes/improvements
Remove "Indirect" from a few section names -- not actually indirect.

Also few minor updates to the related multipython.py example.
2023-07-20 09:51:11 +03:00
Isaac Virshup
1de0923e83 Have pytest.raises match against exception __notes__ (#11227)
The doctest is skipped because add_note is only available in 3.11,

Closes #11223
2023-07-18 08:39:39 -03:00
Ronny Pfannschmidt
7c30f674c5 Merge pull request #11228 from bluetech/fixtures-check-scope-test
fixtures: add a test for a currently non-covered scope mismatch scenario
2023-07-18 08:59:55 +02:00
Ran Benita
396bfbf30b fixtures: add a test for a currently non-covered scope mismatch scenario
This test makes clear the need for the `_check_scope()` call in the
`pytest_setup_fixture` impl in fixtures.py, which otherwise seems
redundant with the one in `_compute_fixture_value`.
2023-07-18 00:01:40 +03:00
Ran Benita
02ba39bfcd Merge pull request #11215 from bluetech/fixtures-tweaks2
fixtures: minor tweaks
2023-07-17 17:30:24 +03:00
Ran Benita
29010d23a6 Merge pull request #11217 from bluetech/fixtures-skip-xunit-loc
fixtures: show test as skip location if skipped from an xunit setup function
2023-07-17 17:30:06 +03:00
dependabot[bot]
de1f6f58ba build(deps): Bump pypa/gh-action-pypi-publish from 1.8.7 to 1.8.8 (#11221)
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.7 to 1.8.8.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.7...v1.8.8)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 09:31:06 +02:00
dependabot[bot]
cfda801ebf build(deps): Bump pytest-asyncio in /testing/plugins_integration (#11222)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.21.0 to 0.21.1.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.21.0...v0.21.1)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 09:27:38 +02:00
Ran Benita
c5262b0c42 fixtures: show test as skip location if skipped from an xunit setup function
Fix #11216.
2023-07-16 23:26:04 +03:00
Ran Benita
ff6e110161 fixtures: remove inaccurate comment
unittest TestCases can also use `usefixtures`. Just remove this comment,
it's not very helpful.
2023-07-16 23:19:33 +03:00
Ran Benita
0e0ed2af95 fixtures: some code comments and minor improvements 2023-07-16 23:19:33 +03:00
Ran Benita
a3fbf24389 unittest: hide access to _request
Let the parent class (Function) do this. Tiny bit better abstraction.
There seems to be no reason for the `hasattr` bit.
2023-07-16 23:19:33 +03:00
Ran Benita
bf451d47a1 Merge pull request #11213 from bluetech/py38-literal
Use typing.Literal without TYPE_CHECKING checks
2023-07-16 23:17:12 +03:00
Ran Benita
578fbe3dfd Merge pull request #11214 from pytest-dev/update-plugin-list/patch-32f480814
[automated] Update plugin list
2023-07-16 13:07:40 +03:00
pytest bot
a668719626 [automated] Update plugin list 2023-07-16 00:28:56 +00:00
Ran Benita
04e0db7e48 Use typing.Literal without TYPE_CHECKING checks
Literal was added in Python 3.8 which we now require so can use it
freely.
2023-07-16 01:11:21 +03:00
Ran Benita
32f480814c Merge pull request #11209 from bluetech/fixtures-doc-comments
fixtures: some tweaks & improvements
2023-07-15 19:40:48 +03:00
Ran Benita
40ed678885 fixtures: remove two unused functions
Not used since 310b67b227.
2023-07-15 10:06:06 +03:00
Ran Benita
fb55615d5e Export FixtureDef
FixtureDef is used in the `pytest_fixture_setup` hook so needs to be
public. However since its current internals are quite dubious (and not
all marked with `_` prefix) I've added an explicit note that only
documented fields/methods are considered public.

Refs #7469.
2023-07-15 10:06:06 +03:00
Ran Benita
9d0ddb4625 fixtures: change FixtureDef.cached_result[2] from exception triplet to exception
Fix #11208.
2023-07-15 10:06:06 +03:00
Ran Benita
01f38aca44 fixtures: expand comments and annotations on fixture internals 2023-07-15 10:06:06 +03:00
Ran Benita
78d81ef865 Merge pull request #11123 from bluetech/new-style-wrappers
Switch to new-style pluggy hook wrappers
2023-07-15 10:03:35 +03:00
Ran Benita
b41acaea12 Switch to new-style pluggy hook wrappers
Fix #11122.
2023-07-14 22:47:48 +03:00
pre-commit-ci[bot]
7008385253 [pre-commit.ci] pre-commit autoupdate (#11195)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0)
- [github.com/asottile/blacken-docs: 1.14.0 → 1.15.0](https://github.com/asottile/blacken-docs/compare/1.14.0...1.15.0)
- [github.com/asottile/pyupgrade: v3.8.0 → v3.9.0](https://github.com/asottile/pyupgrade/compare/v3.8.0...v3.9.0)

* Update .pre-commit-config.yaml

* Update .pre-commit-config.yaml

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-07-11 11:37:07 +00:00
Ran Benita
b25a3adff5 Merge pull request #11192 from bluetech/py38-extra
A few more Python>=3.8 simplifications
2023-07-11 01:13:17 +03:00
Ran Benita
ecfab4dc8b fixtures: fix a typing ignore TODO
From understanding the code better I see this is the correct fix.
The fixturedefs can be None if `request.getfixturevalue("doesnotexist")`
is used.

In practice there is no change in behavior because this mapping is used
as `self._arg2fixturedefs.get(argname, None)` which ends up the same.
2023-07-11 00:19:29 +03:00
Ran Benita
2c80de532f fixtures: replace a startswith("conftest.py") with == "conftest.py"
I can't imagine why we would want to test for a prefix here.
2023-07-10 23:27:11 +03:00
Ran Benita
7967b2e710 fixtures: change a lambda to partial
It makes for a more debuggable repr. Before:

    <function FixtureRequest._schedule_finalizers.<locals>.<lambda> at 0x7fe4ae32d440>

After:

    functools.partial(<bound method FixtureDef.finish of <FixtureDef argname='hello_package' scope='package' baseid=''>>, request=<SubRequest 'hello_package' for <Function test_hello>>)
2023-07-10 23:27:11 +03:00
Ran Benita
f1c9570a0e A few more Python>=3.8 simplifications 2023-07-10 23:20:11 +03:00
dependabot[bot]
b20e7f6d0c build(deps): Bump anyio[curio,trio] in /testing/plugins_integration (#11191)
Bumps [anyio[curio,trio]](https://github.com/agronholm/anyio) from 3.7.0 to 3.7.1.
- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/anyio/compare/3.7.0...3.7.1)

---
updated-dependencies:
- dependency-name: anyio[curio,trio]
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:23:47 -03:00
dependabot[bot]
b91d5a3112 build(deps): Bump pytest-rerunfailures in /testing/plugins_integration (#11190)
Bumps [pytest-rerunfailures](https://github.com/pytest-dev/pytest-rerunfailures) from 11.1.2 to 12.0.
- [Changelog](https://github.com/pytest-dev/pytest-rerunfailures/blob/master/CHANGES.rst)
- [Commits](https://github.com/pytest-dev/pytest-rerunfailures/compare/11.1.2...12.0)

---
updated-dependencies:
- dependency-name: pytest-rerunfailures
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:23:33 -03:00
dependabot[bot]
4e75bff71a build(deps): Bump pypa/gh-action-pypi-publish from 1.8.5 to 1.8.7 (#11189)
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.5 to 1.8.7.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.5...v1.8.7)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:23:12 -03:00
antosikv
99ab8ae884 Clarify docs for pytest.main default behavior (#11187)
Add explicit mentions of the default behavior to both API reference and
how-to section about ways to invoke pytest.

Co-authored-by: Ran Benita <ran@unusedvar.com>
2023-07-09 12:30:33 -03:00
Ran Benita
782cacf86b Merge pull request #11184 from pytest-dev/update-plugin-list/patch-fd7a4d242
[automated] Update plugin list
2023-07-09 17:09:12 +03:00
pytest bot
a3b4220d76 [automated] Update plugin list 2023-07-09 00:29:15 +00:00
Bruno Oliveira
fd7a4d2429 Merge pull request #11106 from bluetech/docs-ref-collection-objs
reference: improve the node types docs a bit
2023-07-08 15:41:22 -03:00
Ran Benita
b73ec8e5d1 doc: fix EncodingWarnings in examples (#11158)
Otherwise the warnings show in the regen output.
2023-07-08 15:40:05 -03:00
Zac Hatfield-Dodds
d790e96765 Merge pull request #11178 from kenny-y-dev/add-none-support-approxmapping 2023-07-08 10:40:42 -07:00
Kenny Y
d4265448a5 Update src/_pytest/python_api.py
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-07-08 08:41:42 -04:00
Kenny Y
db37e34613 Merge branch 'main' into add-none-support-approxmapping 2023-07-07 15:55:19 -04:00
Kenny Y
c5b13099e6 Fix error assertion handling in approx when None in dict comparison
Dict comparsion in the ApproxMapping class did not check if values were None before attempting to subtract for max_abs_diff stat, which was throwing an TypeError instead of being handled by pytest error assertion. Check for None has been added before these calculations, so that None will properly show as Obtained/Expected in pytest assert message
2023-07-07 14:42:59 -04:00
Zac Hatfield-Dodds
97ed533f63 Merge pull request #11169 from hugovk/test-me-rm-3.7 2023-07-06 22:28:44 -07:00
Ran Benita
f5a9aa0b84 Merge pull request #11175 from pytest-dev/dependabot/pip/testing/plugins_integration/django-4.2.3
build(deps): Bump django from 4.2.2 to 4.2.3 in /testing/plugins_integration
2023-07-06 11:51:44 +03:00
Zac Hatfield-Dodds
901316b3f4 Merge pull request #8502 from mickeypash/patch-2 2023-07-06 00:28:20 -07:00
Zac Hatfield-Dodds
b81003f6fb Incorporate legend into main table 2023-07-06 00:04:15 -07:00
mickeypash
ddd773ecb1 [docs] add table nose x pytest naming comparison 2023-07-05 23:46:32 -07:00
dependabot[bot]
44604f49cd build(deps): Bump django in /testing/plugins_integration
Bumps [django](https://github.com/django/django) from 4.2.2 to 4.2.3.
- [Commits](https://github.com/django/django/compare/4.2.2...4.2.3)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-05 22:57:45 +00:00
Zac Hatfield-Dodds
2203897086 Merge pull request #11173 from bluetech/enc-warning-detox
tox: turn off PYTHONWARNDEFAULTENCODING for pre-commit, sphinx etc.
2023-07-05 09:48:26 -07:00
Ran Benita
119cec0279 tox: turn off PYTHONWARNDEFAULTENCODING for pre-commit, sphinx etc.
Fix #11157.
2023-07-05 19:05:08 +03:00
Florian Bruhin
b5bc53e441 Update open trainings (#11171) 2023-07-04 23:19:24 +02:00
Zac Hatfield-Dodds
084d756ae6 Merge pull request #11143 from tushar-deepsource/patch-1 2023-07-04 10:47:13 -07:00
Zac Hatfield-Dodds
d7dbadbffc Merge pull request #11160 from lesnek/ml/fix/warinings-recorder-pop 2023-07-04 10:20:04 -07:00
Zac Hatfield-Dodds
cb732f7f49 Merge branch 'main' into patch-1 2023-07-04 10:17:06 -07:00
Zac Hatfield-Dodds
7775e494b1 Further tweaks from code review 2023-07-04 10:00:29 -07:00
Hugo van Kemenade
1f5058e972 Use same Black version for blacken-docs as regular Black check 2023-07-04 18:55:08 +03:00
Hugo van Kemenade
6baf9f2d31 Update docs and code after dropping EOL 3.7 2023-07-04 18:55:08 +03:00
Lesnek
c4876c7106 chore(CR): Add changes from code review 2023-07-04 11:49:11 +02:00
Milan Lesnek
6badb6f01e Apply suggestions from code review
chore(changelog): describe better the fix

Co-authored-by: Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
2023-07-04 10:30:19 +02:00
Lesnek
4517af1e28 test(warnings-recorder): Add attribute error test 2023-07-04 10:30:19 +02:00
Lesnek
3d0dedb5ec test(warnings-recorder): Add attribute error test 2023-07-04 10:30:19 +02:00
Lesnek
7b7bd304aa fix(warnings-recorder): Add handling of rest 2023-07-04 10:30:19 +02:00
Lesnek
2706271f66 test(warnings-recorder): Add another warning 2023-07-04 10:30:19 +02:00
Lesnek
8ac3c645fa fix(warnings-recorder): Match also subclass of warning in pop 2023-07-04 10:30:19 +02:00
Lesnek
18e87c9831 test(warnings-recorder): Add non working subclass behaviour of pop 2023-07-04 10:30:19 +02:00
pre-commit-ci[bot]
6995257cf4 [pre-commit.ci] pre-commit autoupdate (#11165)
updates:
- [github.com/asottile/pyupgrade: v3.7.0 → v3.8.0](https://github.com/asottile/pyupgrade/compare/v3.7.0...v3.8.0)
- [github.com/asottile/setup-cfg-fmt: v2.3.0 → v2.4.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.3.0...v2.4.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-07-04 07:00:14 +00:00
Ronny Pfannschmidt
bea56b30af Switch to deploy environment and configure for pypi oidc (#10925)
Closes #10871
Closes #10870
2023-07-03 12:52:58 -03:00
github-actions[bot]
b847084224 [automated] Update plugin list (#11159)
Co-authored-by: pytest bot <pytestbot@users.noreply.github.com>
2023-07-03 11:45:17 -03:00
Akhilesh Ramakrishnan
024e62e6d2 Added Akhilesh Ramakrishnan to AUTHORS (#11153)
* Added Akhilesh Ramakrishnan to AUTHORS

PR#10338

* Fix typo in changelog
2023-07-03 13:49:50 +02:00
Ronny Pfannschmidt
f9410fddcd Merge pull request #11155 from RonnyPfannschmidt/fix-10447-maker-mro-order-needs-reverse
fix #10447 - consider marks in reverse mro order to give base classes priority
2023-07-02 22:23:00 +02:00
Ronny Pfannschmidt
561f1a993b fix #10447 - consider marks in reverse mro order to give base classes priority 2023-07-01 22:27:18 +02:00
Bruno Oliveira
b77d0deaf5 Fix duplicated imports with importlib mode and doctest-modules (#11148)
The initial implementation (in #7246) introduced the `importlib` mode, which
never added the imported module to `sys.modules`, so it included a test
to ensure calling `import_path` twice would yield different modules.

Not adding modules to `sys.modules` proved problematic, so we began to add the imported module to `sys.modules`
in #7870, but failed to realize that given we are now changing `sys.modules`, we might
as well avoid importing it more than once.

Then #10088 came along, passing `importlib` also when importing application modules
(as opposed to only test modules before), which caused problems due to imports
having side-effects and the expectation being that they are imported only once.

With this PR, `import_path` returns the module immediately if already in
`sys.modules`.

Fix #10811
Fix #10341
2023-07-01 15:37:46 +00:00
akhilramkee
2f7415cfbc Add child modules as attributes of parent modules. (#10338)
Failing to add child modules as attributes of parent module will prevent them from being accessible through parent module.

Fix #10337
2023-07-01 15:12:41 +00:00
Zac Hatfield-Dodds
ba60649680 Merge pull request #11129 from Cheukting/warn_in_expt 2023-06-30 21:58:42 -07:00
Zac Hatfield-Dodds
679bd6f2ed Merge pull request #10937 from reaganjlee/re-emit 2023-06-30 21:21:37 -07:00
Zac Hatfield-Dodds
a50ea1b8e7 Merge pull request #11152 from Zac-HD/drop-py37 2023-06-30 20:56:47 -07:00
Zac Hatfield-Dodds
0353a94cd1 Explicit GC for PyPy, take 2 2023-06-30 20:33:12 -07:00
Zac Hatfield-Dodds
0311fc3384 Apply suggestions from code review
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-06-30 20:18:25 -07:00
Zac Hatfield-Dodds
7fdc8391e2 Explicit GC for PyPy 2023-06-30 16:23:18 -07:00
Cheukting
15524f34d2 capture warning when exception is raised (fix #9036) 2023-06-30 16:04:37 -07:00
Zac Hatfield-Dodds
2d48171e88 Tweak docs on review 2023-06-30 15:29:03 -07:00
Zac Hatfield-Dodds
7022fb455d Update tests for re-emitted warnings 2023-06-30 15:29:03 -07:00
Zac Hatfield-Dodds
a1b37022af Refactor warns() exit logic 2023-06-30 15:29:02 -07:00
Reagan Lee
9279ea2882 Emit unmatched warnings from pytest.warns() 2023-06-30 15:29:02 -07:00
Zac Hatfield-Dodds
165fbbd12a Drop py37 from CI 2023-06-30 15:19:19 -07:00
Zac Hatfield-Dodds
f617bab0a2 Update pre-commit config 2023-06-30 15:07:07 -07:00
Zac Hatfield-Dodds
f4e3b4ad98 Drop Python 3.7 2023-06-30 14:55:42 -07:00
Ran Benita
81cfb3fc87 Merge pull request #11017 from erik-hasse/caplog-root-logger-docs
add a warning about modifying the root logger during tests
2023-06-28 09:28:46 +03:00
pre-commit-ci[bot]
dd5f3773d9 [pre-commit.ci] pre-commit autoupdate (#11145)
updates:
- [github.com/PyCQA/autoflake: v2.1.1 → v2.2.0](https://github.com/PyCQA/autoflake/compare/v2.1.1...v2.2.0)
- [github.com/pre-commit/mirrors-mypy: v1.3.0 → v1.4.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.3.0...v1.4.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-06-27 05:28:11 +00:00
Ran Benita
e132d6488f Merge pull request #11139 from pytest-dev/update-plugin-list/patch-fe51121f3
[automated] Update plugin list
2023-06-26 15:33:14 +03:00
pre-commit-ci[bot]
4719d998d8 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-06-26 11:34:03 +00:00
Tushar Sadhwani
5332656906 Add changelog and author 2023-06-26 17:02:33 +05:30
Tushar Sadhwani
a14fc10cac add a test function to the test 2023-06-26 13:06:11 +05:30
Tushar Sadhwani
05d7e60904 Add test 2023-06-26 12:37:23 +05:30
Tushar Sadhwani
4ebb2b94c2 fix code for py37 2023-06-26 12:19:42 +05:30
Tushar Sadhwani
9859c110cc Ensure the docstring is a string 2023-06-26 12:14:41 +05:30
Zac Hatfield-Dodds
5eaf8207eb Merge pull request #8428 from graingert/warn-when-a-mark-is-applied-to-a-fixture 2023-06-25 10:21:18 -07:00
Thomas Grainger
518ca37cae Update doc/en/deprecations.rst 2023-06-25 16:09:04 +01:00
Thomas Grainger
45f1a462d5 Apply suggestions from code review
Co-authored-by: Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
2023-06-25 16:08:53 +01:00
Thomas Grainger
4cd95eeabf Merge branch 'main' into warn-when-a-mark-is-applied-to-a-fixture 2023-06-25 16:08:11 +01:00
pytest bot
1306b84241 [automated] Update plugin list 2023-06-25 00:27:02 +00:00
Ran Benita
fe51121f39 Merge pull request #11042 from bluetech/pkg-init-argpath
python: change `pytest pkg/__init__.py` to only collect the `__init__.py` Module
2023-06-23 21:09:00 +03:00
Ran Benita
c8b1790ee7 python: change pytest pkg/__init__.py to only collect the __init__.py Module
Previously it would collect the entire package, but this is not what
users expect.

Refs #3749
Fixes #8976
Fixes #9263
Fixes #9313
2023-06-23 20:42:50 +03:00
Ran Benita
2870157234 Merge pull request #11133 from bluetech/removed-in-8-error
Change PytestRemovedIn8Warning to error by default, add PytestRemovedIn9Warning
2023-06-23 20:13:17 +03:00
Ran Benita
1b7896f83d Add PytestRemovedIn9Warning
It's good to have it available already in all 8.* versions, even if it's
not used yet.
2023-06-23 16:42:26 +03:00
Ran Benita
a4a189ad99 Change PytestRemovedIn8Warning to error by default
Per our backward compatibility policy.
2023-06-23 16:42:24 +03:00
Ran Benita
bd88a6412d reference: separate node types to their own section
I think it's helpful to separate the node classes from the other
objects, as they have their own unique usage.

I've chosen not to alphabetize the order, but to use a logical order
instead.

Also slightly improve the docstrings.
2023-06-14 15:57:56 +03:00
Ran Benita
264e7ac327 reference: add doc for Package
We document the other py collectors, we should document `Package` as
well.
2023-06-14 09:51:37 +03:00
Erik Hasse
a2feb6bd00 add a warning about modifying the root logger during tests 2023-05-18 09:26:16 -05:00
Thomas Grainger
246ceb84bd Update doc/en/deprecations.rst 2022-10-10 13:58:05 +01:00
Thomas Grainger
2fd160110c Merge branch 'main' into warn-when-a-mark-is-applied-to-a-fixture 2022-10-10 13:55:24 +01:00
Thomas Grainger
2998b596b4 Merge remote-tracking branch 'graingert/warn-when-a-mark-is-applied-to-a-fixture' into warn-when-a-mark-is-applied-to-a-fixture 2022-10-10 13:53:51 +01:00
Thomas Grainger
7f73722c4a add a test for fixture between mark decorators 2022-10-10 13:52:26 +01:00
Thomas Grainger
f7542f6292 move tests into deprecated_test, and test for number of warnings issued 2022-10-10 13:48:26 +01:00
pre-commit-ci[bot]
0de2aa93f0 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-10-10 11:30:13 +00:00
Thomas Grainger
7759a9d3c2 Update src/_pytest/deprecated.py
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2022-10-10 12:28:30 +01:00
Thomas Grainger
d86df89a92 Update doc/en/deprecations.rst
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2022-10-10 12:28:22 +01:00
Thomas Grainger
24fd292878 Update changelog/3664.deprecation.rst
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2022-10-10 12:28:14 +01:00
Thomas Grainger
a1b10b552a use getfixturemarker 2022-10-09 20:25:48 +01:00
pre-commit-ci[bot]
aa9cc7e8b4 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-10-09 19:11:57 +00:00
Thomas Grainger
5c286d19d8 Update doc/en/deprecations.rst 2022-10-09 20:11:51 +01:00
Thomas Grainger
faac197fcf Merge branch 'main' into warn-when-a-mark-is-applied-to-a-fixture 2022-10-09 20:10:53 +01:00
Thomas Grainger
5227279c15 Update changelog/3664.deprecation.rst 2021-03-19 09:47:19 +00:00
Thomas Grainger
a7e0ae2455 update MARKED_FIXTURE deprecation message 2021-03-19 09:44:39 +00:00
Thomas Grainger
12efc58479 document deprecation in deprecations.rst 2021-03-19 09:43:22 +00:00
Thomas Grainger
3f71680ac0 Warn when a mark is applied to a fixture
Fixes #3664
2021-03-19 09:30:52 +00:00
312 changed files with 18245 additions and 8952 deletions

View File

@@ -23,6 +23,11 @@ afc607cfd81458d4e4f3b1f3cf8cc931b933907e
5f95dce95602921a70bfbc7d8de2f7712c5e4505
# ran pyupgrade-docs again
75d0b899bbb56d6849e9d69d83a9426ed3f43f8b
# move argument parser to own file
c9df77cbd6a365dcb73c39618e4842711817e871
# Replace reorder-python-imports by isort due to black incompatibility (#11896)
8b54596639f41dfac070030ef20394b9001fe63c
# Run blacken-docs with black's 2024's style
4546d5445aaefe6a03957db028c263521dfb5c4b
# Migration to ruff / ruff format
4588653b2497ed25976b7aaff225b889fb476756

View File

@@ -22,7 +22,7 @@ jobs:
pull-requests: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true

View File

@@ -1,60 +1,101 @@
name: deploy
on:
push:
tags:
# These tags are protected, see:
# https://github.com/pytest-dev/pytest/settings/tag_protection
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+rc[0-9]+"
workflow_dispatch:
inputs:
version:
description: 'Release version'
required: true
default: '1.2.3'
# Set permissions at the job level.
permissions: {}
jobs:
deploy:
if: github.repository == 'pytest-dev/pytest'
package:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
env:
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ github.event.inputs.version }}
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5
uses: hynek/build-and-inspect-python-package@v2.4.0
deploy:
if: github.repository == 'pytest-dev/pytest'
needs: [package]
runs-on: ubuntu-latest
environment: deploy
timeout-minutes: 30
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v4
- name: Download Package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
uses: pypa/gh-action-pypi-publish@v1.8.14
- name: Push tag
run: |
git config user.name "pytest bot"
git config user.email "pytestbot@gmail.com"
git tag --annotate --message=v${{ github.event.inputs.version }} ${{ github.event.inputs.version }} ${{ github.sha }}
git push origin ${{ github.event.inputs.version }}
release-notes:
# todo: generate the content in the build job
# the goal being of using a github action script to push the release data
# after success instead of creating a complete python/tox env
needs: [deploy]
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
password: ${{ secrets.pypi_token }}
fetch-depth: 0
persist-credentials: false
- name: Download Package
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.7"
python-version: "3.11"
- name: Install tox
run: |
python -m pip install --upgrade pip
pip install --upgrade tox
- name: Publish GitHub release notes
env:
GH_RELEASE_NOTES_TOKEN: ${{ github.token }}
- name: Generate release notes
run: |
sudo apt-get install pandoc
tox -e publish-gh-release-notes
tox -e generate-gh-release-notes -- ${{ github.event.inputs.version }} scripts/latest-release-notes.md
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
with:
body_path: scripts/latest-release-notes.md
files: dist/*
tag_name: ${{ github.event.inputs.version }}

View File

@@ -27,12 +27,12 @@ jobs:
pull-requests: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.8"

View File

@@ -10,14 +10,14 @@ jobs:
permissions:
issues: write
steps:
- uses: actions/stale@v8
- uses: actions/stale@v9
with:
debug-only: false
days-before-issue-stale: 14
days-before-issue-close: 7
only-labels: "status: needs information"
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 14 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale."
stale-issue-message: "This issue is stale because it has the `status: needs information` label and requested follow-up information was not provided for 14 days."
close-issue-message: "This issue was closed because it has the `status: needs information` label and follow-up information has not been provided for 7 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1

View File

@@ -27,7 +27,19 @@ concurrency:
permissions: {}
jobs:
package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v2.4.0
build:
needs: [package]
runs-on: ${{ matrix.os }}
timeout-minutes: 45
permissions:
@@ -37,48 +49,41 @@ jobs:
fail-fast: false
matrix:
name: [
"windows-py37",
"windows-py37-pluggy",
"windows-py38",
"windows-py38-pluggy",
"windows-py39",
"windows-py310",
"windows-py311",
"windows-py312",
"ubuntu-py37",
"ubuntu-py37-pluggy",
"ubuntu-py37-freeze",
"ubuntu-py38",
"ubuntu-py38-pluggy",
"ubuntu-py38-freeze",
"ubuntu-py39",
"ubuntu-py310",
"ubuntu-py311",
"ubuntu-py312",
"ubuntu-pypy3",
"macos-py37",
"macos-py38",
"macos-py39",
"macos-py310",
"macos-py312",
"docs",
"doctesting",
"plugins",
]
include:
- name: "windows-py37"
python: "3.7"
os: windows-latest
tox_env: "py37-numpy"
- name: "windows-py37-pluggy"
python: "3.7"
os: windows-latest
tox_env: "py37-pluggymain-pylib-xdist"
- name: "windows-py38"
python: "3.8"
os: windows-latest
tox_env: "py38-unittestextras"
use_coverage: true
- name: "windows-py38-pluggy"
python: "3.8"
os: windows-latest
tox_env: "py38-pluggymain-pylib-xdist"
- name: "windows-py39"
python: "3.9"
os: windows-latest
@@ -96,23 +101,19 @@ jobs:
os: windows-latest
tox_env: "py312"
- name: "ubuntu-py37"
python: "3.7"
os: ubuntu-latest
tox_env: "py37-lsof-numpy-pexpect"
use_coverage: true
- name: "ubuntu-py37-pluggy"
python: "3.7"
os: ubuntu-latest
tox_env: "py37-pluggymain-pylib-xdist"
- name: "ubuntu-py37-freeze"
python: "3.7"
os: ubuntu-latest
tox_env: "py37-freeze"
- name: "ubuntu-py38"
python: "3.8"
os: ubuntu-latest
tox_env: "py38-xdist"
tox_env: "py38-lsof-numpy-pexpect"
use_coverage: true
- name: "ubuntu-py38-pluggy"
python: "3.8"
os: ubuntu-latest
tox_env: "py38-pluggymain-pylib-xdist"
- name: "ubuntu-py38-freeze"
python: "3.8"
os: ubuntu-latest
tox_env: "py38-freeze"
- name: "ubuntu-py39"
python: "3.9"
os: ubuntu-latest
@@ -132,14 +133,14 @@ jobs:
tox_env: "py312"
use_coverage: true
- name: "ubuntu-pypy3"
python: "pypy-3.7"
python: "pypy-3.8"
os: ubuntu-latest
tox_env: "pypy3-xdist"
- name: "macos-py37"
python: "3.7"
- name: "macos-py38"
python: "3.8"
os: macos-latest
tox_env: "py37-xdist"
tox_env: "py38-xdist"
- name: "macos-py39"
python: "3.9"
os: macos-latest
@@ -155,28 +156,30 @@ jobs:
tox_env: "py312-xdist"
- name: "plugins"
python: "3.9"
python: "3.12"
os: ubuntu-latest
tox_env: "plugins"
- name: "docs"
python: "3.7"
os: ubuntu-latest
tox_env: "docs"
- name: "doctesting"
python: "3.7"
python: "3.8"
os: ubuntu-latest
tox_env: "doctesting"
use_coverage: true
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Download Package
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
check-latest: ${{ endsWith(matrix.python, '-dev') }}
@@ -188,11 +191,13 @@ jobs:
- name: Test without coverage
if: "! matrix.use_coverage"
run: "tox -e ${{ matrix.tox_env }}"
shell: bash
run: tox run -e ${{ matrix.tox_env }} --installpkg `find dist/*.tar.gz`
- name: Test with coverage
if: "matrix.use_coverage"
run: "tox -e ${{ matrix.tox_env }}-coverage"
shell: bash
run: tox run -e ${{ matrix.tox_env }}-coverage --installpkg `find dist/*.tar.gz`
- name: Generate coverage report
if: "matrix.use_coverage"
@@ -200,16 +205,9 @@ jobs:
- name: Upload coverage to Codecov
if: "matrix.use_coverage"
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
continue-on-error: true
with:
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

@@ -20,25 +20,33 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: "3.11"
cache: pip
- name: requests-cache
uses: actions/cache@v4
with:
path: ~/.cache/pytest-plugin-list/
key: plugins-http-cache-${{ github.run_id }} # Can use time based key as well
restore-keys: plugins-http-cache-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install packaging requests tabulate[widechars] tqdm
pip install packaging requests tabulate[widechars] tqdm requests-cache platformdirs
- name: Update Plugin List
run: python scripts/update-plugin-list.py
- name: Create Pull Request
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
with:
commit-message: '[automated] Update plugin list'
author: 'pytest bot <pytestbot@users.noreply.github.com>'

1
.gitignore vendored
View File

@@ -51,6 +51,7 @@ coverage.xml
.settings
.vscode
__pycache__/
.python-version
# generated by pip
pip-wheel-metadata/

View File

@@ -1,16 +1,12 @@
repos:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
args: [--safe, --quiet]
- repo: https://github.com/asottile/blacken-docs
rev: 1.14.0
hooks:
- id: blacken-docs
additional_dependencies: [black==23.1.0]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.4.1"
hooks:
- id: ruff
args: ["--fix"]
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@@ -20,58 +16,47 @@ repos:
- id: debug-statements
exclude: _pytest/(debugging|hookspec).py
language_version: python3
- repo: https://github.com/PyCQA/autoflake
rev: v2.1.1
- repo: https://github.com/adamchainz/blacken-docs
rev: 1.16.0
hooks:
- id: autoflake
name: autoflake
args: ["--in-place", "--remove-unused-variables", "--remove-all-unused-imports"]
language: python
files: \.py$
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
language_version: python3
additional_dependencies:
- flake8-typing-imports==1.12.0
- flake8-docstrings==1.5.0
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.10.0
hooks:
- id: reorder-python-imports
args: ['--application-directories=.:src', --py37-plus]
- repo: https://github.com/asottile/pyupgrade
rev: v3.7.0
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.3.0
hooks:
- id: setup-cfg-fmt
args: ["--max-py-version=3.12", "--include-version-classifiers"]
- id: blacken-docs
additional_dependencies: [black==24.1.1]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-use-type-annotations
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
rev: v1.9.0
hooks:
- id: mypy
files: ^(src/|testing/)
files: ^(src/|testing/|scripts/)
args: []
additional_dependencies:
- iniconfig>=1.1.0
- attrs>=19.2.0
- pluggy>=1.5.0
- packaging
- tomli
- types-pkg_resources
- types-tabulate
# for mypy running on python>=3.11 since exceptiongroup is only a dependency
# on <3.11
- exceptiongroup>=1.0.0rc8
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "1.8.0"
hooks:
- id: pyproject-fmt
# https://pyproject-fmt.readthedocs.io/en/latest/#calculating-max-supported-python-version
additional_dependencies: ["tox>=4.9"]
- repo: local
hooks:
- id: pylint
name: pylint
entry: pylint
language: system
types: [python]
args: ["-rn", "-sn", "--fail-on=I"]
stages: [manual]
- id: rst
name: rst
entry: rst-lint --encoding utf-8

View File

@@ -9,6 +9,10 @@ python:
path: .
- requirements: doc/en/requirements.txt
sphinx:
configuration: doc/en/conf.py
fail_on_warning: true
build:
os: ubuntu-20.04
tools:

43
AUTHORS
View File

@@ -11,6 +11,7 @@ Adam Johnson
Adam Stewart
Adam Uhlir
Ahn Ki-Wook
Akhilesh Ramakrishnan
Akiomi Kamakura
Alan Velasco
Alessio Izzo
@@ -47,15 +48,20 @@ Ariel Pillemer
Armin Rigo
Aron Coyle
Aron Curzon
Arthur Richard
Ashish Kurmi
Aviral Verma
Aviv Palivoda
Babak Keyvani
Barney Gale
Ben Brown
Ben Gartner
Ben Leith
Ben Webb
Benjamin Peterson
Benjamin Schubert
Bernard Pratz
Bo Wu
Bob Ippolito
Brian Dorsey
Brian Larsen
@@ -88,12 +94,14 @@ Christopher Dignam
Christopher Gilling
Claire Cecil
Claudio Madotto
Clément M.T. Robert
CrazyMerlyn
Cristian Vera
Cyrus Maden
Damian Skrzypczak
Daniel Grana
Daniel Hahler
Daniel Miller
Daniel Nuri
Daniel Sánchez Castelló
Daniel Valenzuela Zenteno
@@ -111,6 +119,7 @@ Daw-Ran Liou
Debi Mishra
Denis Kirisov
Denivy Braiam Rück
Dheeraj C K
Dhiren Serai
Diego Russo
Dmitry Dygalo
@@ -121,6 +130,8 @@ Edison Gustavo Muenz
Edoardo Batini
Edson Tadeu M. Manoel
Eduardo Schettino
Edward Haigh
Eero Vaher
Eli Boyarski
Elizaveta Shashkova
Éloi Rivard
@@ -128,18 +139,23 @@ Endre Galaczi
Eric Hunsberger
Eric Liu
Eric Siegerman
Eric Yuan
Erik Aronesty
Erik Hasse
Erik M. Bray
Evan Kepner
Evgeny Seliverstov
Fabian Sturm
Fabien Zarifian
Fabio Zadrozny
faph
Felix Hofstätter
Felix Nieuwenhuizen
Feng Ma
Florian Bruhin
Florian Dahlitz
Floris Bruynooghe
Fraser Stark
Gabriel Landau
Gabriel Reis
Garvit Shubham
@@ -166,6 +182,8 @@ Ian Bicking
Ian Lesperance
Ilya Konstantinov
Ionuț Turturică
Isaac Virshup
Israel Fruchter
Itxaso Aizpurua
Iwan Briquemont
Jaap Broekhuizen
@@ -181,6 +199,7 @@ Javier Romero
Jeff Rackauckas
Jeff Widman
Jenni Rinker
Jens Tröger
John Eddie Ayson
John Litborn
John Towler
@@ -219,6 +238,7 @@ Kyle Altendorf
Lawrence Mitchell
Lee Kamentsky
Lev Maximov
Levon Saldamli
Lewis Cowles
Llandy Riveron Del Risco
Loic Esteve
@@ -229,9 +249,11 @@ Maho
Maik Figura
Mandeep Bhutani
Manuel Krebber
Marc Mueller
Marc Schlaich
Marcelo Duarte Trevisani
Marcin Bachry
Marc Bresson
Marco Gorelli
Mark Abramowitz
Mark Dickinson
@@ -256,15 +278,20 @@ Michael Goerz
Michael Krebs
Michael Seifert
Michal Wajszczuk
Michał Górny
Michał Zięba
Mickey Pashov
Mihai Capotă
Mihail Milushev
Mike Hoyle (hoylemd)
Mike Lundy
Milan Lesnek
Miro Hrončok
mrbean-bremen
Nathaniel Compton
Nathaniel Waisbrot
Ned Batchelder
Neil Martin
Neven Mundar
Nicholas Devenish
Nicholas Murphy
@@ -282,6 +309,7 @@ Ondřej Súkup
Oscar Benjamin
Parth Patel
Patrick Hayes
Patrick Lannigan
Paul Müller
Paul Reece
Pauli Virtanen
@@ -294,6 +322,7 @@ Pierre Sassoulas
Pieter Mulder
Piotr Banaszkiewicz
Piotr Helm
Poulami Sau
Prakhar Gurunani
Prashant Anand
Prashant Sharma
@@ -310,6 +339,7 @@ Raphael Pierzina
Rafal Semik
Raquel Alegre
Ravi Chandra
Reagan Lee
Robert Holt
Roberto Aldera
Roberto Polli
@@ -320,25 +350,33 @@ Ronny Pfannschmidt
Ross Lawley
Ruaridh Williamson
Russel Winder
Russell Martin
Ryan Puddephatt
Ryan Wooden
Sadra Barikbin
Saiprasad Kale
Samuel Colvin
Samuel Dion-Girardeau
Samuel Searles-Bryant
Samuel Therrien (Avasam)
Samuele Pedroni
Sanket Duthade
Sankt Petersbug
Saravanan Padmanaban
Sean Malloy
Segev Finer
Serhii Mozghovyi
Seth Junot
Shantanu Jain
Sharad Nair
Shubham Adep
Simon Blanchard
Simon Gomizelj
Simon Holesch
Simon Kerr
Skylar Downes
Srinivas Reddy Thatiparthy
Stefaan Lippens
Stefan Farmbauer
Stefan Scherfke
Stefan Zimmermann
@@ -352,6 +390,7 @@ Tadek Teleżyński
Takafumi Arakaki
Taneli Hukkinen
Tanvi Mehta
Tanya Agarwal
Tarcisio Fischer
Tareq Alayan
Tatiana Ovary
@@ -370,7 +409,9 @@ Tomer Keren
Tony Narlock
Tor Colvin
Trevor Bekolay
Tushar Sadhwani
Tyler Goodlet
Tyler Smart
Tzu-ping Chung
Vasily Kuznetsov
Victor Maryama
@@ -384,6 +425,7 @@ Vivaan Verma
Vlad Dragos
Vlad Radziuk
Vladyslav Rachek
Volodymyr Kochetkov
Volodymyr Piskun
Wei Lin
Wil Cooley
@@ -394,6 +436,7 @@ Xixi Zhao
Xuan Luong
Xuecong Liao
Yannick Péroux
Yao Xiao
Yoav Caspi
Yuliang Shao
Yusuke Kadowaki

View File

@@ -50,7 +50,7 @@ Fix bugs
--------
Look through the `GitHub issues for bugs <https://github.com/pytest-dev/pytest/labels/type:%20bug>`_.
See also the `"status: easy" issues <https://github.com/pytest-dev/pytest/labels/status%3A%20easy>`_
See also the `"good first issue" issues <https://github.com/pytest-dev/pytest/labels/good%20first%20issue>`_
that are friendly to new contributors.
:ref:`Talk <contact>` to developers to find out how you can fix specific bugs. To indicate that you are going
@@ -197,11 +197,12 @@ Short version
~~~~~~~~~~~~~
#. Fork the repository.
#. Fetch tags from upstream if necessary (if you cloned only main `git fetch --tags https://github.com/pytest-dev/pytest`).
#. Enable and install `pre-commit <https://pre-commit.com>`_ to ensure style-guides and code checks are followed.
#. Follow **PEP-8** for naming and `black <https://github.com/psf/black>`_ for formatting.
#. Follow `PEP-8 <https://www.python.org/dev/peps/pep-0008/>`_ for naming.
#. Tests are run using ``tox``::
tox -e linting,py37
tox -e linting,py39
The test environments above are usually enough to cover most cases locally.
@@ -236,6 +237,7 @@ Here is a simple overview, with pytest-specific bits:
$ git clone git@github.com:YOUR_GITHUB_USERNAME/pytest.git
$ cd pytest
$ git fetch --tags https://github.com/pytest-dev/pytest
# now, create your own branch off "main":
$ git checkout -b your-bugfix-branch-name main
@@ -272,35 +274,35 @@ Here is a simple overview, with pytest-specific bits:
#. Run all the tests
You need to have Python 3.7 available in your system. Now
You need to have Python 3.8 or later available in your system. Now
running tests is as simple as issuing this command::
$ tox -e linting,py37
$ tox -e linting,py39
This command will run tests via the "tox" tool against Python 3.7
This command will run tests via the "tox" tool against Python 3.9
and also perform "lint" coding-style checks.
#. You can now edit your local working copy and run the tests again as necessary. Please follow PEP-8 for naming.
#. You can now edit your local working copy and run the tests again as necessary. Please follow `PEP-8 <https://www.python.org/dev/peps/pep-0008/>`_ for naming.
You can pass different options to ``tox``. For example, to run tests on Python 3.7 and pass options to pytest
You can pass different options to ``tox``. For example, to run tests on Python 3.9 and pass options to pytest
(e.g. enter pdb on failure) to pytest you can do::
$ tox -e py37 -- --pdb
$ tox -e py39 -- --pdb
Or to only run tests in a particular test module on Python 3.7::
Or to only run tests in a particular test module on Python 3.9::
$ tox -e py37 -- testing/test_config.py
$ tox -e py39 -- testing/test_config.py
When committing, ``pre-commit`` will re-format the files if necessary.
#. If instead of using ``tox`` you prefer to run the tests directly, then we suggest to create a virtual environment and use
an editable install with the ``testing`` extra::
an editable install with the ``dev`` extra::
$ python3 -m venv .venv
$ source .venv/bin/activate # Linux
$ .venv/Scripts/activate.bat # Windows
$ pip install -e ".[testing]"
$ pip install -e ".[dev]"
Afterwards, you can edit the files and run pytest normally::

View File

@@ -20,16 +20,13 @@
:target: https://codecov.io/gh/pytest-dev/pytest
:alt: Code coverage Status
.. image:: https://github.com/pytest-dev/pytest/workflows/test/badge.svg
.. image:: https://github.com/pytest-dev/pytest/actions/workflows/test.yml/badge.svg
:target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Atest
.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg
:target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main
:alt: pre-commit.ci status
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black
.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg
:target: https://www.codetriage.com/pytest-dev/pytest
@@ -97,12 +94,12 @@ Features
- `Modular fixtures <https://docs.pytest.org/en/stable/explanation/fixtures.html>`_ for
managing small or parametrized long-lived test resources
- Can run `unittest <https://docs.pytest.org/en/stable/how-to/unittest.html>`_ (or trial),
`nose <https://docs.pytest.org/en/stable/how-to/nose.html>`_ test suites out of the box
- Can run `unittest <https://docs.pytest.org/en/stable/how-to/unittest.html>`_ (or trial)
test suites out of the box
- Python 3.7+ or PyPy3
- Python 3.8+ or PyPy3
- Rich plugin architecture, with over 850+ `external plugins <https://docs.pytest.org/en/latest/reference/plugin_list.html>`_ and thriving community
- Rich plugin architecture, with over 1300+ `external plugins <https://docs.pytest.org/en/latest/reference/plugin_list.html>`_ and thriving community
Documentation

View File

@@ -133,14 +133,12 @@ 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, tag the release commit
in the ``release-MAJOR.MINOR.PATCH`` branch and push it. This will publish to PyPI::
#. 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, using the ``release-MAJOR.MINOR.PATCH`` branch
as source.
git fetch upstream
git tag MAJOR.MINOR.PATCH upstream/release-MAJOR.MINOR.PATCH
git push upstream MAJOR.MINOR.PATCH
Wait for the deploy to complete, then make sure it is `available on PyPI <https://pypi.org/project/pytest>`_.
This job will require approval from ``pytest-dev/core``, after which it will publish to PyPI
and tag the repository.
#. Merge the PR. **Make sure it's not squash-merged**, so that the tagged commit ends up in the main branch.

View File

@@ -23,9 +23,9 @@ members of the `contributors team`_ interested in receiving funding.
The current list of contributors receiving funding are:
* `@asottile`_
* `@nicoddemus`_
* `@The-Compiler`_
* `@RonnyPfannschmidt`_
Contributors interested in receiving a part of the funds just need to submit a PR adding their
name to the list. Contributors that want to stop receiving the funds should also submit a PR
@@ -55,6 +55,6 @@ funds. Just drop a line to one of the `@pytest-dev/tidelift-admins`_ or use the
.. _`@pytest-dev/tidelift-admins`: https://github.com/orgs/pytest-dev/teams/tidelift-admins/members
.. _`agreement`: https://tidelift.com/docs/lifting/agreement
.. _`@asottile`: https://github.com/asottile
.. _`@nicoddemus`: https://github.com/nicoddemus
.. _`@The-Compiler`: https://github.com/The-Compiler
.. _`@RonnyPfannschmidt`: https://github.com/RonnyPfannschmidt

View File

@@ -1,10 +1,12 @@
import sys
if __name__ == "__main__":
import cProfile
import pytest # NOQA
import pstats
import pytest # noqa: F401
script = sys.argv[1:] if len(sys.argv) > 1 else ["empty.py"]
cProfile.run("pytest.cmdline.main(%r)" % script, "prof")
p = pstats.Stats("prof")

View File

@@ -4,6 +4,7 @@
# FastFilesCompleter 0.7383 1.0760
import timeit
imports = [
"from argcomplete.completers import FilesCompleter as completer",
"from _pytest._argcomplete import FastFilesCompleter as completer",

View File

@@ -1,5 +1,6 @@
import pytest
SKIP = True

View File

@@ -1,5 +1,6 @@
from unittest import TestCase # noqa: F401
for i in range(15000):
exec(
f"""

View File

@@ -14,7 +14,7 @@ Each file should be named like ``<ISSUE>.<TYPE>.rst``, where
``<ISSUE>`` is an issue number, and ``<TYPE>`` is one of:
* ``feature``: new user facing features, like new command-line options and new behavior.
* ``improvement``: improvement of existing functionality, usually without requiring user intervention (for example, new fields being written in ``--junitxml``, improved colors in terminal, etc).
* ``improvement``: improvement of existing functionality, usually without requiring user intervention (for example, new fields being written in ``--junit-xml``, improved colors in terminal, etc).
* ``bugfix``: fixes a bug.
* ``doc``: documentation improvement, like rewording an entire session or adding missing docs.
* ``deprecation``: feature deprecation.

View File

@@ -5,11 +5,10 @@
<div id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" aria-labelledby="searchlabel"
placeholder="Search"/>
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="{{ _('Go') }}" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>document.getElementById('searchbox').style.display = "block"</script>
{%- endif %}

View File

@@ -44,7 +44,7 @@ Partner projects, sign up here! (by 22 March)
What does it mean to "adopt pytest"?
-----------------------------------------
There can be many different definitions of "success". Pytest can run many nose_ and unittest_ tests by default, so using pytest as your testrunner may be possible from day 1. Job done, right?
There can be many different definitions of "success". Pytest can run many unittest_ tests by default, so using pytest as your testrunner may be possible from day 1. Job done, right?
Progressive success might look like:
@@ -62,7 +62,6 @@ Progressive success might look like:
It may be after the month is up, the partner project decides that pytest is not right for it. That's okay - hopefully the pytest team will also learn something about its weaknesses or deficiencies.
.. _nose: nose.html
.. _unittest: unittest.html
.. _assert: assert.html
.. _pycmd: https://bitbucket.org/hpk42/pycmd/overview

View File

@@ -6,6 +6,19 @@ Release announcements
:maxdepth: 2
release-8.2.0
release-8.1.2
release-8.1.1
release-8.1.0
release-8.0.2
release-8.0.1
release-8.0.0
release-8.0.0rc2
release-8.0.0rc1
release-7.4.4
release-7.4.3
release-7.4.2
release-7.4.1
release-7.4.0
release-7.3.2
release-7.3.1

View File

@@ -0,0 +1,20 @@
pytest-7.4.1
=======================================
pytest 7.4.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:
* Bruno Oliveira
* Florian Bruhin
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,18 @@
pytest-7.4.2
=======================================
pytest 7.4.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
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,19 @@
pytest-7.4.3
=======================================
pytest 7.4.3 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
* Marc Mueller
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,20 @@
pytest-7.4.4
=======================================
pytest 7.4.4 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
* Ran Benita
* Zac Hatfield-Dodds
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,26 @@
pytest-8.0.0
=======================================
The pytest team is proud to announce the 8.0.0 release!
This release contains new features, improvements, bug fixes, and breaking changes, so users
are encouraged to take a look at the CHANGELOG carefully:
https://docs.pytest.org/en/stable/changelog.html
For complete documentation, please visit:
https://docs.pytest.org/en/stable/
As usual, you can upgrade from PyPI via:
pip install -U pytest
Thanks to all of the contributors to this release:
* Bruno Oliveira
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,82 @@
pytest-8.0.0rc1
=======================================
The pytest team is proud to announce the 8.0.0rc1 release!
This release contains new features, improvements, bug fixes, and breaking changes, so users
are encouraged to take a look at the CHANGELOG carefully:
https://docs.pytest.org/en/stable/changelog.html
For complete documentation, please visit:
https://docs.pytest.org/en/stable/
As usual, you can upgrade from PyPI via:
pip install -U pytest
Thanks to all of the contributors to this release:
* Akhilesh Ramakrishnan
* Aleksandr Brodin
* Anthony Sottile
* Arthur Richard
* Avasam
* Benjamin Schubert
* Bruno Oliveira
* Carsten Grohmann
* Cheukting
* Chris Mahoney
* Christoph Anton Mitterer
* DetachHead
* Erik Hasse
* Florian Bruhin
* Fraser Stark
* Ha Pam
* Hugo van Kemenade
* Isaac Virshup
* Israel Fruchter
* Jens Tröger
* Jon Parise
* Kenny Y
* Lesnek
* Marc Mueller
* Michał Górny
* Mihail Milushev
* Milan Lesnek
* Miro Hrončok
* Patrick Lannigan
* Ran Benita
* Reagan Lee
* Ronny Pfannschmidt
* Sadra Barikbin
* Sean Malloy
* Sean Patrick Malloy
* Sharad Nair
* Simon Blanchard
* Sourabh Beniwal
* Stefaan Lippens
* Tanya Agarwal
* Thomas Grainger
* Tom Mortimer-Jones
* Tushar Sadhwani
* Tyler Smart
* Uday Kumar
* Warren Markham
* WarrenTheRabbit
* Zac Hatfield-Dodds
* Ziad Kermadi
* akhilramkee
* antosikv
* bowugit
* mickeypash
* neilmartin2000
* pomponchik
* ryanpudd
* touilleWoman
* ubaumann
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,32 @@
pytest-8.0.0rc2
=======================================
The pytest team is proud to announce the 8.0.0rc2 prerelease!
This is a prerelease, not intended for production use, but to test the upcoming features and improvements
in order to catch any major problems before the final version is released to the major public.
We appreciate your help testing this out before the final release, making sure to report any
regressions to our issue tracker:
https://github.com/pytest-dev/pytest/issues
When doing so, please include the string ``[prerelease]`` in the title.
You can upgrade from PyPI via:
pip install pytest==8.0.0rc2
Users are encouraged to take a look at the CHANGELOG carefully:
https://docs.pytest.org/en/release-8.0.0rc2/changelog.html
Thanks to all the contributors to this release:
* Ben Brown
* Bruno Oliveira
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,21 @@
pytest-8.0.1
=======================================
pytest 8.0.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:
* Bruno Oliveira
* Clément Robert
* Pierre Sassoulas
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,18 @@
pytest-8.0.2
=======================================
pytest 8.0.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:
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,54 @@
pytest-8.1.0
=======================================
The pytest team is proud to announce the 8.1.0 release!
This release contains new features, improvements, and bug fixes,
the full list of changes is available in the changelog:
https://docs.pytest.org/en/stable/changelog.html
For complete documentation, please visit:
https://docs.pytest.org/en/stable/
As usual, you can upgrade from PyPI via:
pip install -U pytest
Thanks to all of the contributors to this release:
* Ben Brown
* Ben Leith
* Bruno Oliveira
* Clément Robert
* Dave Hall
* Dương Quốc Khánh
* Eero Vaher
* Eric Larson
* Fabian Sturm
* Faisal Fawad
* Florian Bruhin
* Franck Charras
* Joachim B Haga
* John Litborn
* Loïc Estève
* Marc Bresson
* Patrick Lannigan
* Pierre Sassoulas
* Ran Benita
* Reagan Lee
* Ronny Pfannschmidt
* Russell Martin
* clee2000
* donghui
* faph
* jakkdl
* mrbean-bremen
* robotherapist
* whysage
* woutdenolf
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,18 @@
pytest-8.1.1
=======================================
pytest 8.1.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:
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,18 @@
pytest-8.1.2
=======================================
pytest 8.1.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
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,43 @@
pytest-8.2.0
=======================================
The pytest team is proud to announce the 8.2.0 release!
This release contains new features, improvements, and bug fixes,
the full list of changes is available in the changelog:
https://docs.pytest.org/en/stable/changelog.html
For complete documentation, please visit:
https://docs.pytest.org/en/stable/
As usual, you can upgrade from PyPI via:
pip install -U pytest
Thanks to all of the contributors to this release:
* Bruno Oliveira
* Daniel Miller
* Florian Bruhin
* HolyMagician03-UMich
* John Litborn
* Levon Saldamli
* Linghao Zhang
* Manuel López-Ibáñez
* Pierre Sassoulas
* Ran Benita
* Ronny Pfannschmidt
* Sebastian Meyer
* Shekhar verma
* Tamir Duberstein
* Tobias Stoeckmann
* dj
* jakkdl
* poulami-sau
* tserg
Happy testing,
The pytest Development Team

View File

@@ -22,7 +22,7 @@ b) transitional: the old and new API don't conflict
We will only start the removal of deprecated functionality in major releases (e.g. if we deprecate something in 3.0 we will start to remove it in 4.0), and keep it around for at least two minor releases (e.g. if we deprecate something in 3.9 and 4.0 is the next release, we start to remove it in 5.0, not in 4.0).
A deprecated feature scheduled to be removed in major version X will use the warning class `PytestRemovedInXWarning` (a subclass of :class:`~pytest.PytestDeprecationwarning`).
A deprecated feature scheduled to be removed in major version X will use the warning class `PytestRemovedInXWarning` (a subclass of :class:`~pytest.PytestDeprecationWarning`).
When the deprecation expires (e.g. 4.0 is released), we won't remove the deprecated functionality immediately, but will use the standard warning filters to turn `PytestRemovedInXWarning` (e.g. `PytestRemovedIn4Warning`) into **errors** by default. This approach makes it explicit that removal is imminent, and still gives you time to turn the deprecated feature into a warning instead of an error so it can be dealt with in your own time. In the next minor release (e.g. 4.1), the feature will be effectively removed.
@@ -87,6 +87,7 @@ Released pytest versions support all Python versions that are actively maintaine
============== ===================
pytest version min. Python version
============== ===================
8.0+ 3.8+
7.1+ 3.7+
6.2 - 7.0 3.6+
5.0 - 6.1 3.5+

View File

@@ -18,11 +18,11 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
$ pytest --fixtures -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collected 0 items
cache -- .../_pytest/cacheprovider.py:528
cache -- .../_pytest/cacheprovider.py:542
Return a cache object that can persist state between testing sessions.
cache.get(key, default)
@@ -33,7 +33,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Values can be any object handled by the json stdlib module.
capsysbinary -- .../_pytest/capture.py:1001
capsysbinary -- .../_pytest/capture.py:1003
Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``.
The captured output is made available via ``capsysbinary.readouterr()``
@@ -43,7 +43,6 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Returns an instance of :class:`CaptureFixture[bytes] <pytest.CaptureFixture>`.
Example:
.. code-block:: python
def test_output(capsysbinary):
@@ -51,7 +50,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capsysbinary.readouterr()
assert captured.out == b"hello\n"
capfd -- .../_pytest/capture.py:1029
capfd -- .../_pytest/capture.py:1030
Enable text capturing of writes to file descriptors ``1`` and ``2``.
The captured output is made available via ``capfd.readouterr()`` method
@@ -61,7 +60,6 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Returns an instance of :class:`CaptureFixture[str] <pytest.CaptureFixture>`.
Example:
.. code-block:: python
def test_system_echo(capfd):
@@ -79,7 +77,6 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Returns an instance of :class:`CaptureFixture[bytes] <pytest.CaptureFixture>`.
Example:
.. code-block:: python
def test_system_echo(capfdbinary):
@@ -87,7 +84,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capfdbinary.readouterr()
assert captured.out == b"hello\n"
capsys -- .../_pytest/capture.py:973
capsys -- .../_pytest/capture.py:976
Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``.
The captured output is made available via ``capsys.readouterr()`` method
@@ -97,7 +94,6 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Returns an instance of :class:`CaptureFixture[str] <pytest.CaptureFixture>`.
Example:
.. code-block:: python
def test_output(capsys):
@@ -105,7 +101,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capsys.readouterr()
assert captured.out == "hello\n"
doctest_namespace [session scope] -- .../_pytest/doctest.py:737
doctest_namespace [session scope] -- .../_pytest/doctest.py:738
Fixture that returns a :py:class:`dict` that will be injected into the
namespace of doctests.
@@ -119,7 +115,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:1353
pytestconfig [session scope] -- .../_pytest/fixtures.py:1335
Session-scoped fixture that returns the session's :class:`pytest.Config`
object.
@@ -129,7 +125,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
if pytestconfig.getoption("verbose") > 0:
...
record_property -- .../_pytest/junitxml.py:282
record_property -- .../_pytest/junitxml.py:284
Add extra properties to the calling test.
User properties become part of the test report and are available to the
@@ -143,13 +139,13 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
def test_function(record_property):
record_property("example_key", 1)
record_xml_attribute -- .../_pytest/junitxml.py:305
record_xml_attribute -- .../_pytest/junitxml.py:307
Add extra xml attributes to the tag for the calling test.
The fixture is callable with ``name, value``. The value is
automatically XML-encoded.
record_testsuite_property [session scope] -- .../_pytest/junitxml.py:343
record_testsuite_property [session scope] -- .../_pytest/junitxml.py:345
Record a new ``<property>`` tag as child of the root ``<testsuite>``.
This is suitable to writing global information regarding the entire test
@@ -174,18 +170,18 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
`pytest-xdist <https://github.com/pytest-dev/pytest-xdist>`__ plugin. See
:issue:`7767` for details.
tmpdir_factory [session scope] -- .../_pytest/legacypath.py:302
tmpdir_factory [session scope] -- .../_pytest/legacypath.py:303
Return a :class:`pytest.TempdirFactory` instance for the test session.
tmpdir -- .../_pytest/legacypath.py:309
tmpdir -- .../_pytest/legacypath.py:310
Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.
By default, a new base temporary directory is created each test session,
and old bases are removed after 3 sessions, to aid in debugging. If
``--basetemp`` is used then it is cleared each session. See :ref:`base
temporary directory`.
``--basetemp`` is used then it is cleared each session. See
:ref:`temporary directory location and retention`.
The returned object is a `legacy_path`_ object.
@@ -196,7 +192,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
.. _legacy_path: https://py.readthedocs.io/en/latest/path.html
caplog -- .../_pytest/logging.py:570
caplog -- .../_pytest/logging.py:602
Access and control log capturing.
Captured logs are available through the following properties/methods::
@@ -207,7 +203,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
* caplog.record_tuples -> list of (logger_name, level, message) tuples
* caplog.clear() -> clear captured records and formatted log output string
monkeypatch -- .../_pytest/monkeypatch.py:30
monkeypatch -- .../_pytest/monkeypatch.py:33
A convenient fixture for monkey-patching.
The fixture provides these methods to modify objects, dictionaries, or
@@ -231,16 +227,16 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
To undo modifications done by the fixture in a contained scope,
use :meth:`context() <pytest.MonkeyPatch.context>`.
recwarn -- .../_pytest/recwarn.py:30
recwarn -- .../_pytest/recwarn.py:32
Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.
See https://docs.pytest.org/en/latest/how-to/capture-warnings.html for information
on warning categories.
tmp_path_factory [session scope] -- .../_pytest/tmpdir.py:245
tmp_path_factory [session scope] -- .../_pytest/tmpdir.py:242
Return a :class:`pytest.TempPathFactory` instance for the test session.
tmp_path -- .../_pytest/tmpdir.py:260
tmp_path -- .../_pytest/tmpdir.py:257
Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.
@@ -249,8 +245,8 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
and old bases are removed after 3 sessions, to aid in debugging.
This behavior can be configured with :confval:`tmp_path_retention_count` and
:confval:`tmp_path_retention_policy`.
If ``--basetemp`` is used then it is cleared each session. See :ref:`base
temporary directory`.
If ``--basetemp`` is used then it is cleared each session. See
:ref:`temporary directory location and retention`.
The returned object is a :class:`pathlib.Path` object.

View File

@@ -28,6 +28,758 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start
pytest 8.2.0 (2024-04-27)
=========================
Deprecations
------------
- `#12069 <https://github.com/pytest-dev/pytest/issues/12069>`_: A deprecation warning is now raised when implementations of one of the following hooks request a deprecated ``py.path.local`` parameter instead of the ``pathlib.Path`` parameter which replaced it:
- :hook:`pytest_ignore_collect` - the ``path`` parameter - use ``collection_path`` instead.
- :hook:`pytest_collect_file` - the ``path`` parameter - use ``file_path`` instead.
- :hook:`pytest_pycollect_makemodule` - the ``path`` parameter - use ``module_path`` instead.
- :hook:`pytest_report_header` - the ``startdir`` parameter - use ``start_path`` instead.
- :hook:`pytest_report_collectionfinish` - the ``startdir`` parameter - use ``start_path`` instead.
The replacement parameters are available since pytest 7.0.0.
The old parameters will be removed in pytest 9.0.0.
See :ref:`legacy-path-hooks-deprecated` for more details.
Features
--------
- `#11871 <https://github.com/pytest-dev/pytest/issues/11871>`_: Added support for reading command line arguments from a file using the prefix character ``@``, like e.g.: ``pytest @tests.txt``. The file must have one argument per line.
See :ref:`Read arguments from file <args-from-file>` for details.
Improvements
------------
- `#11523 <https://github.com/pytest-dev/pytest/issues/11523>`_: :func:`pytest.importorskip` will now issue a warning if the module could be found, but raised :class:`ImportError` instead of :class:`ModuleNotFoundError`.
The warning can be suppressed by passing ``exc_type=ImportError`` to :func:`pytest.importorskip`.
See :ref:`import-or-skip-import-error` for details.
- `#11728 <https://github.com/pytest-dev/pytest/issues/11728>`_: For ``unittest``-based tests, exceptions during class cleanup (as raised by functions registered with :meth:`TestCase.addClassCleanup <unittest.TestCase.addClassCleanup>`) are now reported instead of silently failing.
- `#11777 <https://github.com/pytest-dev/pytest/issues/11777>`_: Text is no longer truncated in the ``short test summary info`` section when ``-vv`` is given.
- `#12112 <https://github.com/pytest-dev/pytest/issues/12112>`_: Improved namespace packages detection when :confval:`consider_namespace_packages` is enabled, covering more situations (like editable installs).
- `#9502 <https://github.com/pytest-dev/pytest/issues/9502>`_: Added :envvar:`PYTEST_VERSION` environment variable which is defined at the start of the pytest session and undefined afterwards. It contains the value of ``pytest.__version__``, and among other things can be used to easily check if code is running from within a pytest run.
Bug Fixes
---------
- `#12065 <https://github.com/pytest-dev/pytest/issues/12065>`_: Fixed a regression in pytest 8.0.0 where test classes containing ``setup_method`` and tests using ``@staticmethod`` or ``@classmethod`` would crash with ``AttributeError: 'NoneType' object has no attribute 'setup_method'``.
Now the :attr:`request.instance <pytest.FixtureRequest.instance>` attribute of tests using ``@staticmethod`` and ``@classmethod`` is no longer ``None``, but a fresh instance of the class, like in non-static methods.
Previously it was ``None``, and all fixtures of such tests would share a single ``self``.
- `#12135 <https://github.com/pytest-dev/pytest/issues/12135>`_: Fixed issue where fixtures adding their finalizer multiple times to fixtures they request would cause unreliable and non-intuitive teardown ordering in some instances.
- `#12194 <https://github.com/pytest-dev/pytest/issues/12194>`_: Fixed a bug with ``--importmode=importlib`` and ``--doctest-modules`` where child modules did not appear as attributes in parent modules.
- `#1489 <https://github.com/pytest-dev/pytest/issues/1489>`_: Fixed some instances where teardown of higher-scoped fixtures was not happening in the reverse order they were initialized in.
Trivial/Internal Changes
------------------------
- `#12069 <https://github.com/pytest-dev/pytest/issues/12069>`_: ``pluggy>=1.5.0`` is now required.
- `#12167 <https://github.com/pytest-dev/pytest/issues/12167>`_: :ref:`cache <cache>`: create supporting files (``CACHEDIR.TAG``, ``.gitignore``, etc.) in a temporary directory to provide atomic semantics.
pytest 8.1.2 (2024-04-26)
=========================
Bug Fixes
---------
- `#12114 <https://github.com/pytest-dev/pytest/issues/12114>`_: Fixed error in :func:`pytest.approx` when used with `numpy` arrays and comparing with other types.
pytest 8.1.1 (2024-03-08)
=========================
.. note::
This release is not a usual bug fix release -- it contains features and improvements, being a follow up
to ``8.1.0``, which has been yanked from PyPI.
Features
--------
- `#11475 <https://github.com/pytest-dev/pytest/issues/11475>`_: Added the new :confval:`consider_namespace_packages` configuration option, defaulting to ``False``.
If set to ``True``, pytest will attempt to identify modules that are part of `namespace packages <https://packaging.python.org/en/latest/guides/packaging-namespace-packages>`__ when importing modules.
- `#11653 <https://github.com/pytest-dev/pytest/issues/11653>`_: Added the new :confval:`verbosity_test_cases` configuration option for fine-grained control of test execution verbosity.
See :ref:`Fine-grained verbosity <pytest.fine_grained_verbosity>` for more details.
Improvements
------------
- `#10865 <https://github.com/pytest-dev/pytest/issues/10865>`_: :func:`pytest.warns` now validates that :func:`warnings.warn` was called with a `str` or a `Warning`.
Currently in Python it is possible to use other types, however this causes an exception when :func:`warnings.filterwarnings` is used to filter those warnings (see `CPython #103577 <https://github.com/python/cpython/issues/103577>`__ for a discussion).
While this can be considered a bug in CPython, we decided to put guards in pytest as the error message produced without this check in place is confusing.
- `#11311 <https://github.com/pytest-dev/pytest/issues/11311>`_: When using ``--override-ini`` for paths in invocations without a configuration file defined, the current working directory is used
as the relative directory.
Previoulsy this would raise an :class:`AssertionError`.
- `#11475 <https://github.com/pytest-dev/pytest/issues/11475>`_: :ref:`--import-mode=importlib <import-mode-importlib>` now tries to import modules using the standard import mechanism (but still without changing :py:data:`sys.path`), falling back to importing modules directly only if that fails.
This means that installed packages will be imported under their canonical name if possible first, for example ``app.core.models``, instead of having the module name always be derived from their path (for example ``.env310.lib.site_packages.app.core.models``).
- `#11801 <https://github.com/pytest-dev/pytest/issues/11801>`_: Added the :func:`iter_parents() <_pytest.nodes.Node.iter_parents>` helper method on nodes.
It is similar to :func:`listchain <_pytest.nodes.Node.listchain>`, but goes from bottom to top, and returns an iterator, not a list.
- `#11850 <https://github.com/pytest-dev/pytest/issues/11850>`_: Added support for :data:`sys.last_exc` for post-mortem debugging on Python>=3.12.
- `#11962 <https://github.com/pytest-dev/pytest/issues/11962>`_: In case no other suitable candidates for configuration file are found, a ``pyproject.toml`` (even without a ``[tool.pytest.ini_options]`` table) will be considered as the configuration file and define the ``rootdir``.
- `#11978 <https://github.com/pytest-dev/pytest/issues/11978>`_: Add ``--log-file-mode`` option to the logging plugin, enabling appending to log-files. This option accepts either ``"w"`` or ``"a"`` and defaults to ``"w"``.
Previously, the mode was hard-coded to be ``"w"`` which truncates the file before logging.
- `#12047 <https://github.com/pytest-dev/pytest/issues/12047>`_: When multiple finalizers of a fixture raise an exception, now all exceptions are reported as an exception group.
Previously, only the first exception was reported.
Bug Fixes
---------
- `#11475 <https://github.com/pytest-dev/pytest/issues/11475>`_: Fixed regression where ``--importmode=importlib`` would import non-test modules more than once.
- `#11904 <https://github.com/pytest-dev/pytest/issues/11904>`_: Fixed a regression in pytest 8.0.0 that would cause test collection to fail due to permission errors when using ``--pyargs``.
This change improves the collection tree for tests specified using ``--pyargs``, see :pull:`12043` for a comparison with pytest 8.0 and <8.
- `#12011 <https://github.com/pytest-dev/pytest/issues/12011>`_: Fixed a regression in 8.0.1 whereby ``setup_module`` xunit-style fixtures are not executed when ``--doctest-modules`` is passed.
- `#12014 <https://github.com/pytest-dev/pytest/issues/12014>`_: Fix the ``stacklevel`` used when warning about marks used on fixtures.
- `#12039 <https://github.com/pytest-dev/pytest/issues/12039>`_: Fixed a regression in ``8.0.2`` where tests created using :fixture:`tmp_path` have been collected multiple times in CI under Windows.
Improved Documentation
----------------------
- `#11790 <https://github.com/pytest-dev/pytest/issues/11790>`_: Documented the retention of temporary directories created using the ``tmp_path`` fixture in more detail.
Trivial/Internal Changes
------------------------
- `#11785 <https://github.com/pytest-dev/pytest/issues/11785>`_: Some changes were made to private functions which may affect plugins which access them:
- ``FixtureManager._getautousenames()`` now takes a ``Node`` itself instead of the nodeid.
- ``FixtureManager.getfixturedefs()`` now takes the ``Node`` itself instead of the nodeid.
- The ``_pytest.nodes.iterparentnodeids()`` function is removed without replacement.
Prefer to traverse the node hierarchy itself instead.
If you really need to, copy the function from the previous pytest release.
- `#12069 <https://github.com/pytest-dev/pytest/issues/12069>`_: Delayed the deprecation of the following features to ``9.0.0``:
* :ref:`node-ctor-fspath-deprecation`.
* :ref:`legacy-path-hooks-deprecated`.
It was discovered after ``8.1.0`` was released that the warnings about the impeding removal were not being displayed, so the team decided to revert the removal.
This is the reason for ``8.1.0`` being yanked.
pytest 8.1.0 (YANKED)
=====================
.. note::
This release has been **yanked**: it broke some plugins without the proper warning period, due to
some warnings not showing up as expected.
See `#12069 <https://github.com/pytest-dev/pytest/issues/12069>`__.
pytest 8.0.2 (2024-02-24)
=========================
Bug Fixes
---------
- `#11895 <https://github.com/pytest-dev/pytest/issues/11895>`_: Fix collection on Windows where initial paths contain the short version of a path (for example ``c:\PROGRA~1\tests``).
- `#11953 <https://github.com/pytest-dev/pytest/issues/11953>`_: Fix an ``IndexError`` crash raising from ``getstatementrange_ast``.
- `#12021 <https://github.com/pytest-dev/pytest/issues/12021>`_: Reverted a fix to `--maxfail` handling in pytest 8.0.0 because it caused a regression in pytest-xdist whereby session fixture teardowns may get executed multiple times when the max-fails is reached.
pytest 8.0.1 (2024-02-16)
=========================
Bug Fixes
---------
- `#11875 <https://github.com/pytest-dev/pytest/issues/11875>`_: Correctly handle errors from :func:`getpass.getuser` in Python 3.13.
- `#11879 <https://github.com/pytest-dev/pytest/issues/11879>`_: Fix an edge case where ``ExceptionInfo._stringify_exception`` could crash :func:`pytest.raises`.
- `#11906 <https://github.com/pytest-dev/pytest/issues/11906>`_: Fix regression with :func:`pytest.warns` using custom warning subclasses which have more than one parameter in their `__init__`.
- `#11907 <https://github.com/pytest-dev/pytest/issues/11907>`_: Fix a regression in pytest 8.0.0 whereby calling :func:`pytest.skip` and similar control-flow exceptions within a :func:`pytest.warns()` block would get suppressed instead of propagating.
- `#11929 <https://github.com/pytest-dev/pytest/issues/11929>`_: Fix a regression in pytest 8.0.0 whereby autouse fixtures defined in a module get ignored by the doctests in the module.
- `#11937 <https://github.com/pytest-dev/pytest/issues/11937>`_: Fix a regression in pytest 8.0.0 whereby items would be collected in reverse order in some circumstances.
pytest 8.0.0 (2024-01-27)
=========================
Bug Fixes
---------
- `#11842 <https://github.com/pytest-dev/pytest/issues/11842>`_: Properly escape the ``reason`` of a :ref:`skip <pytest.mark.skip ref>` mark when writing JUnit XML files.
- `#11861 <https://github.com/pytest-dev/pytest/issues/11861>`_: Avoid microsecond exceeds ``1_000_000`` when using ``log-date-format`` with ``%f`` specifier, which might cause the test suite to crash.
pytest 8.0.0rc2 (2024-01-17)
============================
Improvements
------------
- `#11233 <https://github.com/pytest-dev/pytest/issues/11233>`_: Improvements to ``-r`` for xfailures and xpasses:
* Report tracebacks for xfailures when ``-rx`` is set.
* Report captured output for xpasses when ``-rX`` is set.
* For xpasses, add ``-`` in summary between test name and reason, to match how xfail is displayed.
- `#11825 <https://github.com/pytest-dev/pytest/issues/11825>`_: The :hook:`pytest_plugin_registered` hook has a new ``plugin_name`` parameter containing the name by which ``plugin`` is registered.
Bug Fixes
---------
- `#11706 <https://github.com/pytest-dev/pytest/issues/11706>`_: Fix reporting of teardown errors in higher-scoped fixtures when using `--maxfail` or `--stepwise`.
NOTE: This change was reverted in pytest 8.0.2 to fix a `regression <https://github.com/pytest-dev/pytest-xdist/issues/1024>`_ it caused in pytest-xdist.
- `#11758 <https://github.com/pytest-dev/pytest/issues/11758>`_: Fixed ``IndexError: string index out of range`` crash in ``if highlighted[-1] == "\n" and source[-1] != "\n"``.
This bug was introduced in pytest 8.0.0rc1.
- `#9765 <https://github.com/pytest-dev/pytest/issues/9765>`_, `#11816 <https://github.com/pytest-dev/pytest/issues/11816>`_: Fixed a frustrating bug that afflicted some users with the only error being ``assert mod not in mods``. The issue was caused by the fact that ``str(Path(mod))`` and ``mod.__file__`` don't necessarily produce the same string, and was being erroneously used interchangably in some places in the code.
This fix also broke the internal API of ``PytestPluginManager.consider_conftest`` by introducing a new parameter -- we mention this in case it is being used by external code, even if marked as *private*.
pytest 8.0.0rc1 (2023-12-30)
============================
Breaking Changes
----------------
Old Deprecations Are Now Errors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- `#7363 <https://github.com/pytest-dev/pytest/issues/7363>`_: **PytestRemovedIn8Warning deprecation warnings are now errors by default.**
Following our plan to remove deprecated features with as little disruption as
possible, all warnings of type ``PytestRemovedIn8Warning`` now generate errors
instead of warning messages by default.
**The affected features will be effectively removed in pytest 8.1**, so please consult the
:ref:`deprecations` section in the docs for directions on how to update existing code.
In the pytest ``8.0.X`` series, it is possible to change the errors back into warnings as a
stopgap measure by adding this to your ``pytest.ini`` file:
.. code-block:: ini
[pytest]
filterwarnings =
ignore::pytest.PytestRemovedIn8Warning
But this will stop working when pytest ``8.1`` is released.
**If you have concerns** about the removal of a specific feature, please add a
comment to :issue:`7363`.
Version Compatibility
^^^^^^^^^^^^^^^^^^^^^
- `#11151 <https://github.com/pytest-dev/pytest/issues/11151>`_: Dropped support for Python 3.7, which `reached end-of-life on 2023-06-27 <https://devguide.python.org/versions/>`__.
- ``pluggy>=1.3.0`` is now required.
Collection Changes
^^^^^^^^^^^^^^^^^^
In this version we've made several breaking changes to pytest's collection phase,
particularly around how filesystem directories and Python packages are collected,
fixing deficiencies and allowing for cleanups and improvements to pytest's internals.
A deprecation period for these changes was not possible.
- `#7777 <https://github.com/pytest-dev/pytest/issues/7777>`_: Files and directories are now collected in alphabetical order jointly, unless changed by a plugin.
Previously, files were collected before directories.
See below for an example.
- `#8976 <https://github.com/pytest-dev/pytest/issues/8976>`_: Running `pytest pkg/__init__.py` now collects the `pkg/__init__.py` file (module) only.
Previously, it collected the entire `pkg` package, including other test files in the directory, but excluding tests in the `__init__.py` file itself
(unless :confval:`python_files` was changed to allow `__init__.py` file).
To collect the entire package, specify just the directory: `pytest pkg`.
- `#11137 <https://github.com/pytest-dev/pytest/issues/11137>`_: :class:`pytest.Package` is no longer a :class:`pytest.Module` or :class:`pytest.File`.
The ``Package`` collector node designates a Python package, that is, a directory with an `__init__.py` file.
Previously ``Package`` was a subtype of ``pytest.Module`` (which represents a single Python module),
the module being the `__init__.py` file.
This has been deemed a design mistake (see :issue:`11137` and :issue:`7777` for details).
The ``path`` property of ``Package`` nodes now points to the package directory instead of the ``__init__.py`` file.
Note that a ``Module`` node for ``__init__.py`` (which is not a ``Package``) may still exist,
if it is picked up during collection (e.g. if you configured :confval:`python_files` to include ``__init__.py`` files).
- `#7777 <https://github.com/pytest-dev/pytest/issues/7777>`_: Added a new :class:`pytest.Directory` base collection node, which all collector nodes for filesystem directories are expected to subclass.
This is analogous to the existing :class:`pytest.File` for file nodes.
Changed :class:`pytest.Package` to be a subclass of :class:`pytest.Directory`.
A ``Package`` represents a filesystem directory which is a Python package,
i.e. contains an ``__init__.py`` file.
:class:`pytest.Package` now only collects files in its own directory; previously it collected recursively.
Sub-directories are collected as their own collector nodes, which then collect themselves, thus creating a collection tree which mirrors the filesystem hierarchy.
Added a new :class:`pytest.Dir` concrete collection node, a subclass of :class:`pytest.Directory`.
This node represents a filesystem directory, which is not a :class:`pytest.Package`,
that is, does not contain an ``__init__.py`` file.
Similarly to ``Package``, it only collects the files in its own directory.
:class:`pytest.Session` now only collects the initial arguments, without recursing into directories.
This work is now done by the :func:`recursive expansion process <pytest.Collector.collect>` of directory collector nodes.
:attr:`session.name <pytest.Session.name>` is now ``""``; previously it was the rootdir directory name.
This matches :attr:`session.nodeid <_pytest.nodes.Node.nodeid>` which has always been `""`.
The collection tree now contains directories/packages up to the :ref:`rootdir <rootdir>`,
for initial arguments that are found within the rootdir.
For files outside the rootdir, only the immediate directory/package is collected --
note however that collecting from outside the rootdir is discouraged.
As an example, given the following filesystem tree::
myroot/
pytest.ini
top/
├── aaa
│ └── test_aaa.py
├── test_a.py
├── test_b
│ ├── __init__.py
│ └── test_b.py
├── test_c.py
└── zzz
├── __init__.py
└── test_zzz.py
the collection tree, as shown by `pytest --collect-only top/` but with the otherwise-hidden :class:`~pytest.Session` node added for clarity,
is now the following::
<Session>
<Dir myroot>
<Dir top>
<Dir aaa>
<Module test_aaa.py>
<Function test_it>
<Module test_a.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Module test_c.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
Previously, it was::
<Session>
<Module top/test_a.py>
<Function test_it>
<Module top/test_c.py>
<Function test_it>
<Module top/aaa/test_aaa.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
Code/plugins which rely on a specific shape of the collection tree might need to update.
- `#11676 <https://github.com/pytest-dev/pytest/issues/11676>`_: The classes :class:`~_pytest.nodes.Node`, :class:`~pytest.Collector`, :class:`~pytest.Item`, :class:`~pytest.File`, :class:`~_pytest.nodes.FSCollector` are now marked abstract (see :mod:`abc`).
We do not expect this change to affect users and plugin authors, it will only cause errors when the code is already wrong or problematic.
Other breaking changes
^^^^^^^^^^^^^^^^^^^^^^
These are breaking changes where deprecation was not possible.
- `#11282 <https://github.com/pytest-dev/pytest/issues/11282>`_: Sanitized the handling of the ``default`` parameter when defining configuration options.
Previously if ``default`` was not supplied for :meth:`parser.addini <pytest.Parser.addini>` and the configuration option value was not defined in a test session, then calls to :func:`config.getini <pytest.Config.getini>` returned an *empty list* or an *empty string* depending on whether ``type`` was supplied or not respectively, which is clearly incorrect. Also, ``None`` was not honored even if ``default=None`` was used explicitly while defining the option.
Now the behavior of :meth:`parser.addini <pytest.Parser.addini>` is as follows:
* If ``default`` is NOT passed but ``type`` is provided, then a type-specific default will be returned. For example ``type=bool`` will return ``False``, ``type=str`` will return ``""``, etc.
* If ``default=None`` is passed and the option is not defined in a test session, then ``None`` will be returned, regardless of the ``type``.
* If neither ``default`` nor ``type`` are provided, assume ``type=str`` and return ``""`` as default (this is as per previous behavior).
The team decided to not introduce a deprecation period for this change, as doing so would be complicated both in terms of communicating this to the community as well as implementing it, and also because the team believes this change should not break existing plugins except in rare cases.
- `#11667 <https://github.com/pytest-dev/pytest/issues/11667>`_: pytest's ``setup.py`` file is removed.
If you relied on this file, e.g. to install pytest using ``setup.py install``,
please see `Why you shouldn't invoke setup.py directly <https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html#summary>`_ for alternatives.
- `#9288 <https://github.com/pytest-dev/pytest/issues/9288>`_: :func:`~pytest.warns` now re-emits unmatched warnings when the context
closes -- previously it would consume all warnings, hiding those that were not
matched by the function.
While this is a new feature, we announce it as a breaking change
because many test suites are configured to error-out on warnings, and will
therefore fail on the newly-re-emitted warnings.
- The internal ``FixtureManager.getfixtureclosure`` method has changed. Plugins which use this method or
which subclass ``FixtureManager`` and overwrite that method will need to adapt to the change.
Deprecations
------------
- `#10465 <https://github.com/pytest-dev/pytest/issues/10465>`_: Test functions returning a value other than ``None`` will now issue a :class:`pytest.PytestWarning` instead of ``pytest.PytestRemovedIn8Warning``, meaning this will stay a warning instead of becoming an error in the future.
- `#3664 <https://github.com/pytest-dev/pytest/issues/3664>`_: Applying a mark to a fixture function now issues a warning: marks in fixtures never had any effect, but it is a common user error to apply a mark to a fixture (for example ``usefixtures``) and expect it to work.
This will become an error in pytest 9.0.
Features and Improvements
-------------------------
Improved Diffs
^^^^^^^^^^^^^^
These changes improve the diffs that pytest prints when an assertion fails.
Note that syntax highlighting requires the ``pygments`` package.
- `#11520 <https://github.com/pytest-dev/pytest/issues/11520>`_: The very verbose (``-vv``) diff output is now colored as a diff instead of a big chunk of red.
Python code in error reports is now syntax-highlighted as Python.
The sections in the error reports are now better separated.
- `#1531 <https://github.com/pytest-dev/pytest/issues/1531>`_: The very verbose diff (``-vv``) for every standard library container type is improved. The indentation is now consistent and the markers are on their own separate lines, which should reduce the diffs shown to users.
Previously, the standard Python pretty printer was used to generate the output, which puts opening and closing
markers on the same line as the first/last entry, in addition to not having consistent indentation.
- `#10617 <https://github.com/pytest-dev/pytest/issues/10617>`_: Added more comprehensive set assertion rewrites for comparisons other than equality ``==``, with
the following operations now providing better failure messages: ``!=``, ``<=``, ``>=``, ``<``, and ``>``.
Separate Control For Assertion Verbosity
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- `#11387 <https://github.com/pytest-dev/pytest/issues/11387>`_: Added the new :confval:`verbosity_assertions` configuration option for fine-grained control of failed assertions verbosity.
If you've ever wished that pytest always show you full diffs, but without making everything else verbose, this is for you.
See :ref:`Fine-grained verbosity <pytest.fine_grained_verbosity>` for more details.
For plugin authors, :attr:`config.get_verbosity <pytest.Config.get_verbosity>` can be used to retrieve the verbosity level for a specific verbosity type.
Additional Support For Exception Groups and ``__notes__``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
These changes improve pytest's support for exception groups.
- `#10441 <https://github.com/pytest-dev/pytest/issues/10441>`_: Added :func:`ExceptionInfo.group_contains() <pytest.ExceptionInfo.group_contains>`, an assertion helper that tests if an :class:`ExceptionGroup` contains a matching exception.
See :ref:`assert-matching-exception-groups` for an example.
- `#11227 <https://github.com/pytest-dev/pytest/issues/11227>`_: Allow :func:`pytest.raises` ``match`` argument to match against `PEP-678 <https://peps.python.org/pep-0678/>` ``__notes__``.
Custom Directory collectors
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- `#7777 <https://github.com/pytest-dev/pytest/issues/7777>`_: Added a new hook :hook:`pytest_collect_directory`,
which is called by filesystem-traversing collector nodes,
such as :class:`pytest.Session`, :class:`pytest.Dir` and :class:`pytest.Package`,
to create a collector node for a sub-directory.
It is expected to return a subclass of :class:`pytest.Directory`.
This hook allows plugins to :ref:`customize the collection of directories <custom directory collectors>`.
"New-style" Hook Wrappers
^^^^^^^^^^^^^^^^^^^^^^^^^
- `#11122 <https://github.com/pytest-dev/pytest/issues/11122>`_: pytest now uses "new-style" hook wrappers internally, available since pluggy 1.2.0.
See `pluggy's 1.2.0 changelog <https://pluggy.readthedocs.io/en/latest/changelog.html#pluggy-1-2-0-2023-06-21>`_ and the :ref:`updated docs <hookwrapper>` for details.
Plugins which want to use new-style wrappers can do so if they require ``pytest>=8``.
Other Improvements
^^^^^^^^^^^^^^^^^^
- `#11216 <https://github.com/pytest-dev/pytest/issues/11216>`_: If a test is skipped from inside an :ref:`xunit setup fixture <classic xunit>`, the test summary now shows the test location instead of the fixture location.
- `#11314 <https://github.com/pytest-dev/pytest/issues/11314>`_: Logging to a file using the ``--log-file`` option will use ``--log-level``, ``--log-format`` and ``--log-date-format`` as fallback
if ``--log-file-level``, ``--log-file-format`` and ``--log-file-date-format`` are not provided respectively.
- `#11610 <https://github.com/pytest-dev/pytest/issues/11610>`_: Added the :func:`LogCaptureFixture.filtering() <pytest.LogCaptureFixture.filtering>` context manager which
adds a given :class:`logging.Filter` object to the :fixture:`caplog` fixture.
- `#11447 <https://github.com/pytest-dev/pytest/issues/11447>`_: :func:`pytest.deprecated_call` now also considers warnings of type :class:`FutureWarning`.
- `#11600 <https://github.com/pytest-dev/pytest/issues/11600>`_: Improved the documentation and type signature for :func:`pytest.mark.xfail <pytest.mark.xfail>`'s ``condition`` param to use ``False`` as the default value.
- `#7469 <https://github.com/pytest-dev/pytest/issues/7469>`_: :class:`~pytest.FixtureDef` is now exported as ``pytest.FixtureDef`` for typing purposes.
- `#11353 <https://github.com/pytest-dev/pytest/issues/11353>`_: Added typing to :class:`~pytest.PytestPluginManager`.
Bug Fixes
---------
- `#10701 <https://github.com/pytest-dev/pytest/issues/10701>`_: :meth:`pytest.WarningsRecorder.pop` will return the most-closely-matched warning in the list,
rather than the first warning which is an instance of the requested type.
- `#11255 <https://github.com/pytest-dev/pytest/issues/11255>`_: Fixed crash on `parametrize(..., scope="package")` without a package present.
- `#11277 <https://github.com/pytest-dev/pytest/issues/11277>`_: Fixed a bug that when there are multiple fixtures for an indirect parameter,
the scope of the highest-scope fixture is picked for the parameter set, instead of that of the one with the narrowest scope.
- `#11456 <https://github.com/pytest-dev/pytest/issues/11456>`_: Parametrized tests now *really do* ensure that the ids given to each input are unique - for
example, ``a, a, a0`` now results in ``a1, a2, a0`` instead of the previous (buggy) ``a0, a1, a0``.
This necessarily means changing nodeids where these were previously colliding, and for
readability adds an underscore when non-unique ids end in a number.
- `#11563 <https://github.com/pytest-dev/pytest/issues/11563>`_: Fixed a crash when using an empty string for the same parametrized value more than once.
- `#11712 <https://github.com/pytest-dev/pytest/issues/11712>`_: Fixed handling ``NO_COLOR`` and ``FORCE_COLOR`` to ignore an empty value.
- `#9036 <https://github.com/pytest-dev/pytest/issues/9036>`_: ``pytest.warns`` and similar functions now capture warnings when an exception is raised inside a ``with`` block.
Improved Documentation
----------------------
- `#11011 <https://github.com/pytest-dev/pytest/issues/11011>`_: Added a warning about modifying the root logger during tests when using ``caplog``.
- `#11065 <https://github.com/pytest-dev/pytest/issues/11065>`_: Use ``pytestconfig`` instead of ``request.config`` in cache example to be consistent with the API documentation.
Trivial/Internal Changes
------------------------
- `#11208 <https://github.com/pytest-dev/pytest/issues/11208>`_: The (internal) ``FixtureDef.cached_result`` type has changed.
Now the third item ``cached_result[2]``, when set, is an exception instance instead of an exception triplet.
- `#11218 <https://github.com/pytest-dev/pytest/issues/11218>`_: (This entry is meant to assist plugins which access private pytest internals to instantiate ``FixtureRequest`` objects.)
:class:`~pytest.FixtureRequest` is now an abstract class which can't be instantiated directly.
A new concrete ``TopRequest`` subclass of ``FixtureRequest`` has been added for the ``request`` fixture in test functions,
as counterpart to the existing ``SubRequest`` subclass for the ``request`` fixture in fixture functions.
- `#11315 <https://github.com/pytest-dev/pytest/issues/11315>`_: The :fixture:`pytester` fixture now uses the :fixture:`monkeypatch` fixture to manage the current working directory.
If you use ``pytester`` in combination with :func:`monkeypatch.undo() <pytest.MonkeyPatch.undo>`, the CWD might get restored.
Use :func:`monkeypatch.context() <pytest.MonkeyPatch.context>` instead.
- `#11333 <https://github.com/pytest-dev/pytest/issues/11333>`_: Corrected the spelling of ``Config.ArgsSource.INVOCATION_DIR``.
The previous spelling ``INCOVATION_DIR`` remains as an alias.
- `#11638 <https://github.com/pytest-dev/pytest/issues/11638>`_: Fixed the selftests to pass correctly if ``FORCE_COLOR``, ``NO_COLOR`` or ``PY_COLORS`` is set in the calling environment.
pytest 7.4.4 (2023-12-31)
=========================
Bug Fixes
---------
- `#11140 <https://github.com/pytest-dev/pytest/issues/11140>`_: Fix non-string constants at the top of file being detected as docstrings on Python>=3.8.
- `#11572 <https://github.com/pytest-dev/pytest/issues/11572>`_: Handle an edge case where :data:`sys.stderr` and :data:`sys.__stderr__` might already be closed when :ref:`faulthandler` is tearing down.
- `#11710 <https://github.com/pytest-dev/pytest/issues/11710>`_: Fixed tracebacks from collection errors not getting pruned.
- `#7966 <https://github.com/pytest-dev/pytest/issues/7966>`_: Removed unhelpful error message from assertion rewrite mechanism when exceptions are raised in ``__iter__`` methods. Now they are treated un-iterable instead.
Improved Documentation
----------------------
- `#11091 <https://github.com/pytest-dev/pytest/issues/11091>`_: Updated documentation to refer to hyphenated options: replaced ``--junitxml`` with ``--junit-xml`` and ``--collectonly`` with ``--collect-only``.
pytest 7.4.3 (2023-10-24)
=========================
Bug Fixes
---------
- `#10447 <https://github.com/pytest-dev/pytest/issues/10447>`_: Markers are now considered in the reverse mro order to ensure base class markers are considered first -- this resolves a regression.
- `#11239 <https://github.com/pytest-dev/pytest/issues/11239>`_: Fixed ``:=`` in asserts impacting unrelated test cases.
- `#11439 <https://github.com/pytest-dev/pytest/issues/11439>`_: Handled an edge case where :data:`sys.stderr` might already be closed when :ref:`faulthandler` is tearing down.
pytest 7.4.2 (2023-09-07)
=========================
Bug Fixes
---------
- `#11237 <https://github.com/pytest-dev/pytest/issues/11237>`_: Fix doctest collection of `functools.cached_property` objects.
- `#11306 <https://github.com/pytest-dev/pytest/issues/11306>`_: Fixed bug using ``--importmode=importlib`` which would cause package ``__init__.py`` files to be imported more than once in some cases.
- `#11367 <https://github.com/pytest-dev/pytest/issues/11367>`_: Fixed bug where `user_properties` where not being saved in the JUnit XML file if a fixture failed during teardown.
- `#11394 <https://github.com/pytest-dev/pytest/issues/11394>`_: Fixed crash when parsing long command line arguments that might be interpreted as files.
Improved Documentation
----------------------
- `#11391 <https://github.com/pytest-dev/pytest/issues/11391>`_: Improved disclaimer on pytest plugin reference page to better indicate this is an automated, non-curated listing.
pytest 7.4.1 (2023-09-02)
=========================
Bug Fixes
---------
- `#10337 <https://github.com/pytest-dev/pytest/issues/10337>`_: Fixed bug where fake intermediate modules generated by ``--import-mode=importlib`` would not include the
child modules as attributes of the parent modules.
- `#10702 <https://github.com/pytest-dev/pytest/issues/10702>`_: Fixed error assertion handling in :func:`pytest.approx` when ``None`` is an expected or received value when comparing dictionaries.
- `#10811 <https://github.com/pytest-dev/pytest/issues/10811>`_: Fixed issue when using ``--import-mode=importlib`` together with ``--doctest-modules`` that caused modules
to be imported more than once, causing problems with modules that have import side effects.
pytest 7.4.0 (2023-06-23)
=========================
@@ -356,7 +1108,7 @@ Improvements
- `#8508 <https://github.com/pytest-dev/pytest/issues/8508>`_: Introduce multiline display for warning matching via :py:func:`pytest.warns` and
enhance match comparison for :py:func:`_pytest._code.ExceptionInfo.match` as returned by :py:func:`pytest.raises`.
enhance match comparison for :py:func:`pytest.ExceptionInfo.match` as returned by :py:func:`pytest.raises`.
- `#8646 <https://github.com/pytest-dev/pytest/issues/8646>`_: Improve :py:func:`pytest.raises`. Previously passing an empty tuple would give a confusing
@@ -365,7 +1117,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.
`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``.
@@ -400,7 +1152,7 @@ Bug Fixes
When inheriting marks from super-classes, marks from the sub-classes are now ordered before marks from the super-classes, in MRO order. Previously it was the reverse.
When inheriting marks from super-classes, the `pytestmark` attribute of the sub-class now only contains the marks directly applied to it. Previously, it also contained marks from its super-classes. Please note that this attribute should not normally be accessed directly; use :func:`pytest.Node.iter_markers` instead.
When inheriting marks from super-classes, the `pytestmark` attribute of the sub-class now only contains the marks directly applied to it. Previously, it also contained marks from its super-classes. Please note that this attribute should not normally be accessed directly; use :func:`Node.iter_markers <_pytest.nodes.Node.iter_markers>` instead.
- `#9159 <https://github.com/pytest-dev/pytest/issues/9159>`_: Showing inner exceptions by forcing native display in ``ExceptionGroups`` even when using display options other than ``--tb=native``. A temporary step before full implementation of pytest-native display for inner exceptions in ``ExceptionGroups``.
@@ -653,7 +1405,7 @@ Bug Fixes
- `#9355 <https://github.com/pytest-dev/pytest/issues/9355>`_: Fixed error message prints function decorators when using assert in Python 3.8 and above.
- `#9396 <https://github.com/pytest-dev/pytest/issues/9396>`_: Ensure :attr:`pytest.Config.inifile` is available during the :func:`pytest_cmdline_main <_pytest.hookspec.pytest_cmdline_main>` hook (regression during ``7.0.0rc1``).
- `#9396 <https://github.com/pytest-dev/pytest/issues/9396>`_: Ensure `pytest.Config.inifile` is available during the :hook:`pytest_cmdline_main` hook (regression during ``7.0.0rc1``).
@@ -798,13 +1550,13 @@ Deprecations
- ``parser.addoption(..., type="int/string/float/complex")`` - use ``type=int`` etc. instead.
- `#8447 <https://github.com/pytest-dev/pytest/issues/8447>`_: Defining a custom pytest node type which is both an :class:`pytest.Item <Item>` and a :class:`pytest.Collector <Collector>` (e.g. :class:`pytest.File <File>`) now issues a warning.
- `#8447 <https://github.com/pytest-dev/pytest/issues/8447>`_: Defining a custom pytest node type which is both an :class:`~pytest.Item` and a :class:`~pytest.Collector` (e.g. :class:`~pytest.File`) now issues a warning.
It was never sanely supported and triggers hard to debug errors.
See :ref:`the deprecation note <diamond-inheritance-deprecated>` for full details.
- `#8592 <https://github.com/pytest-dev/pytest/issues/8592>`_: :hook:`pytest_cmdline_preparse` has been officially deprecated. It will be removed in a future release. Use :hook:`pytest_load_initial_conftests` instead.
- `#8592 <https://github.com/pytest-dev/pytest/issues/8592>`_: ``pytest_cmdline_preparse`` has been officially deprecated. It will be removed in a future release. Use :hook:`pytest_load_initial_conftests` instead.
See :ref:`the deprecation note <cmdline-preparse-deprecated>` for full details.
@@ -840,7 +1592,7 @@ Features
- `#7132 <https://github.com/pytest-dev/pytest/issues/7132>`_: Added two environment variables :envvar:`PYTEST_THEME` and :envvar:`PYTEST_THEME_MODE` to let the users customize the pygments theme used.
- `#7259 <https://github.com/pytest-dev/pytest/issues/7259>`_: Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing :meth:`cache.makedir() <pytest.Cache.makedir>`,
- `#7259 <https://github.com/pytest-dev/pytest/issues/7259>`_: Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing ``cache.makedir()``,
but returns a :class:`pathlib.Path` instead of a legacy ``py.path.local``.
Added a ``paths`` type to :meth:`parser.addini() <pytest.Parser.addini>`,
@@ -866,7 +1618,7 @@ Features
- ``pytest.HookRecorder`` for the :class:`HookRecorder <pytest.HookRecorder>` type returned from :class:`~pytest.Pytester`.
- ``pytest.RecordedHookCall`` for the :class:`RecordedHookCall <pytest.HookRecorder>` type returned from :class:`~pytest.HookRecorder`.
- ``pytest.RunResult`` for the :class:`RunResult <pytest.RunResult>` type returned from :class:`~pytest.Pytester`.
- ``pytest.LineMatcher`` for the :class:`LineMatcher <pytest.RunResult>` type used in :class:`~pytest.RunResult` and others.
- ``pytest.LineMatcher`` for the :class:`LineMatcher <pytest.LineMatcher>` type used in :class:`~pytest.RunResult` and others.
- ``pytest.TestReport`` for the :class:`TestReport <pytest.TestReport>` type used in various hooks.
- ``pytest.CollectReport`` for the :class:`CollectReport <pytest.CollectReport>` type used in various hooks.
@@ -899,7 +1651,7 @@ Features
- `#8251 <https://github.com/pytest-dev/pytest/issues/8251>`_: Implement ``Node.path`` as a ``pathlib.Path``. Both the old ``fspath`` and this new attribute gets set no matter whether ``path`` or ``fspath`` (deprecated) is passed to the constructor. It is a replacement for the ``fspath`` attribute (which represents the same path as ``py.path.local``). While ``fspath`` is not deprecated yet
due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo`, we expect to deprecate it in a future release.
due to the ongoing migration of methods like :meth:`~pytest.Item.reportinfo`, we expect to deprecate it in a future release.
.. note::
The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the
@@ -931,7 +1683,7 @@ Features
See :ref:`plugin-stash` for details.
- `#8953 <https://github.com/pytest-dev/pytest/issues/8953>`_: :class:`RunResult <_pytest.pytester.RunResult>` method :meth:`assert_outcomes <_pytest.pytester.RunResult.assert_outcomes>` now accepts a
- `#8953 <https://github.com/pytest-dev/pytest/issues/8953>`_: :class:`~pytest.RunResult` method :meth:`~pytest.RunResult.assert_outcomes` now accepts a
``warnings`` argument to assert the total number of warnings captured.
@@ -943,7 +1695,7 @@ Features
used.
- `#9113 <https://github.com/pytest-dev/pytest/issues/9113>`_: :class:`RunResult <_pytest.pytester.RunResult>` method :meth:`assert_outcomes <_pytest.pytester.RunResult.assert_outcomes>` now accepts a
- `#9113 <https://github.com/pytest-dev/pytest/issues/9113>`_: :class:`~pytest.RunResult` method :meth:`~pytest.RunResult.assert_outcomes` now accepts a
``deselected`` argument to assert the total number of deselected tests.
@@ -956,7 +1708,7 @@ Improvements
- `#7480 <https://github.com/pytest-dev/pytest/issues/7480>`_: A deprecation scheduled to be removed in a major version X (e.g. pytest 7, 8, 9, ...) now uses warning category `PytestRemovedInXWarning`,
a subclass of :class:`~pytest.PytestDeprecationWarning`,
instead of :class:`PytestDeprecationWarning` directly.
instead of :class:`~pytest.PytestDeprecationWarning` directly.
See :ref:`backwards-compatibility` for more details.
@@ -995,7 +1747,7 @@ Improvements
- `#8803 <https://github.com/pytest-dev/pytest/issues/8803>`_: It is now possible to add colors to custom log levels on cli log.
By using :func:`add_color_level <_pytest.logging.add_color_level>` from a ``pytest_configure`` hook, colors can be added::
By using ``add_color_level`` from a :hook:`pytest_configure` hook, colors can be added::
logging_plugin = config.pluginmanager.get_plugin('logging-plugin')
logging_plugin.log_cli_handler.formatter.add_color_level(logging.INFO, 'cyan')
@@ -1060,7 +1812,7 @@ Bug Fixes
- `#8503 <https://github.com/pytest-dev/pytest/issues/8503>`_: :meth:`pytest.MonkeyPatch.syspath_prepend` no longer fails when
``setuptools`` is not installed.
It now only calls :func:`pkg_resources.fixup_namespace_packages` if
It now only calls ``pkg_resources.fixup_namespace_packages`` if
``pkg_resources`` was previously imported, because it is not needed otherwise.
@@ -1287,7 +2039,7 @@ Features
This is part of the movement to use :class:`pathlib.Path` objects internally, in order to remove the dependency to ``py`` in the future.
Internally, the old :class:`Testdir <_pytest.pytester.Testdir>` is now a thin wrapper around :class:`Pytester <_pytest.pytester.Pytester>`, preserving the old interface.
Internally, the old ``pytest.Testdir`` is now a thin wrapper around :class:`~pytest.Pytester`, preserving the old interface.
- :issue:`7695`: A new hook was added, `pytest_markeval_namespace` which should return a dictionary.
@@ -1325,7 +2077,7 @@ Features
Improvements
------------
- :issue:`1265`: Added an ``__str__`` implementation to the :class:`~pytest.pytester.LineMatcher` class which is returned from ``pytester.run_pytest().stdout`` and similar. It returns the entire output, like the existing ``str()`` method.
- :issue:`1265`: Added an ``__str__`` implementation to the :class:`~pytest.LineMatcher` class which is returned from ``pytester.run_pytest().stdout`` and similar. It returns the entire output, like the existing ``str()`` method.
- :issue:`2044`: Verbose mode now shows the reason that a test was skipped in the test's terminal line after the "SKIPPED", "XFAIL" or "XPASS".
@@ -1389,7 +2141,7 @@ Bug Fixes
- :issue:`7911`: Directories created by by :fixture:`tmp_path` and :fixture:`tmpdir` are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites.
- :issue:`7913`: Fixed a crash or hang in :meth:`pytester.spawn <_pytest.pytester.Pytester.spawn>` when the :mod:`readline` module is involved.
- :issue:`7913`: Fixed a crash or hang in :meth:`pytester.spawn <pytest.Pytester.spawn>` when the :mod:`readline` module is involved.
- :issue:`7951`: Fixed handling of recursive symlinks when collecting tests.
@@ -1506,7 +2258,7 @@ Deprecations
if you use this and want a replacement.
- :issue:`7255`: The :hook:`pytest_warning_captured` hook is deprecated in favor
- :issue:`7255`: The ``pytest_warning_captured`` hook is deprecated in favor
of :hook:`pytest_warning_recorded`, and will be removed in a future version.
@@ -1534,8 +2286,8 @@ Improvements
- :issue:`7572`: When a plugin listed in ``required_plugins`` is missing or an unknown config key is used with ``--strict-config``, a simple error message is now shown instead of a stacktrace.
- :issue:`7685`: Added two new attributes :attr:`rootpath <_pytest.config.Config.rootpath>` and :attr:`inipath <_pytest.config.Config.inipath>` to :class:`Config <_pytest.config.Config>`.
These attributes are :class:`pathlib.Path` versions of the existing :attr:`rootdir <_pytest.config.Config.rootdir>` and :attr:`inifile <_pytest.config.Config.inifile>` attributes,
- :issue:`7685`: Added two new attributes :attr:`rootpath <pytest.Config.rootpath>` and :attr:`inipath <pytest.Config.inipath>` to :class:`~pytest.Config`.
These attributes are :class:`pathlib.Path` versions of the existing ``rootdir`` and ``inifile`` attributes,
and should be preferred over them when possible.
@@ -1606,7 +2358,7 @@ Trivial/Internal Changes
- :issue:`7587`: The dependency on the ``more-itertools`` package has been removed.
- :issue:`7631`: The result type of :meth:`capfd.readouterr() <_pytest.capture.CaptureFixture.readouterr>` (and similar) is no longer a namedtuple,
- :issue:`7631`: The result type of :meth:`capfd.readouterr() <pytest.CaptureFixture.readouterr>` (and similar) is no longer a namedtuple,
but should behave like one in all respects. This was done for technical reasons.
@@ -1984,10 +2736,10 @@ Improvements
- :issue:`7128`: `pytest --version` now displays just the pytest version, while `pytest --version --version` displays more verbose information including plugins. This is more consistent with how other tools show `--version`.
- :issue:`7133`: :meth:`caplog.set_level() <_pytest.logging.LogCaptureFixture.set_level>` will now override any :confval:`log_level` set via the CLI or configuration file.
- :issue:`7133`: :meth:`caplog.set_level() <pytest.LogCaptureFixture.set_level>` will now override any :confval:`log_level` set via the CLI or configuration file.
- :issue:`7159`: :meth:`caplog.set_level() <_pytest.logging.LogCaptureFixture.set_level>` and :meth:`caplog.at_level() <_pytest.logging.LogCaptureFixture.at_level>` no longer affect
- :issue:`7159`: :meth:`caplog.set_level() <pytest.LogCaptureFixture.set_level>` and :meth:`caplog.at_level() <pytest.LogCaptureFixture.at_level>` no longer affect
the level of logs that are shown in the *Captured log report* report section.
@@ -2082,7 +2834,7 @@ Bug Fixes
parameter when Python is called with the ``-bb`` flag.
- :issue:`7143`: Fix :meth:`pytest.File.from_parent` so it forwards extra keyword arguments to the constructor.
- :issue:`7143`: Fix :meth:`pytest.File.from_parent <_pytest.nodes.Node.from_parent>` so it forwards extra keyword arguments to the constructor.
- :issue:`7145`: Classes with broken ``__getattribute__`` methods are displayed correctly during failures.
@@ -2333,7 +3085,7 @@ Improvements
- :issue:`6384`: Make `--showlocals` work also with `--tb=short`.
- :issue:`6653`: Add support for matching lines consecutively with :attr:`LineMatcher <_pytest.pytester.LineMatcher>`'s :func:`~_pytest.pytester.LineMatcher.fnmatch_lines` and :func:`~_pytest.pytester.LineMatcher.re_match_lines`.
- :issue:`6653`: Add support for matching lines consecutively with :class:`~pytest.LineMatcher`'s :func:`~pytest.LineMatcher.fnmatch_lines` and :func:`~pytest.LineMatcher.re_match_lines`.
- :issue:`6658`: Code is now highlighted in tracebacks when ``pygments`` is installed.
@@ -2401,7 +3153,7 @@ Bug Fixes
- :issue:`6597`: Fix node ids which contain a parametrized empty-string variable.
- :issue:`6646`: Assertion rewriting hooks are (re)stored for the current item, which fixes them being still used after e.g. pytester's :func:`testdir.runpytest <_pytest.pytester.Testdir.runpytest>` etc.
- :issue:`6646`: Assertion rewriting hooks are (re)stored for the current item, which fixes them being still used after e.g. pytester's ``testdir.runpytest`` etc.
- :issue:`6660`: :py:func:`pytest.exit` is handled when emitted from the :hook:`pytest_sessionfinish` hook. This includes quitting from a debugger.
@@ -2467,7 +3219,7 @@ Bug Fixes
``multiprocessing`` module.
- :issue:`6436`: :class:`FixtureDef <_pytest.fixtures.FixtureDef>` objects now properly register their finalizers with autouse and
- :issue:`6436`: :class:`~pytest.FixtureDef` objects now properly register their finalizers with autouse and
parameterized fixtures that execute before them in the fixture stack so they are torn
down at the right times, and in the right order.
@@ -2523,7 +3275,7 @@ Improvements
Bug Fixes
---------
- :issue:`5914`: pytester: fix :py:func:`~_pytest.pytester.LineMatcher.no_fnmatch_line` when used after positive matching.
- :issue:`5914`: pytester: fix :py:func:`~pytest.LineMatcher.no_fnmatch_line` when used after positive matching.
- :issue:`6082`: Fix line detection for doctest samples inside :py:class:`python:property` docstrings, as a workaround to :bpo:`17446`.
@@ -2587,8 +3339,8 @@ Features
rather than implicitly.
- :issue:`5914`: :fixture:`testdir` learned two new functions, :py:func:`~_pytest.pytester.LineMatcher.no_fnmatch_line` and
:py:func:`~_pytest.pytester.LineMatcher.no_re_match_line`.
- :issue:`5914`: :fixture:`testdir` learned two new functions, :py:func:`~pytest.LineMatcher.no_fnmatch_line` and
:py:func:`~pytest.LineMatcher.no_re_match_line`.
The functions are used to ensure the captured text *does not* match the given
pattern.
@@ -6440,7 +7192,7 @@ Changes
* fix :issue:`2013`: turn RecordedWarning into ``namedtuple``,
to give it a comprehensible repr while preventing unwarranted modification.
* fix :issue:`2208`: ensure an iteration limit for _pytest.compat.get_real_func.
* fix :issue:`2208`: ensure an iteration limit for ``_pytest.compat.get_real_func``.
Thanks :user:`RonnyPfannschmidt` for the report and PR.
* Hooks are now verified after collection is complete, rather than right after loading installed plugins. This

View File

@@ -15,16 +15,15 @@
#
# The full version, including alpha/beta/rc tags.
# The short X.Y version.
import ast
import os
import shutil
import sys
from textwrap import dedent
from typing import List
from typing import TYPE_CHECKING
from _pytest import __version__ as version
if TYPE_CHECKING:
import sphinx.application
@@ -171,6 +170,50 @@ extlinks = {
}
nitpicky = True
nitpick_ignore = [
# TODO (fix in pluggy?)
("py:class", "HookCaller"),
("py:class", "HookspecMarker"),
("py:exc", "PluginValidationError"),
# Might want to expose/TODO (https://github.com/pytest-dev/pytest/issues/7469)
("py:class", "ExceptionRepr"),
("py:class", "Exit"),
("py:class", "SubRequest"),
("py:class", "SubRequest"),
("py:class", "TerminalReporter"),
("py:class", "_pytest._code.code.TerminalRepr"),
("py:class", "_pytest.fixtures.FixtureFunctionMarker"),
("py:class", "_pytest.logging.LogCaptureHandler"),
("py:class", "_pytest.mark.structures.ParameterSet"),
# Intentionally undocumented/private
("py:class", "_pytest._code.code.Traceback"),
("py:class", "_pytest._py.path.LocalPath"),
("py:class", "_pytest.capture.CaptureResult"),
("py:class", "_pytest.compat.NotSetType"),
("py:class", "_pytest.python.PyCollector"),
("py:class", "_pytest.python.PyobjMixin"),
("py:class", "_pytest.python_api.RaisesContext"),
("py:class", "_pytest.recwarn.WarningsChecker"),
("py:class", "_pytest.reports.BaseReport"),
# Undocumented third parties
("py:class", "_tracing.TagTracerSub"),
("py:class", "warnings.WarningMessage"),
# Undocumented type aliases
("py:class", "LEGACY_PATH"),
("py:class", "_PluggyPlugin"),
# TypeVars
("py:class", "_pytest._code.code.E"),
("py:class", "_pytest.fixtures.FixtureFunction"),
("py:class", "_pytest.nodes._NodeType"),
("py:class", "_pytest.python_api.E"),
("py:class", "_pytest.recwarn.T"),
("py:class", "_pytest.runner.TResult"),
("py:obj", "_pytest.fixtures.FixtureValue"),
("py:obj", "_pytest.stash.T"),
]
# -- Options for HTML output ---------------------------------------------------
sys.path.append(os.path.abspath("_themes"))
@@ -352,7 +395,7 @@ epub_copyright = "2013, holger krekel et alii"
# The format is a list of tuples containing the path and title.
# epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# HTML files that should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
# epub_post_files = []
@@ -399,9 +442,10 @@ intersphinx_mapping = {
def configure_logging(app: "sphinx.application.Sphinx") -> None:
"""Configure Sphinx's WarningHandler to handle (expected) missing include."""
import sphinx.util.logging
import logging
import sphinx.util.logging
class WarnLogFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
"""Ignore warnings about missing include with "only" directive.
@@ -451,25 +495,6 @@ def setup(app: "sphinx.application.Sphinx") -> None:
configure_logging(app)
# Make Sphinx mark classes with "final" when decorated with @final.
# We need this because we import final from pytest._compat, not from
# typing (for Python < 3.8 compat), so Sphinx doesn't detect it.
# To keep things simple we accept any `@final` decorator.
# Ref: https://github.com/pytest-dev/pytest/pull/7780
import sphinx.pycode.ast
import sphinx.pycode.parser
original_is_final = sphinx.pycode.parser.VariableCommentPicker.is_final
def patched_is_final(self, decorators: List[ast.expr]) -> bool:
if original_is_final(self, decorators):
return True
return any(
sphinx.pycode.ast.unparse(decorator) == "final" for decorator in decorators
)
sphinx.pycode.parser.VariableCommentPicker.is_final = patched_is_final
# legacypath.py monkey-patches pytest.Testdir in. Import the file so
# that autodoc can discover references to it.
import _pytest.legacypath # noqa: F401

View File

@@ -44,7 +44,6 @@ How-to guides
how-to/existingtestsuite
how-to/unittest
how-to/nose
how-to/xunit_setup
how-to/bash-completion

View File

@@ -19,129 +19,39 @@ Below is a complete list of all pytest features which are considered deprecated.
:class:`~pytest.PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters <warnings>`.
.. _nose-deprecation:
.. _import-or-skip-import-error:
Support for tests written for nose
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``pytest.importorskip`` default behavior regarding :class:`ImportError`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.2
.. deprecated:: 8.2
Support for running tests written for `nose <https://nose.readthedocs.io/en/latest/>`__ is now deprecated.
Traditionally :func:`pytest.importorskip` will capture :class:`ImportError`, with the original intent being to skip
tests where a dependent module is not installed, for example testing with different dependencies.
``nose`` has been in maintenance mode-only for years, and maintaining the plugin is not trivial as it spills
over the code base (see :issue:`9886` for more details).
However some packages might be installed in the system, but are not importable due to
some other issue, for example, a compilation error or a broken installation. In those cases :func:`pytest.importorskip`
would still silently skip the test, but more often than not users would like to see the unexpected
error so the underlying issue can be fixed.
setup/teardown
^^^^^^^^^^^^^^
In ``8.2`` the ``exc_type`` parameter has been added, giving users the ability of passing :class:`ModuleNotFoundError`
to skip tests only if the module cannot really be found, and not because of some other error.
One thing that might catch users by surprise is that plain ``setup`` and ``teardown`` methods are not pytest native,
they are in fact part of the ``nose`` support.
Catching only :class:`ModuleNotFoundError` by default (and letting other errors propagate) would be the best solution,
however for backward compatibility, pytest will keep the existing behavior but raise an warning if:
1. The captured exception is of type :class:`ImportError`, and:
2. The user does not pass ``exc_type`` explicitly.
.. code-block:: python
If the import attempt raises :class:`ModuleNotFoundError` (the usual case), then the module is skipped and no
warning is emitted.
class Test:
def setup(self):
self.resource = make_resource()
This way, the usual cases will keep working the same way, while unexpected errors will now issue a warning, with
users being able to supress the warning by passing ``exc_type=ImportError`` explicitly.
def teardown(self):
self.resource.close()
def test_foo(self):
...
def test_bar(self):
...
Native pytest support uses ``setup_method`` and ``teardown_method`` (see :ref:`xunit-method-setup`), so the above should be changed to:
.. code-block:: python
class Test:
def setup_method(self):
self.resource = make_resource()
def teardown_method(self):
self.resource.close()
def test_foo(self):
...
def test_bar(self):
...
This is easy to do in an entire code base by doing a simple find/replace.
@with_setup
^^^^^^^^^^^
Code using `@with_setup <with-setup-nose>`_ such as this:
.. code-block:: python
from nose.tools import with_setup
def setup_some_resource():
...
def teardown_some_resource():
...
@with_setup(setup_some_resource, teardown_some_resource)
def test_foo():
...
Will also need to be ported to a supported pytest style. One way to do it is using a fixture:
.. code-block:: python
import pytest
def setup_some_resource():
...
def teardown_some_resource():
...
@pytest.fixture
def some_resource():
setup_some_resource()
yield
teardown_some_resource()
def test_foo(some_resource):
...
.. _`with-setup-nose`: https://nose.readthedocs.io/en/latest/testing_tools.html?highlight=with_setup#nose.tools.with_setup
.. _instance-collector-deprecation:
The ``pytest.Instance`` collector
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionremoved:: 7.0
The ``pytest.Instance`` collector type has been removed.
Previously, Python test methods were collected as :class:`~pytest.Class` -> ``Instance`` -> :class:`~pytest.Function`.
Now :class:`~pytest.Class` collects the test methods directly.
Most plugins which reference ``Instance`` do so in order to ignore or skip it,
using a check such as ``if isinstance(node, Instance): return``.
Such plugins should simply remove consideration of ``Instance`` on pytest>=7.
However, to keep such uses working, a dummy type has been instanted in ``pytest.Instance`` and ``_pytest.python.Instance``,
and importing it emits a deprecation warning. This will be removed in pytest 8.
In ``9.0``, the warning will turn into an error, and in ``9.1`` :func:`pytest.importorskip` will only capture
:class:`ModuleNotFoundError` by default and no warnings will be issued anymore -- but users can still capture
:class:`ImportError` by passing it to ``exc_type``.
.. _node-ctor-fspath-deprecation:
@@ -177,13 +87,12 @@ arguments they only pass on to the superclass.
resolved in future versions as we slowly get rid of the :pypi:`py`
dependency (see :issue:`9283` for a longer discussion).
Due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo`
Due to the ongoing migration of methods like :meth:`~pytest.Item.reportinfo`
which still is expected to return a ``py.path.local`` object, nodes still have
both ``fspath`` (``py.path.local``) and ``path`` (``pathlib.Path``) attributes,
no matter what argument was used in the constructor. We expect to deprecate the
``fspath`` attribute in a future release.
.. _legacy-path-hooks-deprecated:
Configuring hook specs/impls using markers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -197,13 +106,11 @@ have been available since years and should be used instead.
.. code-block:: python
@pytest.mark.tryfirst
def pytest_runtest_call():
...
def pytest_runtest_call(): ...
# or
def pytest_runtest_call():
...
def pytest_runtest_call(): ...
pytest_runtest_call.tryfirst = True
@@ -213,8 +120,7 @@ should be changed to:
.. code-block:: python
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_call():
...
def pytest_runtest_call(): ...
Changed ``hookimpl`` attributes:
@@ -229,6 +135,8 @@ Changed ``hookwrapper`` attributes:
* ``historic``
.. _legacy-path-hooks-deprecated:
``py.path.local`` arguments for hooks replaced with ``pathlib.Path``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -273,62 +181,6 @@ Directly constructing the following classes is now deprecated:
These constructors have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 8.
.. _cmdline-preparse-deprecated:
Passing ``msg=`` to ``pytest.skip``, ``pytest.fail`` or ``pytest.exit``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.0
Passing the keyword argument ``msg`` to :func:`pytest.skip`, :func:`pytest.fail` or :func:`pytest.exit`
is now deprecated and ``reason`` should be used instead. This change is to bring consistency between these
functions and the ``@pytest.mark.skip`` and ``@pytest.mark.xfail`` markers which already accept a ``reason`` argument.
.. code-block:: python
def test_fail_example():
# old
pytest.fail(msg="foo")
# new
pytest.fail(reason="bar")
def test_skip_example():
# old
pytest.skip(msg="foo")
# new
pytest.skip(reason="bar")
def test_exit_example():
# old
pytest.exit(msg="foo")
# new
pytest.exit(reason="bar")
Implementing the ``pytest_cmdline_preparse`` hook
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.0
Implementing the :hook:`pytest_cmdline_preparse` hook has been officially deprecated.
Implement the :hook:`pytest_load_initial_conftests` hook instead.
.. code-block:: python
def pytest_cmdline_preparse(config: Config, args: List[str]) -> None:
...
# becomes:
def pytest_load_initial_conftests(
early_config: Config, parser: Parser, args: List[str]
) -> None:
...
.. _diamond-inheritance-deprecated:
Diamond inheritance between :class:`pytest.Collector` and :class:`pytest.Item`
@@ -336,7 +188,7 @@ Diamond inheritance between :class:`pytest.Collector` and :class:`pytest.Item`
.. deprecated:: 7.0
Defining a custom pytest node type which is both an :class:`pytest.Item <Item>` and a :class:`pytest.Collector <Collector>` (e.g. :class:`pytest.File <File>`) now issues a warning.
Defining a custom pytest node type which is both an :class:`~pytest.Item` and a :class:`~pytest.Collector` (e.g. :class:`~pytest.File`) now issues a warning.
It was never sanely supported and triggers hard to debug errors.
Some plugins providing linting/code analysis have been using this as a hack.
@@ -348,8 +200,8 @@ Instead, a separate collector node should be used, which collects the item. See
.. _uncooperative-constructors-deprecated:
Constructors of custom :class:`pytest.Node` subclasses should take ``**kwargs``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Constructors of custom :class:`~_pytest.nodes.Node` subclasses should take ``**kwargs``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.0
@@ -380,28 +232,22 @@ conflicts (such as :class:`pytest.File` now taking ``path`` instead of
``fspath``, as :ref:`outlined above <node-ctor-fspath-deprecation>`), a
deprecation warning is now raised.
Backward compatibilities in ``Parser.addoption``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Applying a mark to a fixture function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 2.4
.. deprecated:: 7.4
Several behaviors of :meth:`Parser.addoption <pytest.Parser.addoption>` are now
scheduled for removal in pytest 8 (deprecated since pytest 2.4.0):
Applying a mark to a fixture function never had any effect, but it is a common user error.
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
- ``parser.addoption(..., type="int/string/float/complex")`` - use ``type=int`` etc. instead.
.. code-block:: python
@pytest.mark.usefixtures("clean_database")
@pytest.fixture
def user() -> User: ...
Using ``pytest.warns(None)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Users expected in this case that the ``usefixtures`` mark would have its intended effect of using the ``clean_database`` fixture when ``user`` was invoked, when in fact it has no effect at all.
.. deprecated:: 7.0
:func:`pytest.warns(None) <pytest.warns>` is now deprecated because it was frequently misused.
Its correct usage was checking that the code emits at least one warning of any type - like ``pytest.warns()``
or ``pytest.warns(Warning)``.
See :ref:`warns use cases` for examples.
Now pytest will issue a warning when it encounters this problem, and will raise an error in the future versions.
Returning non-None value in test functions
@@ -444,19 +290,6 @@ The proper fix is to change the `return` to an `assert`:
assert foo(a, b) == result
The ``--strict`` command-line option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 6.2
The ``--strict`` command-line option has been deprecated in favor of ``--strict-markers``, which
better conveys what the option does.
We have plans to maybe in the future to reintroduce ``--strict`` and make it an encompassing
flag for all strictness related options (``--strict-markers`` and ``--strict-config``
at the moment, more might be introduced in the future).
The ``yield_fixture`` function/decorator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -467,12 +300,348 @@ The ``yield_fixture`` function/decorator
It has been so for a very long time, so can be search/replaced safely.
Removed Features
----------------
Removed Features and Breaking Changes
-------------------------------------
As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after
an appropriate period of deprecation has passed.
Some breaking changes which could not be deprecated are also listed.
.. _nose-deprecation:
Support for tests written for nose
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.2
.. versionremoved:: 8.0
Support for running tests written for `nose <https://nose.readthedocs.io/en/latest/>`__ is now deprecated.
``nose`` has been in maintenance mode-only for years, and maintaining the plugin is not trivial as it spills
over the code base (see :issue:`9886` for more details).
setup/teardown
^^^^^^^^^^^^^^
One thing that might catch users by surprise is that plain ``setup`` and ``teardown`` methods are not pytest native,
they are in fact part of the ``nose`` support.
.. code-block:: python
class Test:
def setup(self):
self.resource = make_resource()
def teardown(self):
self.resource.close()
def test_foo(self): ...
def test_bar(self): ...
Native pytest support uses ``setup_method`` and ``teardown_method`` (see :ref:`xunit-method-setup`), so the above should be changed to:
.. code-block:: python
class Test:
def setup_method(self):
self.resource = make_resource()
def teardown_method(self):
self.resource.close()
def test_foo(self): ...
def test_bar(self): ...
This is easy to do in an entire code base by doing a simple find/replace.
@with_setup
^^^^^^^^^^^
Code using `@with_setup <with-setup-nose>`_ such as this:
.. code-block:: python
from nose.tools import with_setup
def setup_some_resource(): ...
def teardown_some_resource(): ...
@with_setup(setup_some_resource, teardown_some_resource)
def test_foo(): ...
Will also need to be ported to a supported pytest style. One way to do it is using a fixture:
.. code-block:: python
import pytest
def setup_some_resource(): ...
def teardown_some_resource(): ...
@pytest.fixture
def some_resource():
setup_some_resource()
yield
teardown_some_resource()
def test_foo(some_resource): ...
.. _`with-setup-nose`: https://nose.readthedocs.io/en/latest/testing_tools.html?highlight=with_setup#nose.tools.with_setup
The ``compat_co_firstlineno`` attribute
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Nose inspects this attribute on function objects to allow overriding the function's inferred line number.
Pytest no longer respects this attribute.
Passing ``msg=`` to ``pytest.skip``, ``pytest.fail`` or ``pytest.exit``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.0
.. versionremoved:: 8.0
Passing the keyword argument ``msg`` to :func:`pytest.skip`, :func:`pytest.fail` or :func:`pytest.exit`
is now deprecated and ``reason`` should be used instead. This change is to bring consistency between these
functions and the ``@pytest.mark.skip`` and ``@pytest.mark.xfail`` markers which already accept a ``reason`` argument.
.. code-block:: python
def test_fail_example():
# old
pytest.fail(msg="foo")
# new
pytest.fail(reason="bar")
def test_skip_example():
# old
pytest.skip(msg="foo")
# new
pytest.skip(reason="bar")
def test_exit_example():
# old
pytest.exit(msg="foo")
# new
pytest.exit(reason="bar")
.. _instance-collector-deprecation:
The ``pytest.Instance`` collector
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionremoved:: 7.0
The ``pytest.Instance`` collector type has been removed.
Previously, Python test methods were collected as :class:`~pytest.Class` -> ``Instance`` -> :class:`~pytest.Function`.
Now :class:`~pytest.Class` collects the test methods directly.
Most plugins which reference ``Instance`` do so in order to ignore or skip it,
using a check such as ``if isinstance(node, Instance): return``.
Such plugins should simply remove consideration of ``Instance`` on pytest>=7.
However, to keep such uses working, a dummy type has been instanted in ``pytest.Instance`` and ``_pytest.python.Instance``,
and importing it emits a deprecation warning. This was removed in pytest 8.
Using ``pytest.warns(None)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.0
.. versionremoved:: 8.0
:func:`pytest.warns(None) <pytest.warns>` is now deprecated because it was frequently misused.
Its correct usage was checking that the code emits at least one warning of any type - like ``pytest.warns()``
or ``pytest.warns(Warning)``.
See :ref:`warns use cases` for examples.
Backward compatibilities in ``Parser.addoption``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 2.4
.. versionremoved:: 8.0
Several behaviors of :meth:`Parser.addoption <pytest.Parser.addoption>` are now
removed in pytest 8 (deprecated since pytest 2.4.0):
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
- ``parser.addoption(..., type="int/string/float/complex")`` - use ``type=int`` etc. instead.
The ``--strict`` command-line option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 6.2
.. versionremoved:: 8.0
The ``--strict`` command-line option has been deprecated in favor of ``--strict-markers``, which
better conveys what the option does.
We have plans to maybe in the future to reintroduce ``--strict`` and make it an encompassing
flag for all strictness related options (``--strict-markers`` and ``--strict-config``
at the moment, more might be introduced in the future).
.. _cmdline-preparse-deprecated:
Implementing the ``pytest_cmdline_preparse`` hook
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 7.0
.. versionremoved:: 8.0
Implementing the ``pytest_cmdline_preparse`` hook has been officially deprecated.
Implement the :hook:`pytest_load_initial_conftests` hook instead.
.. code-block:: python
def pytest_cmdline_preparse(config: Config, args: List[str]) -> None: ...
# becomes:
def pytest_load_initial_conftests(
early_config: Config, parser: Parser, args: List[str]
) -> None: ...
Collection changes in pytest 8
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Added a new :class:`pytest.Directory` base collection node, which all collector nodes for filesystem directories are expected to subclass.
This is analogous to the existing :class:`pytest.File` for file nodes.
Changed :class:`pytest.Package` to be a subclass of :class:`pytest.Directory`.
A ``Package`` represents a filesystem directory which is a Python package,
i.e. contains an ``__init__.py`` file.
:class:`pytest.Package` now only collects files in its own directory; previously it collected recursively.
Sub-directories are collected as sub-collector nodes, thus creating a collection tree which mirrors the filesystem hierarchy.
:attr:`session.name <pytest.Session.name>` is now ``""``; previously it was the rootdir directory name.
This matches :attr:`session.nodeid <_pytest.nodes.Node.nodeid>` which has always been `""`.
Added a new :class:`pytest.Dir` concrete collection node, a subclass of :class:`pytest.Directory`.
This node represents a filesystem directory, which is not a :class:`pytest.Package`,
i.e. does not contain an ``__init__.py`` file.
Similarly to ``Package``, it only collects the files in its own directory,
while collecting sub-directories as sub-collector nodes.
Files and directories are now collected in alphabetical order jointly, unless changed by a plugin.
Previously, files were collected before directories.
The collection tree now contains directories/packages up to the :ref:`rootdir <rootdir>`,
for initial arguments that are found within the rootdir.
For files outside the rootdir, only the immediate directory/package is collected --
note however that collecting from outside the rootdir is discouraged.
As an example, given the following filesystem tree::
myroot/
pytest.ini
top/
├── aaa
│ └── test_aaa.py
├── test_a.py
├── test_b
│ ├── __init__.py
│ └── test_b.py
├── test_c.py
└── zzz
├── __init__.py
└── test_zzz.py
the collection tree, as shown by `pytest --collect-only top/` but with the otherwise-hidden :class:`~pytest.Session` node added for clarity,
is now the following::
<Session>
<Dir myroot>
<Dir top>
<Dir aaa>
<Module test_aaa.py>
<Function test_it>
<Module test_a.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Module test_c.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
Previously, it was::
<Session>
<Module top/test_a.py>
<Function test_it>
<Module top/test_c.py>
<Function test_it>
<Module top/aaa/test_aaa.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
Code/plugins which rely on a specific shape of the collection tree might need to update.
:class:`pytest.Package` is no longer a :class:`pytest.Module` or :class:`pytest.File`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionchanged:: 8.0
The ``Package`` collector node designates a Python package, that is, a directory with an `__init__.py` file.
Previously ``Package`` was a subtype of ``pytest.Module`` (which represents a single Python module),
the module being the `__init__.py` file.
This has been deemed a design mistake (see :issue:`11137` and :issue:`7777` for details).
The ``path`` property of ``Package`` nodes now points to the package directory instead of the ``__init__.py`` file.
Note that a ``Module`` node for ``__init__.py`` (which is not a ``Package``) may still exist,
if it is picked up during collection (e.g. if you configured :confval:`python_files` to include ``__init__.py`` files).
Collecting ``__init__.py`` files no longer collects package
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionremoved:: 8.0
Running `pytest pkg/__init__.py` now collects the `pkg/__init__.py` file (module) only.
Previously, it collected the entire `pkg` package, including other test files in the directory, but excluding tests in the `__init__.py` file itself
(unless :confval:`python_files` was changed to allow `__init__.py` file).
To collect the entire package, specify just the directory: `pytest pkg`.
The ``pytest.collect`` module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -596,7 +765,7 @@ By using ``legacy`` you will keep using the legacy/xunit1 format when upgrading
pytest 6.0, where the default format will be ``xunit2``.
In order to let users know about the transition, pytest will issue a warning in case
the ``--junitxml`` option is given in the command line but ``junit_family`` is not explicitly
the ``--junit-xml`` option is given in the command line but ``junit_family`` is not explicitly
configured in ``pytest.ini``.
Services known to support the ``xunit2`` format:
@@ -773,8 +942,7 @@ Applying marks to values of a ``pytest.mark.parametrize`` call is now deprecated
(50, 500),
],
)
def test_foo(a, b):
...
def test_foo(a, b): ...
This code applies the ``pytest.mark.xfail(reason="flaky")`` mark to the ``(6, 36)`` value of the above parametrization
call.
@@ -797,8 +965,7 @@ To update the code, use ``pytest.param``:
(50, 500),
],
)
def test_foo(a, b):
...
def test_foo(a, b): ...
.. _pytest_funcarg__ prefix deprecated:
@@ -949,15 +1116,13 @@ This is just a matter of renaming the fixture as the API is the same:
.. code-block:: python
def test_foo(record_xml_property):
...
def test_foo(record_xml_property): ...
Change to:
.. code-block:: python
def test_foo(record_property):
...
def test_foo(record_property): ...
.. _passing command-line string to pytest.main deprecated:
@@ -1119,8 +1284,7 @@ Example of usage:
.. code-block:: python
class MySymbol:
...
class MySymbol: ...
def pytest_namespace():

View File

@@ -172,7 +172,7 @@ class TestRaises:
raise ValueError("demo error")
def test_tupleerror(self):
a, b = [1] # NOQA
a, b = [1] # noqa: F841
def test_reinterpret_fails_with_print_for_the_fun_of_it(self):
items = [1, 2, 3]
@@ -180,7 +180,7 @@ class TestRaises:
a, b = items.pop()
def test_some_error(self):
if namenotexi: # NOQA
if namenotexi: # noqa: F821
pass
def func1(self):

View File

@@ -2,6 +2,7 @@ import os.path
import pytest
mydir = os.path.dirname(__file__)

View File

@@ -1,6 +1,7 @@
import os.path
import shutil
failure_demo = os.path.join(os.path.dirname(__file__), "failure_demo.py")
pytest_plugins = ("pytester",)

View File

@@ -1 +1 @@
collect_ignore = ["nonpython"]
collect_ignore = ["nonpython", "customdirectory"]

View File

@@ -0,0 +1,77 @@
.. _`custom directory collectors`:
Using a custom directory collector
====================================================
By default, pytest collects directories using :class:`pytest.Package`, for directories with ``__init__.py`` files,
and :class:`pytest.Dir` for other directories.
If you want to customize how a directory is collected, you can write your own :class:`pytest.Directory` collector,
and use :hook:`pytest_collect_directory` to hook it up.
.. _`directory manifest plugin`:
A basic example for a directory manifest file
--------------------------------------------------------------
Suppose you want to customize how collection is done on a per-directory basis.
Here is an example ``conftest.py`` plugin that allows directories to contain a ``manifest.json`` file,
which defines how the collection should be done for the directory.
In this example, only a simple list of files is supported,
however you can imagine adding other keys, such as exclusions and globs.
.. include:: customdirectory/conftest.py
:literal:
You can create a ``manifest.json`` file and some test files:
.. include:: customdirectory/tests/manifest.json
:literal:
.. include:: customdirectory/tests/test_first.py
:literal:
.. include:: customdirectory/tests/test_second.py
:literal:
.. include:: customdirectory/tests/test_third.py
:literal:
An you can now execute the test specification:
.. code-block:: pytest
customdirectory $ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/customdirectory
configfile: pytest.ini
collected 2 items
tests/test_first.py . [ 50%]
tests/test_second.py . [100%]
============================ 2 passed in 0.12s =============================
.. regendoc:wipe
Notice how ``test_three.py`` was not executed, because it is not listed in the manifest.
You can verify that your custom collector appears in the collection tree:
.. code-block:: pytest
customdirectory $ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/customdirectory
configfile: pytest.ini
collected 2 items
<Dir customdirectory>
<ManifestDirectory tests>
<Module test_first.py>
<Function test_1>
<Module test_second.py>
<Function test_2>
======================== 2 tests collected in 0.12s ========================

View File

@@ -0,0 +1,28 @@
# content of conftest.py
import json
import pytest
class ManifestDirectory(pytest.Directory):
def collect(self):
# The standard pytest behavior is to loop over all `test_*.py` files and
# call `pytest_collect_file` on each file. This collector instead reads
# the `manifest.json` file and only calls `pytest_collect_file` for the
# files defined there.
manifest_path = self.path / "manifest.json"
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
ihook = self.ihook
for file in manifest["files"]:
yield from ihook.pytest_collect_file(
file_path=self.path / file, parent=self
)
@pytest.hookimpl
def pytest_collect_directory(path, parent):
# Use our custom collector for directories containing a `mainfest.json` file.
if path.joinpath("manifest.json").is_file():
return ManifestDirectory.from_parent(parent=parent, path=path)
# Otherwise fallback to the standard behavior.
return None

View File

@@ -0,0 +1,6 @@
{
"files": [
"test_first.py",
"test_second.py"
]
}

View File

@@ -0,0 +1,3 @@
# content of test_first.py
def test_1():
pass

View File

@@ -0,0 +1,3 @@
# content of test_second.py
def test_2():
pass

View File

@@ -0,0 +1,3 @@
# content of test_third.py
def test_3():
pass

View File

@@ -18,7 +18,6 @@ For basic examples, see
- :ref:`Fixtures <fixtures>` for basic fixture/setup examples
- :ref:`parametrize` for basic test function parametrization
- :ref:`unittest` for basic unittest integration
- :ref:`noseintegration` for basic nosetests integration
The following examples aim at various use cases you might encounter.
@@ -32,3 +31,4 @@ The following examples aim at various use cases you might encounter.
special
pythoncollection
nonpython
customdirectory

View File

@@ -45,7 +45,7 @@ You can then restrict a test run to only run tests marked with ``webtest``:
$ pytest -v -m webtest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 4 items / 3 deselected / 1 selected
@@ -60,7 +60,7 @@ Or the inverse, running all tests except the webtest ones:
$ pytest -v -m "not webtest"
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 4 items / 1 deselected / 3 selected
@@ -82,7 +82,7 @@ tests based on their module, class, method, or function name:
$ pytest -v test_server.py::TestClass::test_method
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 1 item
@@ -97,7 +97,7 @@ You can also select on the class:
$ pytest -v test_server.py::TestClass
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 1 item
@@ -112,7 +112,7 @@ Or select multiple nodes:
$ pytest -v test_server.py::TestClass test_server.py::test_send_http
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 2 items
@@ -136,7 +136,7 @@ Or select multiple nodes:
Node IDs for failing tests are displayed in the test summary info
when running pytest with the ``-rf`` option. You can also
construct Node IDs from the output of ``pytest --collectonly``.
construct Node IDs from the output of ``pytest --collect-only``.
Using ``-k expr`` to select tests based on their name
-------------------------------------------------------
@@ -156,7 +156,7 @@ The expression matching is now case-insensitive.
$ pytest -v -k http # running with the above defined example module
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 4 items / 3 deselected / 1 selected
@@ -171,7 +171,7 @@ And you can also run all tests except the ones that match the keyword:
$ pytest -k "not send_http" -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 4 items / 1 deselected / 3 selected
@@ -188,7 +188,7 @@ Or to select "http" and "quick" tests:
$ pytest -k "http or quick" -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 4 items / 2 deselected / 2 selected
@@ -397,7 +397,7 @@ the test needs:
$ pytest -E stage2
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -411,7 +411,7 @@ and here is one that specifies exactly the environment needed:
$ pytest -E stage1
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -604,7 +604,7 @@ then you will see two tests skipped and two executed tests as expected:
$ pytest -rs # this option reports skip reasons
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items
@@ -620,7 +620,7 @@ Note that if you specify a platform via the marker-command line option like this
$ pytest -m linux
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items / 3 deselected / 1 selected
@@ -683,7 +683,7 @@ We can now use the ``-m option`` to select one set:
$ pytest -m interface --tb=short
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items / 2 deselected / 2 selected
@@ -709,7 +709,7 @@ or to select both "event" and "interface" tests:
$ pytest -m "interface or event" --tb=short
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items / 1 deselected / 3 selected

View File

@@ -1,14 +1,14 @@
"""
module containing a parametrized tests testing cross-python
serialization via the pickle module.
"""
"""Module containing a parametrized tests testing cross-python serialization
via the pickle module."""
import shutil
import subprocess
import textwrap
import pytest
pythonlist = ["python3.5", "python3.6", "python3.7"]
pythonlist = ["python3.9", "python3.10", "python3.11"]
@pytest.fixture(params=pythonlist)
@@ -33,37 +33,33 @@ class Python:
dumpfile = self.picklefile.with_name("dump.py")
dumpfile.write_text(
textwrap.dedent(
r"""
rf"""
import pickle
f = open({!r}, 'wb')
s = pickle.dump({!r}, f, protocol=2)
f = open({str(self.picklefile)!r}, 'wb')
s = pickle.dump({obj!r}, f, protocol=2)
f.close()
""".format(
str(self.picklefile), obj
)
"""
)
)
subprocess.check_call((self.pythonpath, str(dumpfile)))
subprocess.run((self.pythonpath, str(dumpfile)), check=True)
def load_and_is_true(self, expression):
loadfile = self.picklefile.with_name("load.py")
loadfile.write_text(
textwrap.dedent(
r"""
rf"""
import pickle
f = open({!r}, 'rb')
f = open({str(self.picklefile)!r}, 'rb')
obj = pickle.load(f)
f.close()
res = eval({!r})
res = eval({expression!r})
if not res:
raise SystemExit(1)
""".format(
str(self.picklefile), expression
)
"""
)
)
print(loadfile)
subprocess.check_call((self.pythonpath, str(loadfile)))
subprocess.run((self.pythonpath, str(loadfile)), check=True)
@pytest.mark.parametrize("obj", [42, {}, {1: 3}])

View File

@@ -28,7 +28,7 @@ now execute the test specification:
nonpython $ pytest test_simple.yaml
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/nonpython
collected 2 items
@@ -64,7 +64,7 @@ consulted when reporting in ``verbose`` mode:
nonpython $ pytest -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project/nonpython
collecting ... collected 2 items
@@ -90,7 +90,7 @@ interesting to just look at the collection tree:
nonpython $ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/nonpython
collected 2 items

View File

@@ -12,7 +12,7 @@ class YamlFile(pytest.File):
# We need a yaml parser, e.g. PyYAML.
import yaml
raw = yaml.safe_load(self.path.open())
raw = yaml.safe_load(self.path.open(encoding="utf-8"))
for name, spec in sorted(raw.items()):
yield YamlItem.from_parent(self, name=name, spec=spec)

View File

@@ -4,8 +4,6 @@
Parametrizing tests
=================================================
.. currentmodule:: _pytest.python
``pytest`` allows to easily parametrize test functions.
For basic docs, see :ref:`parametrize-basics`.
@@ -160,19 +158,20 @@ objects, they are still using the default pytest representation:
$ pytest test_time.py --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 8 items
<Module test_time.py>
<Function test_timedistance_v0[a0-b0-expected0]>
<Function test_timedistance_v0[a1-b1-expected1]>
<Function test_timedistance_v1[forward]>
<Function test_timedistance_v1[backward]>
<Function test_timedistance_v2[20011212-20011211-expected0]>
<Function test_timedistance_v2[20011211-20011212-expected1]>
<Function test_timedistance_v3[forward]>
<Function test_timedistance_v3[backward]>
<Dir parametrize.rst-198>
<Module test_time.py>
<Function test_timedistance_v0[a0-b0-expected0]>
<Function test_timedistance_v0[a1-b1-expected1]>
<Function test_timedistance_v1[forward]>
<Function test_timedistance_v1[backward]>
<Function test_timedistance_v2[20011212-20011211-expected0]>
<Function test_timedistance_v2[20011211-20011212-expected1]>
<Function test_timedistance_v3[forward]>
<Function test_timedistance_v3[backward]>
======================== 8 tests collected in 0.12s ========================
@@ -185,7 +184,7 @@ A quick port of "testscenarios"
Here is a quick port to run tests configured with :pypi:`testscenarios`,
an add-on from Robert Collins for the standard unittest framework. We
only have to work a bit to construct the correct arguments for pytest's
:py:func:`Metafunc.parametrize`:
:py:func:`Metafunc.parametrize <pytest.Metafunc.parametrize>`:
.. code-block:: python
@@ -222,7 +221,7 @@ this is a fully self-contained example which you can run with:
$ pytest test_scenarios.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items
@@ -236,16 +235,17 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
$ pytest --collect-only test_scenarios.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items
<Module test_scenarios.py>
<Class TestSampleWithScenarios>
<Function test_demo1[basic]>
<Function test_demo2[basic]>
<Function test_demo1[advanced]>
<Function test_demo2[advanced]>
<Dir parametrize.rst-198>
<Module test_scenarios.py>
<Class TestSampleWithScenarios>
<Function test_demo1[basic]>
<Function test_demo2[basic]>
<Function test_demo1[advanced]>
<Function test_demo2[advanced]>
======================== 4 tests collected in 0.12s ========================
@@ -314,13 +314,14 @@ Let's first see how it looks like at collection time:
$ pytest test_backends.py --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
<Module test_backends.py>
<Function test_db_initialized[d1]>
<Function test_db_initialized[d2]>
<Dir parametrize.rst-198>
<Module test_backends.py>
<Function test_db_initialized[d1]>
<Function test_db_initialized[d2]>
======================== 2 tests collected in 0.12s ========================
@@ -412,7 +413,7 @@ The result of this test will be successful:
$ pytest -v test_indirect_list.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 1 item
@@ -483,8 +484,8 @@ argument sets to use for each test function. Let's run it:
FAILED test_parametrize.py::TestClass::test_equals[1-2] - assert 1 == 2
1 failed, 2 passed in 0.12s
Indirect parametrization with multiple fixtures
--------------------------------------------------------------
Parametrization with multiple fixtures
--------------------------------------
Here is a stripped down real-life example of using parametrized
testing for testing serialization of objects between different python
@@ -502,15 +503,14 @@ Running it results in some skips if we don't have all the python interpreters in
.. code-block:: pytest
. $ pytest -rs -q multipython.py
sssssssssssssssssssssssssss [100%]
ssssssssssss...ssssssssssss [100%]
========================= short test summary info ==========================
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
SKIPPED [12] multipython.py:65: 'python3.9' not found
SKIPPED [12] multipython.py:65: 'python3.11' not found
3 passed, 24 skipped in 0.12s
Indirect parametrization of optional implementations/imports
--------------------------------------------------------------------
Parametrization of optional implementations/imports
---------------------------------------------------
If you want to compare the outcomes of several implementations of a given
API, you can write test functions that receive the already imported implementations
@@ -567,7 +567,7 @@ If you run this with reporting for skips enabled:
$ pytest -rs test_module.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -628,7 +628,7 @@ Then run ``pytest`` with verbose mode and with only the ``basic`` marker:
$ pytest -v -m basic
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 24 items / 21 deselected / 3 selected
@@ -657,13 +657,16 @@ Use :func:`pytest.raises` with the
:ref:`pytest.mark.parametrize ref` decorator to write parametrized tests
in which some tests raise exceptions and others do not.
It may be helpful to use ``nullcontext`` as a complement to ``raises``.
``contextlib.nullcontext`` can be used to test cases that are not expected to
raise exceptions but that should result in some value. The value is given as the
``enter_result`` parameter, which will be available as the ``with`` statements
target (``e`` in the example below).
For example:
.. code-block:: python
from contextlib import nullcontext as does_not_raise
from contextlib import nullcontext
import pytest
@@ -671,16 +674,17 @@ For example:
@pytest.mark.parametrize(
"example_input,expectation",
[
(3, does_not_raise()),
(2, does_not_raise()),
(1, does_not_raise()),
(3, nullcontext(2)),
(2, nullcontext(3)),
(1, nullcontext(6)),
(0, pytest.raises(ZeroDivisionError)),
],
)
def test_division(example_input, expectation):
"""Test how much I know division."""
with expectation:
assert (6 / example_input) is not None
with expectation as e:
assert (6 / example_input) == e
In the example above, the first three test cases should run unexceptionally,
while the fourth should raise ``ZeroDivisionError``.
In the example above, the first three test cases should run without any
exceptions, while the fourth should raise a``ZeroDivisionError`` exception,
which is expected by pytest.

View File

@@ -147,15 +147,16 @@ The test collection would look like this:
$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 2 items
<Module check_myapp.py>
<Class CheckMyApp>
<Function simple_check>
<Function complex_check>
<Dir pythoncollection.rst-199>
<Module check_myapp.py>
<Class CheckMyApp>
<Function simple_check>
<Function complex_check>
======================== 2 tests collected in 0.12s ========================
@@ -209,16 +210,18 @@ You can always peek at the collection tree without running tests like this:
. $ pytest --collect-only pythoncollection.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 3 items
<Module CWD/pythoncollection.py>
<Function test_function>
<Class TestClass>
<Function test_method>
<Function test_anothermethod>
<Dir pythoncollection.rst-199>
<Dir CWD>
<Module pythoncollection.py>
<Function test_function>
<Class TestClass>
<Function test_method>
<Function test_anothermethod>
======================== 3 tests collected in 0.12s ========================
@@ -291,7 +294,7 @@ file will be left out:
$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 0 items

View File

@@ -9,7 +9,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
assertion $ pytest failure_demo.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/assertion
collected 44 items
@@ -80,6 +80,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_text(self):
> assert "spam" == "eggs"
E AssertionError: assert 'spam' == 'eggs'
E
E - eggs
E + spam
@@ -91,6 +92,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_similar_text(self):
> assert "foo 1 bar" == "foo 2 bar"
E AssertionError: assert 'foo 1 bar' == 'foo 2 bar'
E
E - foo 2 bar
E ? ^
E + foo 1 bar
@@ -104,6 +106,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_multiline_text(self):
> assert "foo\nspam\nbar" == "foo\neggs\nbar"
E AssertionError: assert 'foo\nspam\nbar' == 'foo\neggs\nbar'
E
E foo
E - eggs
E + spam
@@ -119,6 +122,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
b = "1" * 100 + "b" + "2" * 100
> assert a == b
E AssertionError: assert '111111111111...2222222222222' == '111111111111...2222222222222'
E
E Skipping 90 identical leading characters in diff, use -v to show
E Skipping 91 identical trailing characters in diff, use -v to show
E - 1111111111b222222222
@@ -136,15 +140,15 @@ Here is a nice run of several failures and how ``pytest`` presents things:
b = "1\n" * 100 + "b" + "2\n" * 100
> assert a == b
E AssertionError: assert '1\n1\n1\n1\n...n2\n2\n2\n2\n' == '1\n1\n1\n1\n...n2\n2\n2\n2\n'
E
E Skipping 190 identical leading characters in diff, use -v to show
E Skipping 191 identical trailing characters in diff, use -v to show
E 1
E 1
E 1
E 1
E 1...
E
E ...Full output truncated (6 lines hidden), use '-vv' to show
E ...Full output truncated (7 lines hidden), use '-vv' to show
failure_demo.py:60: AssertionError
_________________ TestSpecialisedExplanations.test_eq_list _________________
@@ -154,6 +158,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_list(self):
> assert [0, 1, 2] == [0, 1, 3]
E assert [0, 1, 2] == [0, 1, 3]
E
E At index 2 diff: 2 != 3
E Use -v to get more diff
@@ -167,6 +172,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
b = [0] * 100 + [2] + [3] * 100
> assert a == b
E assert [0, 0, 0, 0, 0, 0, ...] == [0, 0, 0, 0, 0, 0, ...]
E
E At index 100 diff: 1 != 2
E Use -v to get more diff
@@ -178,6 +184,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_dict(self):
> assert {"a": 0, "b": 1, "c": 0} == {"a": 0, "b": 2, "d": 0}
E AssertionError: assert {'a': 0, 'b': 1, 'c': 0} == {'a': 0, 'b': 2, 'd': 0}
E
E Omitting 1 identical items, use -vv to show
E Differing items:
E {'b': 1} != {'b': 2}
@@ -195,6 +202,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_set(self):
> assert {0, 10, 11, 12} == {0, 20, 21}
E assert {0, 10, 11, 12} == {0, 20, 21}
E
E Extra items in the left set:
E 10
E 11
@@ -212,6 +220,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
def test_eq_longer_list(self):
> assert [1, 2] == [1, 2, 3]
E assert [1, 2] == [1, 2, 3]
E
E Right contains one more item: 3
E Use -v to get more diff
@@ -233,6 +242,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
text = "some multiline\ntext\nwhich\nincludes foo\nand a\ntail"
> assert "foo" not in text
E AssertionError: assert 'foo' not in 'some multil...nand a\ntail'
E
E 'foo' is contained here:
E some multiline
E text
@@ -251,6 +261,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
text = "single foo line"
> assert "foo" not in text
E AssertionError: assert 'foo' not in 'single foo line'
E
E 'foo' is contained here:
E single foo line
E ? +++
@@ -264,6 +275,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
text = "head " * 50 + "foo " + "tail " * 20
> assert "foo" not in text
E AssertionError: assert 'foo' not in 'head head h...l tail tail '
E
E 'foo' is contained here:
E head head foo tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail
E ? +++
@@ -277,6 +289,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
text = "head " * 50 + "f" * 70 + "tail " * 20
> assert "f" * 70 not in text
E AssertionError: assert 'fffffffffff...ffffffffffff' not in 'head head h...l tail tail '
E
E 'ffffffffffffffffff...fffffffffffffffffff' is contained here:
E head head fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffftail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail
E ? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -432,7 +445,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
self = <failure_demo.TestRaises object at 0xdeadbeef0020>
def test_tupleerror(self):
> a, b = [1] # NOQA
> a, b = [1] # noqa: F841
E ValueError: not enough values to unpack (expected 2, got 1)
failure_demo.py:175: ValueError
@@ -454,7 +467,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
self = <failure_demo.TestRaises object at 0xdeadbeef0022>
def test_some_error(self):
> if namenotexi: # NOQA
> if namenotexi: # noqa: F821
E NameError: name 'namenotexi' is not defined
failure_demo.py:183: NameError

View File

@@ -168,7 +168,7 @@ Now we'll get feedback on a bad argument:
If you need to provide more detailed error messages, you can use the
``type`` parameter and raise ``pytest.UsageError``:
``type`` parameter and raise :exc:`pytest.UsageError`:
.. code-block:: python
@@ -232,7 +232,7 @@ directory with the above conftest.py:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 0 items
@@ -296,7 +296,7 @@ and when running it will see a skipped "slow" test:
$ pytest -rs # "-rs" means report details on the little 's'
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -312,7 +312,7 @@ Or run it including the ``slow`` marked test:
$ pytest --runslow
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -456,7 +456,7 @@ which will add the string to the test header accordingly:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
project deps: mylib-1.1
rootdir: /home/sweet/project
collected 0 items
@@ -484,7 +484,7 @@ which will add info only when run with "--v":
$ pytest -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
info1: did you know that ...
did you?
@@ -499,7 +499,7 @@ and nothing when run plainly:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 0 items
@@ -538,7 +538,7 @@ Now we can profile which test functions execute the slowest:
$ pytest --durations=3
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 3 items
@@ -644,7 +644,7 @@ If we run this:
$ pytest -rx
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 4 items
@@ -660,6 +660,31 @@ If we run this:
E assert 0
test_step.py:11: AssertionError
================================ XFAILURES =================================
______________________ TestUserHandling.test_deletion ______________________
item = <Function test_deletion>
def pytest_runtest_setup(item):
if "incremental" in item.keywords:
# retrieve the class name of the test
cls_name = str(item.cls)
# check if a previous test has failed for this class
if cls_name in _test_failed_incremental:
# retrieve the index of the test (if parametrize is used in combination with incremental)
parametrize_index = (
tuple(item.callspec.indices.values())
if hasattr(item, "callspec")
else ()
)
# retrieve the name of the first test function to fail for this class name and index
test_name = _test_failed_incremental[cls_name].get(parametrize_index, None)
# if name found, test has failed for the combination of class name & test name
if test_name is not None:
> pytest.xfail(f"previous test failed ({test_name})")
E _pytest.outcomes.XFailed: previous test failed (test_modification)
conftest.py:47: XFailed
========================= short test summary info ==========================
XFAIL test_step.py::TestUserHandling::test_deletion - reason: previous test failed (test_modification)
================== 1 failed, 2 passed, 1 xfailed in 0.12s ==================
@@ -726,14 +751,14 @@ We can run this:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 7 items
test_step.py .Fx. [ 57%]
a/test_db.py F [ 71%]
a/test_db2.py F [ 85%]
b/test_error.py E [100%]
a/test_db.py F [ 14%]
a/test_db2.py F [ 28%]
b/test_error.py E [ 42%]
test_step.py .Fx. [100%]
================================== ERRORS ==================================
_______________________ ERROR at setup of test_root ________________________
@@ -745,39 +770,39 @@ We can run this:
/home/sweet/project/b/test_error.py:1
================================= FAILURES =================================
_________________________________ test_a1 __________________________________
db = <conftest.DB object at 0xdeadbeef0002>
def test_a1(db):
> assert 0, db # to show value
E AssertionError: <conftest.DB object at 0xdeadbeef0002>
E assert 0
a/test_db.py:2: AssertionError
_________________________________ test_a2 __________________________________
db = <conftest.DB object at 0xdeadbeef0002>
def test_a2(db):
> assert 0, db # to show value
E AssertionError: <conftest.DB object at 0xdeadbeef0002>
E assert 0
a/test_db2.py:2: AssertionError
____________________ TestUserHandling.test_modification ____________________
self = <test_step.TestUserHandling object at 0xdeadbeef0002>
self = <test_step.TestUserHandling object at 0xdeadbeef0003>
def test_modification(self):
> assert 0
E assert 0
test_step.py:11: AssertionError
_________________________________ test_a1 __________________________________
db = <conftest.DB object at 0xdeadbeef0003>
def test_a1(db):
> assert 0, db # to show value
E AssertionError: <conftest.DB object at 0xdeadbeef0003>
E assert 0
a/test_db.py:2: AssertionError
_________________________________ test_a2 __________________________________
db = <conftest.DB object at 0xdeadbeef0003>
def test_a2(db):
> assert 0, db # to show value
E AssertionError: <conftest.DB object at 0xdeadbeef0003>
E assert 0
a/test_db2.py:2: AssertionError
========================= short test summary info ==========================
FAILED test_step.py::TestUserHandling::test_modification - assert 0
FAILED a/test_db.py::test_a1 - AssertionError: <conftest.DB object at 0x7...
FAILED a/test_db2.py::test_a2 - AssertionError: <conftest.DB object at 0x...
FAILED test_step.py::TestUserHandling::test_modification - assert 0
ERROR b/test_error.py::test_root
============= 3 failed, 2 passed, 1 xfailed, 1 error in 0.12s ==============
@@ -808,16 +833,15 @@ case we just write some information out to a ``failures`` file:
import pytest
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
@pytest.hookimpl(wrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
rep = yield
# we only look at actual failing test calls, not setup/teardown
if rep.when == "call" and rep.failed:
mode = "a" if os.path.exists("failures") else "w"
with open("failures", mode) as f:
with open("failures", mode, encoding="utf-8") as f:
# let's also access a fixture for the fun of it
if "tmp_path" in item.fixturenames:
extra = " ({})".format(item.funcargs["tmp_path"])
@@ -826,6 +850,8 @@ case we just write some information out to a ``failures`` file:
f.write(rep.nodeid + extra + "\n")
return rep
if you then have failing tests:
@@ -845,7 +871,7 @@ and run them:
$ pytest test_module.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -899,16 +925,17 @@ here is a little example implemented via a local plugin:
phase_report_key = StashKey[Dict[str, CollectReport]]()
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
@pytest.hookimpl(wrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
rep = yield
# store test results for each phase of a call, which can
# be "setup", "call", "teardown"
item.stash.setdefault(phase_report_key, {})[rep.when] = rep
return rep
@pytest.fixture
def something(request):
@@ -953,7 +980,7 @@ and run it:
$ pytest -s test_module.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 3 items
@@ -1088,4 +1115,4 @@ application with standard ``pytest`` command-line options:
.. code-block:: bash
./app_main --pytest --verbose --tb=long --junitxml=results.xml test-suite/
./app_main --pytest --verbose --tb=long --junit=xml=results.xml test-suite/

View File

@@ -1,5 +1,6 @@
import pytest
xfail = pytest.mark.xfail

View File

@@ -34,7 +34,7 @@ a function/method call.
**Assert** is where we look at that resulting state and check if it looks how
we'd expect after the dust has settled. It's where we gather evidence to say the
behavior does or does not aligns with what we expect. The ``assert`` in our test
behavior does or does not align with what we expect. The ``assert`` in our test
is where we take that measurement/observation and apply our judgement to it. If
something should be green, we'd say ``assert thing == "green"``.

View File

@@ -85,7 +85,7 @@ style of setup/teardown functions:
In addition, pytest continues to support :ref:`xunitsetup`. You can mix
both styles, moving incrementally from classic to new style, as you
prefer. You can also start out from existing :ref:`unittest.TestCase
style <unittest.TestCase>` or :ref:`nose based <nosestyle>` projects.
style <unittest.TestCase>`.
@@ -162,7 +162,7 @@ A note about fixture cleanup
----------------------------
pytest does not do any special processing for :data:`SIGTERM <signal.SIGTERM>` and
:data:`SIGQUIT <signal.SIGQUIT>` signals (:data:`SIGINT <signal.SIGINT>` is handled naturally
``SIGQUIT`` signals (:data:`SIGINT <signal.SIGINT>` is handled naturally
by the Python runtime via :class:`KeyboardInterrupt`), so fixtures that manage external resources which are important
to be cleared when the Python process is terminated (by those signals) might leak resources.

View File

@@ -52,10 +52,9 @@ Plugins
Rerunning any failed tests can mitigate the negative effects of flaky tests by giving them additional chances to pass, so that the overall build does not fail. Several pytest plugins support this:
* `flaky <https://github.com/box/flaky>`_
* `pytest-flakefinder <https://github.com/dropbox/pytest-flakefinder>`_ - `blog post <https://blogs.dropbox.com/tech/2016/03/open-sourcing-pytest-tools/>`_
* `pytest-rerunfailures <https://github.com/pytest-dev/pytest-rerunfailures>`_
* `pytest-replay <https://github.com/ESSS/pytest-replay>`_: This plugin helps to reproduce locally crashes or flaky tests observed during CI runs.
* `pytest-flakefinder <https://github.com/dropbox/pytest-flakefinder>`_ - `blog post <https://blogs.dropbox.com/tech/2016/03/open-sourcing-pytest-tools/>`_
Plugins to deliberately randomize tests can help expose tests with state problems:
@@ -106,7 +105,7 @@ This is a limited list, please submit an issue or pull request to expand it!
* Gao, Zebao, Yalan Liang, Myra B. Cohen, Atif M. Memon, and Zhen Wang. "Making system user interactive tests repeatable: When and what should we control?." In *Software Engineering (ICSE), 2015 IEEE/ACM 37th IEEE International Conference on*, vol. 1, pp. 55-65. IEEE, 2015. `PDF <http://www.cs.umd.edu/~atif/pubs/gao-icse15.pdf>`__
* Palomba, Fabio, and Andy Zaidman. "Does refactoring of test smells induce fixing flaky tests?." In *Software Maintenance and Evolution (ICSME), 2017 IEEE International Conference on*, pp. 1-12. IEEE, 2017. `PDF in Google Drive <https://drive.google.com/file/d/10HdcCQiuQVgW3yYUJD-TSTq1NbYEprl0/view>`__
* Bell, Jonathan, Owolabi Legunsen, Michael Hilton, Lamyaa Eloussi, Tifany Yung, and Darko Marinov. "DeFlaker: Automatically detecting flaky tests." In *Proceedings of the 2018 International Conference on Software Engineering*. 2018. `PDF <https://www.jonbell.net/icse18-deflaker.pdf>`__
* Dutta, Saikat and Shi, August and Choudhary, Rutvik and Zhang, Zhekun and Jain, Aryaman and Misailovic, Sasa. "Detecting flaky tests in probabilistic and machine learning applications." In *Proceedings of the 29th ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA)*, pp. 211-224. ACM, 2020. `PDF <https://www.cs.cornell.edu/~saikatd/papers/flash-issta20.pdf>`__
Resources
^^^^^^^^^

View File

@@ -60,8 +60,10 @@ Within Python modules, ``pytest`` also discovers tests using the standard
:ref:`unittest.TestCase <unittest.TestCase>` subclassing technique.
Choosing a test layout / import rules
-------------------------------------
.. _`test layout`:
Choosing a test layout
----------------------
``pytest`` supports two common test layouts:

View File

@@ -10,19 +10,27 @@ Import modes
pytest as a testing framework needs to import test modules and ``conftest.py`` files for execution.
Importing files in Python (at least until recently) is a non-trivial processes, often requiring
changing :data:`sys.path`. Some aspects of the
Importing files in Python is a non-trivial processes, so aspects of the
import process can be controlled through the ``--import-mode`` command-line flag, which can assume
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:`importlib.import_module <importlib.import_module>` function.
.. _`import-mode-prepend`:
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.
* ``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:`importlib.import_module <importlib.import_module>` function.
It is highly recommended to arrange your test modules as packages by adding ``__init__.py`` files to your directories
containing tests. This will make the tests part of a proper Python package, allowing pytest to resolve their full
name (for example ``tests.core.test_core`` for ``test_core.py`` inside the ``tests.core`` package).
If the test directory tree is not arranged as packages, then each test file needs to have a unique name
compared to the other test files, otherwise pytest will raise an error if it finds two tests with the same name.
This is the classic mechanism, dating back from the time Python 2 was still supported.
.. _`import-mode-append`:
* ``append``: the directory containing each module is appended to the end of :py:data:`sys.path` if not already
there, and imported with :func:`importlib.import_module <importlib.import_module>`.
@@ -38,32 +46,78 @@ these values:
the tests will run against the installed version
of ``pkg_under_test`` when ``--import-mode=append`` is used whereas
with ``prepend`` they would pick up the local version. This kind of confusion is why
we advocate for using :ref:`src <src-layout>` layouts.
we advocate for using :ref:`src-layouts <src-layout>`.
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 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`.
.. _`import-mode-importlib`:
For this reason this doesn't require test module names to be unique.
* ``importlib``: this mode uses more fine control mechanisms provided by :mod:`importlib` to import test modules, without changing :py:data:`sys.path`.
One drawback however is that test modules are non-importable by each other. Also, utility
modules in the tests directories are not automatically importable because the tests directory is no longer
added to :py:data:`sys.path`.
Advantages of this mode:
Initially we intended to make ``importlib`` the default in future releases, however it is clear now that
it has its own set of drawbacks so the default will remain ``prepend`` for the foreseeable future.
* pytest will not change :py:data:`sys.path` at all.
* Test module names do not need to be unique -- pytest will generate a unique name automatically based on the ``rootdir``.
Disadvantages:
* Test modules can't import each other.
* Testing utility modules in the tests directories (for example a ``tests.helpers`` module containing test-related functions/classes)
are not importable. The recommendation in this case it to place testing utility modules together with the application/library
code, for example ``app.testing.helpers``.
Important: by "test utility modules" we mean functions/classes which are imported by
other tests directly; this does not include fixtures, which should be placed in ``conftest.py`` files, along
with the test modules, and are discovered automatically by pytest.
It works like this:
1. Given a certain module path, for example ``tests/core/test_models.py``, derives a canonical name
like ``tests.core.test_models`` and tries to import it.
For non-test modules this will work if they are accessible via :py:data:`sys.path`, so
for example ``.env/lib/site-packages/app/core.py`` will be importable as ``app.core``.
This is happens when plugins import non-test modules (for example doctesting).
If this step succeeds, the module is returned.
For test modules, unless they are reachable from :py:data:`sys.path`, this step will fail.
2. If the previous step fails, we import the module directly using ``importlib`` facilities, which lets us import it without
changing :py:data:`sys.path`.
Because Python requires the module to also be available in :py:data:`sys.modules`, pytest derives a unique name for it based
on its relative location from the ``rootdir``, and adds the module to :py:data:`sys.modules`.
For example, ``tests/core/test_models.py`` will end up being imported as the module ``tests.core.test_models``.
.. versionadded:: 6.0
.. note::
Initially we intended to make ``importlib`` the default in future releases, however it is clear now that
it has its own set of drawbacks so the default will remain ``prepend`` for the foreseeable future.
.. note::
By default, pytest will not attempt to resolve namespace packages automatically, but that can
be changed via the :confval:`consider_namespace_packages` configuration variable.
.. seealso::
The :confval:`pythonpath` configuration variable.
The :confval:`consider_namespace_packages` configuration variable.
:ref:`test layout`.
``prepend`` and ``append`` import modes scenarios
-------------------------------------------------
Here's a list of scenarios when using ``prepend`` or ``append`` import modes where pytest needs to
change ``sys.path`` in order to import test modules or ``conftest.py`` files, and the issues users
change :py:data:`sys.path` in order to import test modules or ``conftest.py`` files, and the issues users
might encounter because of that.
Test modules / ``conftest.py`` files inside packages
@@ -92,7 +146,7 @@ pytest will find ``foo/bar/tests/test_foo.py`` and realize it is part of a packa
there's an ``__init__.py`` file in the same folder. It will then search upwards until it can find the
last folder which still contains an ``__init__.py`` file in order to find the package *root* (in
this case ``foo/``). To load the module, it will insert ``root/`` to the front of
``sys.path`` (if not there already) in order to load
:py:data:`sys.path` (if not there already) in order to load
``test_foo.py`` as the *module* ``foo.bar.tests.test_foo``.
The same logic applies to the ``conftest.py`` file: it will be imported as ``foo.conftest`` module.
@@ -122,8 +176,8 @@ When executing:
pytest will find ``foo/bar/tests/test_foo.py`` and realize it is NOT part of a package given that
there's no ``__init__.py`` file in the same folder. It will then add ``root/foo/bar/tests`` to
``sys.path`` in order to import ``test_foo.py`` as the *module* ``test_foo``. The same is done
with the ``conftest.py`` file by adding ``root/foo`` to ``sys.path`` to import it as ``conftest``.
:py:data:`sys.path` in order to import ``test_foo.py`` as the *module* ``test_foo``. The same is done
with the ``conftest.py`` file by adding ``root/foo`` to :py:data:`sys.path` to import it as ``conftest``.
For this reason this layout cannot have test modules with the same name, as they all will be
imported in the global import namespace.
@@ -136,7 +190,7 @@ Invoking ``pytest`` versus ``python -m pytest``
-----------------------------------------------
Running pytest with ``pytest [...]`` instead of ``python -m pytest [...]`` yields nearly
equivalent behaviour, except that the latter will add the current directory to ``sys.path``, which
equivalent behaviour, except that the latter will add the current directory to :py:data:`sys.path`, which
is standard ``python`` behavior.
See also :ref:`invoke-python`.

View File

@@ -11,8 +11,6 @@ funcarg mechanism, see :ref:`historical funcargs and pytest.funcargs`.
If you are new to pytest, then you can simply ignore this
section and read the other sections.
.. currentmodule:: _pytest
Shortcomings of the previous ``pytest_funcarg__`` mechanism
--------------------------------------------------------------
@@ -46,7 +44,7 @@ There are several limitations and difficulties with this approach:
2. parametrizing the "db" resource is not straight forward:
you need to apply a "parametrize" decorator or implement a
:py:func:`~hookspec.pytest_generate_tests` hook
:hook:`pytest_generate_tests` hook
calling :py:func:`~pytest.Metafunc.parametrize` which
performs parametrization at the places where the resource
is used. Moreover, you need to modify the factory to use an
@@ -94,15 +92,14 @@ Direct parametrization of funcarg resource factories
Previously, funcarg factories could not directly cause parametrization.
You needed to specify a ``@parametrize`` decorator on your test function
or implement a ``pytest_generate_tests`` hook to perform
or implement a :hook:`pytest_generate_tests` hook to perform
parametrization, i.e. calling a test multiple times with different value
sets. pytest-2.3 introduces a decorator for use on the factory itself:
.. code-block:: python
@pytest.fixture(params=["mysql", "pg"])
def db(request):
... # use request.param
def db(request): ... # use request.param
Here the factory will be invoked twice (with the respective "mysql"
and "pg" values set as ``request.param`` attributes) and all of
@@ -143,8 +140,7 @@ argument:
.. code-block:: python
@pytest.fixture()
def db(request):
...
def db(request): ...
The name under which the funcarg resource can be requested is ``db``.
@@ -153,8 +149,7 @@ aka:
.. code-block:: python
def pytest_funcarg__db(request):
...
def pytest_funcarg__db(request): ...
But it is then not possible to define scoping and parametrization.

View File

@@ -9,7 +9,7 @@ Get Started
Install ``pytest``
----------------------------------------
``pytest`` requires: Python 3.7+ or PyPy3.
``pytest`` requires: Python 3.8+ or PyPy3.
1. Run the following command in your command line:
@@ -22,7 +22,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
pytest 7.4.0
pytest 8.2.0
.. _`simpletest`:
@@ -47,7 +47,7 @@ The test
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -97,6 +97,30 @@ Use the :ref:`raises <assertraises>` helper to assert that some code raises an e
with pytest.raises(SystemExit):
f()
You can also use the context provided by :ref:`raises <assertraises>` to
assert that an expected exception is part of a raised :class:`ExceptionGroup`:
.. code-block:: python
# content of test_exceptiongroup.py
import pytest
def f():
raise ExceptionGroup(
"Group message",
[
RuntimeError(),
],
)
def test_exception_in_group():
with pytest.raises(ExceptionGroup) as excinfo:
f()
assert excinfo.group_contains(RuntimeError)
assert not excinfo.group_contains(TypeError)
Execute the test function with “quiet” reporting mode:
.. code-block:: pytest

View File

@@ -112,7 +112,7 @@ More details can be found in the :pull:`original PR <3317>`.
.. note::
in a future major release of pytest we will introduce class based markers,
at which point markers will no longer be limited to instances of :py:class:`~_pytest.mark.Mark`.
at which point markers will no longer be limited to instances of :py:class:`~pytest.Mark`.
cache plugin integrated into the core
@@ -227,8 +227,7 @@ to use strings:
@pytest.mark.skipif("sys.version_info >= (3,3)")
def test_function():
...
def test_function(): ...
During test function setup the skipif condition is evaluated by calling
``eval('sys.version_info >= (3,0)', namespace)``. The namespace contains
@@ -262,8 +261,7 @@ configuration value which you might have added:
.. code-block:: python
@pytest.mark.skipif("not config.getvalue('db')")
def test_function():
...
def test_function(): ...
The equivalent with "boolean conditions" is:

View File

@@ -29,7 +29,7 @@ you will see the return value of the function call:
$ pytest test_assert1.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -54,14 +54,13 @@ operators. (See :ref:`tbreportdemo`). This allows you to use the
idiomatic python constructs without boilerplate code while not losing
introspection information.
However, if you specify a message with the assertion like this:
If a message is specified with the assertion like this:
.. code-block:: python
assert a % 2 == 0, "value was odd, should be even"
then no assertion introspection takes places at all and the message
will be simply shown in the traceback.
it is printed alongside the assertion introspection in the traceback.
See :ref:`assert-details` for more information on assertion introspection.
@@ -99,6 +98,27 @@ and if you need to have access to the actual exception info you may use:
the actual exception raised. The main attributes of interest are
``.type``, ``.value`` and ``.traceback``.
Note that ``pytest.raises`` will match the exception type or any subclasses (like the standard ``except`` statement).
If you want to check if a block of code is raising an exact exception type, you need to check that explicitly:
.. code-block:: python
def test_foo_not_implemented():
def foo():
raise NotImplementedError
with pytest.raises(RuntimeError) as excinfo:
foo()
assert excinfo.type is RuntimeError
The :func:`pytest.raises` call will succeed, even though the function raises :class:`NotImplementedError`, because
:class:`NotImplementedError` is a subclass of :class:`RuntimeError`; however the following `assert` statement will
catch the problem.
Matching exception messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can pass a ``match`` keyword parameter to the context-manager to test
that a regular expression matches on the string representation of an exception
(similar to the ``TestCase.assertRaisesRegex`` method from ``unittest``):
@@ -116,36 +136,113 @@ that a regular expression matches on the string representation of an exception
with pytest.raises(ValueError, match=r".* 123 .*"):
myfunc()
The regexp parameter of the ``match`` method is matched with the ``re.search``
function, so in the above example ``match='123'`` would have worked as
well.
Notes:
There's an alternate form of the :func:`pytest.raises` function where you pass
a function that will be executed with the given ``*args`` and ``**kwargs`` and
assert that the given exception is raised:
* The ``match`` parameter is matched with the :func:`re.search`
function, so in the above example ``match='123'`` would have worked as well.
* The ``match`` parameter also matches against `PEP-678 <https://peps.python.org/pep-0678/>`__ ``__notes__``.
.. _`assert-matching-exception-groups`:
Matching exception groups
~~~~~~~~~~~~~~~~~~~~~~~~~
You can also use the :func:`excinfo.group_contains() <pytest.ExceptionInfo.group_contains>`
method to test for exceptions returned as part of an :class:`ExceptionGroup`:
.. code-block:: python
pytest.raises(ExpectedException, func, *args, **kwargs)
def test_exception_in_group():
with pytest.raises(ExceptionGroup) as excinfo:
raise ExceptionGroup(
"Group message",
[
RuntimeError("Exception 123 raised"),
],
)
assert excinfo.group_contains(RuntimeError, match=r".* 123 .*")
assert not excinfo.group_contains(TypeError)
The optional ``match`` keyword parameter works the same way as for
:func:`pytest.raises`.
By default ``group_contains()`` will recursively search for a matching
exception at any level of nested ``ExceptionGroup`` instances. You can
specify a ``depth`` keyword parameter if you only want to match an
exception at a specific level; exceptions contained directly in the top
``ExceptionGroup`` would match ``depth=1``.
.. code-block:: python
def test_exception_in_group_at_given_depth():
with pytest.raises(ExceptionGroup) as excinfo:
raise ExceptionGroup(
"Group message",
[
RuntimeError(),
ExceptionGroup(
"Nested group",
[
TypeError(),
],
),
],
)
assert excinfo.group_contains(RuntimeError, depth=1)
assert excinfo.group_contains(TypeError, depth=2)
assert not excinfo.group_contains(RuntimeError, depth=2)
assert not excinfo.group_contains(TypeError, depth=1)
Alternate form (legacy)
~~~~~~~~~~~~~~~~~~~~~~~
There is an alternate form where you pass
a function that will be executed, along ``*args`` and ``**kwargs``, and :func:`pytest.raises`
will execute the function with the arguments and assert that the given exception is raised:
.. code-block:: python
def func(x):
if x <= 0:
raise ValueError("x needs to be larger than zero")
pytest.raises(ValueError, func, x=-1)
The reporter will provide you with helpful output in case of failures such as *no
exception* or *wrong exception*.
Note that it is also possible to specify a "raises" argument to
``pytest.mark.xfail``, which checks that the test is failing in a more
This form was the original :func:`pytest.raises` API, developed before the ``with`` statement was
added to the Python language. Nowadays, this form is rarely used, with the context-manager form (using ``with``)
being considered more readable.
Nonetheless, this form is fully supported and not deprecated in any way.
xfail mark and pytest.raises
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is also possible to specify a ``raises`` argument to
:ref:`pytest.mark.xfail <pytest.mark.xfail ref>`, which checks that the test is failing in a more
specific way than just having any exception raised:
.. code-block:: python
def f():
raise IndexError()
@pytest.mark.xfail(raises=IndexError)
def test_f():
f()
Using :func:`pytest.raises` is likely to be better for cases where you are
testing exceptions your own code is deliberately raising, whereas using
``@pytest.mark.xfail`` with a check function is probably better for something
like documenting unfixed bugs (where the test describes what "should" happen)
or bugs in dependencies.
This will only "xfail" if the test fails by raising ``IndexError`` or subclasses.
* Using :ref:`pytest.mark.xfail <pytest.mark.xfail ref>` with the ``raises`` parameter is probably better for something
like documenting unfixed bugs (where the test describes what "should" happen) or bugs in dependencies.
* Using :func:`pytest.raises` is likely to be better for cases where you are
testing exceptions your own code is deliberately raising, which is the majority of cases.
.. _`assertwarns`:
@@ -183,7 +280,7 @@ if you run this module:
$ pytest test_assert2.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -197,6 +294,7 @@ if you run this module:
set2 = set("8035")
> assert set1 == set2
E AssertionError: assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'}
E
E Extra items in the left set:
E '1'
E Extra items in the right set:

View File

@@ -86,7 +86,7 @@ If you then run it with ``--lf``:
$ pytest --lf
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
run-last-failure: rerun previous 2 failures
@@ -132,7 +132,7 @@ of ``FF`` and dots):
$ pytest --ff
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 50 items
run-last-failure: rerun previous 2 failures first
@@ -176,14 +176,21 @@ with more recent files coming first.
Behavior when no tests failed in the last run
---------------------------------------------
When no tests failed in the last run, or when no cached ``lastfailed`` data was
found, ``pytest`` can be configured either to run all of the tests or no tests,
using the ``--last-failed-no-failures`` option, which takes one of the following values:
The ``--lfnf/--last-failed-no-failures`` option governs the behavior of ``--last-failed``.
Determines whether to execute tests when there are no previously (known)
failures or when no cached ``lastfailed`` data was found.
There are two options:
* ``all``: when there are no known test failures, runs all tests (the full test suite). This is the default.
* ``none``: when there are no known test failures, just emits a message stating this and exit successfully.
Example:
.. code-block:: bash
pytest --last-failed --last-failed-no-failures all # run all tests (default behavior)
pytest --last-failed --last-failed-no-failures none # run no tests and exit
pytest --last-failed --last-failed-no-failures all # runs the full test suite (default behavior)
pytest --last-failed --last-failed-no-failures none # runs no tests and exits successfully
The new config.cache object
--------------------------------
@@ -206,12 +213,12 @@ across pytest invocations:
@pytest.fixture
def mydata(request):
val = request.config.cache.get("example/value", None)
def mydata(pytestconfig):
val = pytestconfig.cache.get("example/value", None)
if val is None:
expensive_computation()
val = 42
request.config.cache.set("example/value", val)
pytestconfig.cache.set("example/value", val)
return val
@@ -274,7 +281,7 @@ You can always peek at the content of the cache using the
$ pytest --cache-show
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
cachedir: /home/sweet/project/.pytest_cache
--------------------------- cache values for '*' ---------------------------
@@ -296,7 +303,7 @@ filtering:
$ pytest --cache-show example/*
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
cachedir: /home/sweet/project/.pytest_cache
----------------------- cache values for 'example/*' -----------------------

View File

@@ -83,7 +83,7 @@ of the failing function and hide the other one:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items

View File

@@ -28,7 +28,7 @@ Running pytest now produces this output:
$ pytest test_show_warnings.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -382,8 +382,6 @@ warnings: a WarningsRecorder instance. To view the recorded warnings, you can
iterate over this instance, call ``len`` on it to get the number of recorded
warnings, or index into it to get a particular recorded warning.
.. currentmodule:: _pytest.warnings
Full API: :class:`~_pytest.recwarn.WarningsRecorder`.
.. _`warns use cases`:

View File

@@ -30,7 +30,7 @@ then you can just invoke ``pytest`` directly:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -58,7 +58,7 @@ and functions, including from test modules:
$ pytest --doctest-modules
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -224,6 +224,7 @@ place the objects you want to appear in the doctest namespace:
.. code-block:: python
# content of conftest.py
import pytest
import numpy

View File

@@ -4,8 +4,8 @@ How to use pytest with an existing test suite
==============================================
Pytest can be used with most existing test suites, but its
behavior differs from other test runners such as :ref:`nose <noseintegration>` or
Python's default unittest framework.
behavior differs from other test runners such as Python's
default unittest framework.
Before using this section you will want to :ref:`install pytest <getstarted>`.

View File

@@ -135,10 +135,6 @@ Warning about unraisable exceptions and unhandled thread exceptions
.. versionadded:: 6.2
.. note::
These features only work on Python>=3.8.
Unhandled exceptions are exceptions that are raised in a situation in which
they cannot propagate to a caller. The most common case is an exception raised
in a :meth:`__del__ <object.__del__>` implementation.

View File

@@ -433,7 +433,7 @@ marked ``smtp_connection`` fixture function. Running the test looks like this:
$ pytest test_module.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -494,7 +494,7 @@ Fixtures are created when first requested by a test, and are destroyed based on
* ``function``: the default scope, the fixture is destroyed at the end of the test.
* ``class``: the fixture is destroyed during teardown of the last test in the class.
* ``module``: the fixture is destroyed during teardown of the last test in the module.
* ``package``: the fixture is destroyed during teardown of the last test in the package.
* ``package``: the fixture is destroyed during teardown of the last test in the package where the fixture is defined, including sub-packages and sub-directories within it.
* ``session``: the fixture is destroyed at the end of the test session.
.. note::
@@ -771,7 +771,7 @@ For yield fixtures, the first teardown code to run is from the right-most fixtur
$ pytest -s test_finalizers.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -805,7 +805,7 @@ For finalizers, the first fixture to run is last call to `request.addfinalizer`.
$ pytest -s test_finalizers.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -1271,7 +1271,7 @@ configured in multiple ways.
Extending the previous example, we can flag the fixture to create two
``smtp_connection`` fixture instances which will cause all tests using the fixture
to run twice. The fixture function gets access to each parameter
through the special :py:class:`request <FixtureRequest>` object:
through the special :py:class:`request <pytest.FixtureRequest>` object:
.. code-block:: python
@@ -1414,27 +1414,28 @@ Running the above tests results in the following test IDs being used:
$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 12 items
<Module test_anothersmtp.py>
<Function test_showhelo[smtp.gmail.com]>
<Function test_showhelo[mail.python.org]>
<Module test_emaillib.py>
<Function test_email_received>
<Module test_finalizers.py>
<Function test_bar>
<Module test_ids.py>
<Function test_a[spam]>
<Function test_a[ham]>
<Function test_b[eggs]>
<Function test_b[1]>
<Module test_module.py>
<Function test_ehlo[smtp.gmail.com]>
<Function test_noop[smtp.gmail.com]>
<Function test_ehlo[mail.python.org]>
<Function test_noop[mail.python.org]>
<Dir fixtures.rst-217>
<Module test_anothersmtp.py>
<Function test_showhelo[smtp.gmail.com]>
<Function test_showhelo[mail.python.org]>
<Module test_emaillib.py>
<Function test_email_received>
<Module test_finalizers.py>
<Function test_bar>
<Module test_ids.py>
<Function test_a[spam]>
<Function test_a[ham]>
<Function test_b[eggs]>
<Function test_b[1]>
<Module test_module.py>
<Function test_ehlo[smtp.gmail.com]>
<Function test_noop[smtp.gmail.com]>
<Function test_ehlo[mail.python.org]>
<Function test_noop[mail.python.org]>
======================= 12 tests collected in 0.12s ========================
@@ -1468,7 +1469,7 @@ Running this test will *skip* the invocation of ``data_set`` with value ``2``:
$ pytest test_fixture_marks.py -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 3 items
@@ -1518,7 +1519,7 @@ Here we declare an ``app`` fixture which receives the previously defined
$ pytest -v test_appsetup.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 2 items
@@ -1598,7 +1599,7 @@ Let's run the tests in verbose mode and with looking at the print-output:
$ pytest -v -s test_module.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
cachedir: .pytest_cache
rootdir: /home/sweet/project
collecting ... collected 8 items
@@ -1698,7 +1699,7 @@ and declare its use in a test module via a ``usefixtures`` marker:
class TestDirectoryInit:
def test_cwd_starts_empty(self):
assert os.listdir(os.getcwd()) == []
with open("myfile", "w") as f:
with open("myfile", "w", encoding="utf-8") as f:
f.write("hello")
def test_cwd_again_starts_empty(self):
@@ -1720,8 +1721,7 @@ You can specify multiple fixtures like this:
.. code-block:: python
@pytest.mark.usefixtures("cleandir", "anotherfixture")
def test():
...
def test(): ...
and you may specify fixture usage at the test module level using :globalvar:`pytestmark`:
@@ -1749,11 +1749,9 @@ into an ini-file:
@pytest.mark.usefixtures("my_other_fixture")
@pytest.fixture
def my_fixture_that_sadly_wont_use_my_other_fixture():
...
def my_fixture_that_sadly_wont_use_my_other_fixture(): ...
Currently this will not generate any error or warning, but this is intended
to be handled by :issue:`3664`.
This generates a deprecation warning, and will become an error in Pytest 8.
.. _`override fixtures`:

View File

@@ -52,7 +52,6 @@ pytest and other test systems
existingtestsuite
unittest
nose
xunit_setup
pytest development environment

View File

@@ -172,6 +172,13 @@ the records for the ``setup`` and ``call`` stages during teardown like so:
The full API is available at :class:`pytest.LogCaptureFixture`.
.. warning::
The ``caplog`` fixture adds a handler to the root logger to capture logs. If the root logger is
modified during a test, for example with ``logging.config.dictConfig``, this handler may be
removed and cause no logs to be captured. To avoid this, ensure that any root logger configuration
only adds to the existing handlers.
.. _live_logs:
@@ -199,8 +206,9 @@ option names are:
* ``log_cli_date_format``
If you need to record the whole test suite logging calls to a file, you can pass
``--log-file=/path/to/log/file``. This log file is opened in write mode which
``--log-file=/path/to/log/file``. This log file is opened in write mode by default which
means that it will be overwritten at each run tests session.
If you'd like the file opened in append mode instead, then you can pass ``--log-file-mode=a``.
Note that relative paths for the log-file location, whether passed on the CLI or declared in a
config file, are always resolved relative to the current working directory.
@@ -216,12 +224,13 @@ All of the log file options can also be set in the configuration INI file. The
option names are:
* ``log_file``
* ``log_file_mode``
* ``log_file_level``
* ``log_file_format``
* ``log_file_date_format``
You can call ``set_log_path()`` to customize the log_file path dynamically. This functionality
is considered **experimental**.
is considered **experimental**. Note that ``set_log_path()`` respects the ``log_file_mode`` option.
.. _log_colors:
@@ -234,7 +243,7 @@ through ``add_color_level()``. Example:
.. code-block:: python
@pytest.hookimpl
@pytest.hookimpl(trylast=True)
def pytest_configure(config):
logging_plugin = config.pluginmanager.get_plugin("logging-plugin")

View File

@@ -1,82 +0,0 @@
.. _`noseintegration`:
How to run tests written for nose
=======================================
``pytest`` has basic support for running tests written for nose_.
.. warning::
This functionality has been deprecated and is likely to be removed in ``pytest 8.x``.
.. _nosestyle:
Usage
-------------
After :ref:`installation` type:
.. code-block:: bash
python setup.py develop # make sure tests can import our package
pytest # instead of 'nosetests'
and you should be able to run your nose style tests and
make use of pytest's capabilities.
Supported nose Idioms
----------------------
* ``setup()`` and ``teardown()`` at module/class/method level: any function or method called ``setup`` will be called during the setup phase for each test, same for ``teardown``.
* ``SkipTest`` exceptions and markers
* setup/teardown decorators
* ``__test__`` attribute on modules/classes/functions
* general usage of nose utilities
Unsupported idioms / known issues
----------------------------------
- unittest-style ``setUp, tearDown, setUpClass, tearDownClass``
are recognized only on ``unittest.TestCase`` classes but not
on plain classes. ``nose`` supports these methods also on plain
classes but pytest deliberately does not. As nose and pytest already
both support ``setup_class, teardown_class, setup_method, teardown_method``
it doesn't seem useful to duplicate the unittest-API like nose does.
If you however rather think pytest should support the unittest-spelling on
plain classes please post to :issue:`377`.
- nose imports test modules with the same import path (e.g.
``tests.test_mode``) but different file system paths
(e.g. ``tests/test_mode.py`` and ``other/tests/test_mode.py``)
by extending sys.path/import semantics. pytest does not do that
but there is discussion in :issue:`268` for adding some support. Note that
`nose2 choose to avoid this sys.path/import hackery <https://nose2.readthedocs.io/en/latest/differences.html#test-discovery-and-loading>`_.
If you place a conftest.py file in the root directory of your project
(as determined by pytest) pytest will run tests "nose style" against
the code below that directory by adding it to your ``sys.path`` instead of
running against your installed code.
You may find yourself wanting to do this if you ran ``python setup.py install``
to set up your project, as opposed to ``python setup.py develop`` or any of
the package manager equivalents. Installing with develop in a
virtual environment like tox is recommended over this pattern.
- nose-style doctests are not collected and executed correctly,
also doctest fixtures don't work.
- no nose-configuration is recognized.
- ``yield``-based methods are unsupported as of pytest 4.1.0. They are
fundamentally incompatible with pytest because they don't support fixtures
properly since collection and test execution are separated.
Migrating from nose to pytest
------------------------------
`nose2pytest <https://github.com/pytest-dev/nose2pytest>`_ is a Python script
and pytest plugin to help convert Nose-based tests into pytest-based tests.
Specifically, the script transforms nose.tools.assert_* function calls into
raw assert statements, while preserving format of original arguments
as much as possible.
.. _nose: https://nose.readthedocs.io/en/latest/

View File

@@ -16,6 +16,12 @@ Examples for modifying traceback printing:
pytest -l # show local variables (shortcut)
pytest --no-showlocals # hide local variables (if addopts enables them)
pytest --capture=fd # default, capture at the file descriptor level
pytest --capture=sys # capture at the sys level
pytest --capture=no # don't capture
pytest -s # don't capture (shortcut)
pytest --capture=tee-sys # capture to logs but also output to sys level streams
pytest --tb=auto # (default) 'long' tracebacks for the first and last
# entry, but 'short' style for the other entries
pytest --tb=long # exhaustive, informative traceback formatting
@@ -36,6 +42,16 @@ option you make sure a trace is shown.
Verbosity
--------------------------------------------------
Examples for modifying printing verbosity:
.. code-block:: bash
pytest --quiet # quiet - less verbose - mode
pytest -q # quiet - less verbose - mode (shortcut)
pytest -v # increase verbosity, display individual test names
pytest -vv # more verbose, display more details from the test output
pytest -vvv # not a standard , but may be used for even more detail in certain setups
The ``-v`` flag controls the verbosity of pytest output in various aspects: test session progress, assertion
details when tests fail, fixtures details with ``--fixtures``, etc.
@@ -84,6 +100,7 @@ Executing pytest normally gives us this output (we are skipping the header to fo
fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
> assert fruits1 == fruits2
E AssertionError: assert ['banana', 'a...elon', 'kiwi'] == ['banana', 'a...elon', 'kiwi']
E
E At index 2 diff: 'grapes' != 'orange'
E Use -v to get more diff
@@ -95,6 +112,7 @@ Executing pytest normally gives us this output (we are skipping the header to fo
number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
> assert number_to_text1 == number_to_text2
E AssertionError: assert {'0': 0, '1':..., '3': 3, ...} == {'0': 0, '10'...'30': 30, ...}
E
E Omitting 1 identical items, use -vv to show
E Left contains 4 more items:
E {'1': 1, '2': 2, '3': 3, '4': 4}
@@ -146,12 +164,15 @@ Now we can increase pytest's verbosity:
fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
> assert fruits1 == fruits2
E AssertionError: assert ['banana', 'a...elon', 'kiwi'] == ['banana', 'a...elon', 'kiwi']
E
E At index 2 diff: 'grapes' != 'orange'
E
E Full diff:
E - ['banana', 'apple', 'orange', 'melon', 'kiwi']
E ? ^ ^^
E + ['banana', 'apple', 'grapes', 'melon', 'kiwi']
E ? ^ ^ +
E [
E 'banana',
E 'apple',...
E
E ...Full output truncated (7 lines hidden), use '-vv' to show
test_verbosity_example.py:8: AssertionError
____________________________ test_numbers_fail _____________________________
@@ -161,15 +182,15 @@ Now we can increase pytest's verbosity:
number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
> assert number_to_text1 == number_to_text2
E AssertionError: assert {'0': 0, '1':..., '3': 3, ...} == {'0': 0, '10'...'30': 30, ...}
E
E Omitting 1 identical items, use -vv to show
E Left contains 4 more items:
E {'1': 1, '2': 2, '3': 3, '4': 4}
E Right contains 4 more items:
E {'10': 10, '20': 20, '30': 30, '40': 40}
E Full diff:
E - {'0': 0, '10': 10, '20': 20, '30': 30, '40': 40}
E ? - - - - - - - -
E + {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}
E ...
E
E ...Full output truncated (16 lines hidden), use '-vv' to show
test_verbosity_example.py:14: AssertionError
___________________________ test_long_text_fail ____________________________
@@ -215,12 +236,20 @@ Now if we increase verbosity even more:
fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
> assert fruits1 == fruits2
E AssertionError: assert ['banana', 'apple', 'grapes', 'melon', 'kiwi'] == ['banana', 'apple', 'orange', 'melon', 'kiwi']
E
E At index 2 diff: 'grapes' != 'orange'
E
E Full diff:
E - ['banana', 'apple', 'orange', 'melon', 'kiwi']
E ? ^ ^^
E + ['banana', 'apple', 'grapes', 'melon', 'kiwi']
E ? ^ ^ +
E [
E 'banana',
E 'apple',
E - 'orange',
E ? ^ ^^
E + 'grapes',
E ? ^ ^ +
E 'melon',
E 'kiwi',
E ]
test_verbosity_example.py:8: AssertionError
____________________________ test_numbers_fail _____________________________
@@ -230,16 +259,30 @@ Now if we increase verbosity even more:
number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
> assert number_to_text1 == number_to_text2
E AssertionError: assert {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4} == {'0': 0, '10': 10, '20': 20, '30': 30, '40': 40}
E
E Common items:
E {'0': 0}
E Left contains 4 more items:
E {'1': 1, '2': 2, '3': 3, '4': 4}
E Right contains 4 more items:
E {'10': 10, '20': 20, '30': 30, '40': 40}
E
E Full diff:
E - {'0': 0, '10': 10, '20': 20, '30': 30, '40': 40}
E ? - - - - - - - -
E + {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}
E {
E '0': 0,
E - '10': 10,
E ? - -
E + '1': 1,
E - '20': 20,
E ? - -
E + '2': 2,
E - '30': 30,
E ? - -
E + '3': 3,
E - '40': 40,
E ? - -
E + '4': 4,
E }
test_verbosity_example.py:14: AssertionError
___________________________ test_long_text_fail ____________________________
@@ -251,9 +294,47 @@ Now if we increase verbosity even more:
test_verbosity_example.py:19: AssertionError
========================= short test summary info ==========================
FAILED test_verbosity_example.py::test_words_fail - AssertionError: asser...
FAILED test_verbosity_example.py::test_numbers_fail - AssertionError: ass...
FAILED test_verbosity_example.py::test_long_text_fail - AssertionError: a...
FAILED test_verbosity_example.py::test_words_fail - AssertionError: assert ['banana', 'apple', 'grapes', 'melon', 'kiwi'] == ['banana', 'apple', 'orange', 'melon', 'kiwi']
At index 2 diff: 'grapes' != 'orange'
Full diff:
[
'banana',
'apple',
- 'orange',
? ^ ^^
+ 'grapes',
? ^ ^ +
'melon',
'kiwi',
]
FAILED test_verbosity_example.py::test_numbers_fail - AssertionError: assert {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4} == {'0': 0, '10': 10, '20': 20, '30': 30, '40': 40}
Common items:
{'0': 0}
Left contains 4 more items:
{'1': 1, '2': 2, '3': 3, '4': 4}
Right contains 4 more items:
{'10': 10, '20': 20, '30': 30, '40': 40}
Full diff:
{
'0': 0,
- '10': 10,
? - -
+ '1': 1,
- '20': 20,
? - -
+ '2': 2,
- '30': 30,
? - -
+ '3': 3,
- '40': 40,
? - -
+ '4': 4,
}
FAILED test_verbosity_example.py::test_long_text_fail - AssertionError: assert 'hello world' in 'Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet '
======================= 3 failed, 1 passed in 0.12s ========================
Notice now that:
@@ -270,6 +351,22 @@ situations, for example you are shown even fixtures that start with ``_`` if you
Using higher verbosity levels (``-vvv``, ``-vvvv``, ...) is supported, but has no effect in pytest itself at the moment,
however some plugins might make use of higher verbosity.
.. _`pytest.fine_grained_verbosity`:
Fine-grained verbosity
~~~~~~~~~~~~~~~~~~~~~~
In addition to specifying the application wide verbosity level, it is possible to control specific aspects independently.
This is done by setting a verbosity level in the configuration file for the specific aspect of the output.
:confval:`verbosity_assertions`: Controls how verbose the assertion output should be when pytest is executed. Running
``pytest --no-header`` with a value of ``2`` would have the same output as the previous example, but each test inside
the file is shown by a single character in the output.
:confval:`verbosity_test_cases`: Controls how verbose the test execution output should be when pytest is executed.
Running ``pytest --no-header`` with a value of ``2`` would have the same output as the first verbosity example, but each
test inside the file gets its own line in the output.
.. _`pytest.detailed_failed_tests_usage`:
Producing a detailed summary report
@@ -324,7 +421,7 @@ Example:
$ pytest -ra
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 6 items
@@ -347,10 +444,19 @@ Example:
E assert 0
test_example.py:14: AssertionError
================================ XFAILURES =================================
________________________________ test_xfail ________________________________
def test_xfail():
> pytest.xfail("xfailing this test")
E _pytest.outcomes.XFailed: xfailing this test
test_example.py:26: XFailed
================================= XPASSES ==================================
========================= short test summary info ==========================
SKIPPED [1] test_example.py:22: skipping this test
XFAIL test_example.py::test_xfail - reason: xfailing this test
XPASS test_example.py::test_xpass always xfail
XPASS test_example.py::test_xpass - always xfail
ERROR test_example.py::test_error - assert 0
FAILED test_example.py::test_fail - assert 0
== 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12s ===
@@ -380,7 +486,7 @@ More than one character can be used, so for example to only see failed and skipp
$ pytest -rfs
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 6 items
@@ -415,7 +521,7 @@ captured output:
$ pytest -rpP
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 6 items
@@ -478,7 +584,7 @@ integration servers, use this invocation:
.. code-block:: bash
pytest --junitxml=path
pytest --junit-xml=path
to create an XML file at ``path``.

View File

@@ -56,7 +56,7 @@ them in turn:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 3 items
@@ -167,7 +167,7 @@ Let's run this:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 3 items

View File

@@ -47,8 +47,7 @@ which may be passed an optional ``reason``:
.. code-block:: python
@pytest.mark.skip(reason="no way of currently testing this")
def test_the_unknown():
...
def test_the_unknown(): ...
Alternatively, it is also possible to skip imperatively during test execution or setup
@@ -93,8 +92,7 @@ when run on an interpreter earlier than Python3.10:
@pytest.mark.skipif(sys.version_info < (3, 10), reason="requires python3.10 or higher")
def test_function():
...
def test_function(): ...
If the condition evaluates to ``True`` during collection, the test function will be skipped,
with the specified reason appearing in the summary when using ``-rs``.
@@ -112,8 +110,7 @@ You can share ``skipif`` markers between modules. Consider this test module:
@minversion
def test_function():
...
def test_function(): ...
You can import the marker and reuse it in another test module:
@@ -124,8 +121,7 @@ You can import the marker and reuse it in another test module:
@minversion
def test_anotherfunction():
...
def test_anotherfunction(): ...
For larger test suites it's usually a good idea to have one file
where you define the markers which you then consistently apply
@@ -232,8 +228,7 @@ expect a test to fail:
.. code-block:: python
@pytest.mark.xfail
def test_function():
...
def test_function(): ...
This test will run but no traceback will be reported when it fails. Instead, terminal
reporting will list it in the "expected to fail" (``XFAIL``) or "unexpectedly
@@ -275,8 +270,7 @@ that condition as the first parameter:
.. code-block:: python
@pytest.mark.xfail(sys.platform == "win32", reason="bug in a 3rd party library")
def test_function():
...
def test_function(): ...
Note that you have to pass a reason as well (see the parameter description at
:ref:`pytest.mark.xfail ref`).
@@ -289,8 +283,7 @@ You can specify the motive of an expected failure with the ``reason`` parameter:
.. code-block:: python
@pytest.mark.xfail(reason="known parser issue")
def test_function():
...
def test_function(): ...
``raises`` parameter
@@ -302,8 +295,7 @@ a single exception, or a tuple of exceptions, in the ``raises`` argument.
.. code-block:: python
@pytest.mark.xfail(raises=RuntimeError)
def test_function():
...
def test_function(): ...
Then the test will be reported as a regular failure if it fails with an
exception not mentioned in ``raises``.
@@ -317,8 +309,7 @@ even executed, use the ``run`` parameter as ``False``:
.. code-block:: python
@pytest.mark.xfail(run=False)
def test_function():
...
def test_function(): ...
This is specially useful for xfailing tests that are crashing the interpreter and should be
investigated later.
@@ -334,8 +325,7 @@ You can change this by setting the ``strict`` keyword-only parameter to ``True``
.. code-block:: python
@pytest.mark.xfail(strict=True)
def test_function():
...
def test_function(): ...
This will make ``XPASS`` ("unexpectedly passing") results from this test to fail the test suite.

View File

@@ -8,9 +8,8 @@ How to use temporary directories and files in tests
The ``tmp_path`` fixture
------------------------
You can use the ``tmp_path`` fixture which will
provide a temporary directory unique to the test invocation,
created in the `base temporary directory`_.
You can use the ``tmp_path`` fixture which will provide a temporary directory
unique to each test function.
``tmp_path`` is a :class:`pathlib.Path` object. Here is an example test usage:
@@ -24,8 +23,8 @@ created in the `base temporary directory`_.
d = tmp_path / "sub"
d.mkdir()
p = d / "hello.txt"
p.write_text(CONTENT)
assert p.read_text() == CONTENT
p.write_text(CONTENT, encoding="utf-8")
assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1
assert 0
@@ -36,7 +35,7 @@ Running this would result in a passed test except for the last
$ pytest test_tmp_path.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -51,8 +50,8 @@ Running this would result in a passed test except for the last
d = tmp_path / "sub"
d.mkdir()
p = d / "hello.txt"
p.write_text(CONTENT)
assert p.read_text() == CONTENT
p.write_text(CONTENT, encoding="utf-8")
assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1
> assert 0
E assert 0
@@ -62,6 +61,11 @@ Running this would result in a passed test except for the last
FAILED test_tmp_path.py::test_create_file - assert 0
============================ 1 failed in 0.12s =============================
By default, ``pytest`` retains the temporary directory for the last 3 ``pytest``
invocations. Concurrent invocations of the same test function are supported by
configuring the base temporary directory to be unique for each concurrent
run. See `temporary directory location and retention`_ for details.
.. _`tmp_path_factory example`:
The ``tmp_path_factory`` fixture
@@ -100,7 +104,7 @@ See :ref:`tmp_path_factory API <tmp_path_factory factory api>` for details.
.. _tmpdir:
The ``tmpdir`` and ``tmpdir_factory`` fixtures
---------------------------------------------------
----------------------------------------------
The ``tmpdir`` and ``tmpdir_factory`` fixtures are similar to ``tmp_path``
and ``tmp_path_factory``, but use/return legacy `py.path.local`_ objects
@@ -124,10 +128,10 @@ See :fixture:`tmpdir <tmpdir>` :fixture:`tmpdir_factory <tmpdir_factory>`
API for details.
.. _`base temporary directory`:
.. _`temporary directory location and retention`:
The default base temporary directory
-----------------------------------------------
Temporary directory location and retention
------------------------------------------
Temporary directories are by default created as sub-directories of
the system temporary directory. The base name will be ``pytest-NUM`` where
@@ -152,7 +156,7 @@ You can override the default temporary directory setting like this:
for that purpose only.
When distributing tests on the local machine using ``pytest-xdist``, care is taken to
automatically configure a basetemp directory for the sub processes such that all temporary
data lands below a single per-test run basetemp directory.
automatically configure a `basetemp` directory for the sub processes such that all temporary
data lands below a single per-test run temporary directory.
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html

View File

@@ -140,7 +140,7 @@ the ``self.db`` values in the traceback:
$ pytest test_unittest_db.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
@@ -207,10 +207,10 @@ creation of a per-test temporary directory:
@pytest.fixture(autouse=True)
def initdir(self, tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path) # change to pytest-provided temporary directory
tmp_path.joinpath("samplefile.ini").write_text("# testdata")
tmp_path.joinpath("samplefile.ini").write_text("# testdata", encoding="utf-8")
def test_method(self):
with open("samplefile.ini") as f:
with open("samplefile.ini", encoding="utf-8") as f:
s = f.read()
assert "testdata" in s

View File

@@ -17,7 +17,8 @@ in the current directory and its subdirectories. More generally, pytest follows
Specifying which tests to run
------------------------------
Pytest supports several ways to run and select tests from the command-line.
Pytest supports several ways to run and select tests from the command-line or from a file
(see below for :ref:`reading arguments from file <args-from-file>`).
**Run tests in a module**
@@ -44,23 +45,34 @@ Use ``""`` instead of ``''`` in expression when running this on Windows
.. _nodeids:
**Run tests by node ids**
**Run tests by collection arguments**
Each collected test is assigned a unique ``nodeid`` which consist of the module filename followed
by specifiers like class names, function names and parameters from parametrization, separated by ``::`` characters.
Pass the module filename relative to the working directory, followed by specifiers like the class name and function name
separated by ``::`` characters, and parameters from parameterization enclosed in ``[]``.
To run a specific test within a module:
.. code-block:: bash
pytest test_mod.py::test_func
pytest tests/test_mod.py::test_func
Another example specifying a test method in the command line:
To run all tests in a class:
.. code-block:: bash
pytest test_mod.py::TestClass::test_method
pytest tests/test_mod.py::TestClass
Specifying a specific test method:
.. code-block:: bash
pytest tests/test_mod.py::TestClass::test_method
Specifying a specific parametrization of a test:
.. code-block:: bash
pytest tests/test_mod.py::test_func[x1,y2]
**Run tests by marker expressions**
@@ -80,6 +92,28 @@ For more information see :ref:`marks <mark>`.
This will import ``pkg.testing`` and use its filesystem location to find and run tests from.
.. _args-from-file:
**Read arguments from file**
.. versionadded:: 8.2
All of the above can be read from a file using the ``@`` prefix:
.. code-block:: bash
pytest @tests_to_run.txt
where ``tests_to_run.txt`` contains an entry per line, e.g.:
.. code-block:: text
tests/test_file.py
tests/test_mod.py::test_func[x1,y2]
tests/test_mod.py::TestClass
-m slow
This file can also be generated using ``pytest --collect-only -q`` and modified as needed.
Getting help on version, option names, environment variables
--------------------------------------------------------------
@@ -173,7 +207,8 @@ You can invoke ``pytest`` from Python code directly:
this acts as if you would call "pytest" from the command line.
It will not raise :class:`SystemExit` but return the :ref:`exit code <exit-codes>` instead.
You can pass in options and arguments:
If you don't pass it any arguments, ``main`` reads the arguments from the command line arguments of the process (:data:`sys.argv`), which may be undesirable.
You can pass in options and arguments explicitly:
.. code-block:: python

View File

@@ -56,23 +56,17 @@ The remaining hook functions will not be called in this case.
.. _`hookwrapper`:
hookwrapper: executing around other hooks
hook wrappers: executing around other hooks
-------------------------------------------------
.. currentmodule:: _pytest.core
pytest plugins can implement hook wrappers which wrap the execution
of other hook implementations. A hook wrapper is a generator function
which yields exactly once. When pytest invokes hooks it first executes
hook wrappers and passes the same arguments as to the regular hooks.
At the yield point of the hook wrapper pytest will execute the next hook
implementations and return their result to the yield point in the form of
a :py:class:`Result <pluggy._Result>` instance which encapsulates a result or
exception info. The yield point itself will thus typically not raise
exceptions (unless there are bugs).
implementations and return their result to the yield point, or will
propagate an exception if they raised.
Here is an example definition of a hook wrapper:
@@ -81,26 +75,35 @@ Here is an example definition of a hook wrapper:
import pytest
@pytest.hookimpl(hookwrapper=True)
@pytest.hookimpl(wrapper=True)
def pytest_pyfunc_call(pyfuncitem):
do_something_before_next_hook_executes()
outcome = yield
# outcome.excinfo may be None or a (cls, val, tb) tuple
# If the outcome is an exception, will raise the exception.
res = yield
res = outcome.get_result() # will raise if outcome was exception
new_res = post_process_result(res)
post_process_result(res)
# Override the return value to the plugin system.
return new_res
outcome.force_result(new_res) # to override the return value to the plugin system
The hook wrapper needs to return a result for the hook, or raise an exception.
Note that hook wrappers don't return results themselves, they merely
perform tracing or other side effects around the actual hook implementations.
If the result of the underlying hook is a mutable object, they may modify
that result but it's probably better to avoid it.
In many cases, the wrapper only needs to perform tracing or other side effects
around the actual hook implementations, in which case it can return the result
value of the ``yield``. The simplest (though useless) hook wrapper is
``return (yield)``.
In other cases, the wrapper wants the adjust or adapt the result, in which case
it can return a new value. If the result of the underlying hook is a mutable
object, the wrapper may modify that result, but it's probably better to avoid it.
If the hook implementation failed with an exception, the wrapper can handle that
exception using a ``try-catch-finally`` around the ``yield``, by propagating it,
suppressing it, or raising a different exception entirely.
For more information, consult the
:ref:`pluggy documentation about hookwrappers <pluggy:hookwrappers>`.
:ref:`pluggy documentation about hook wrappers <pluggy:hookwrappers>`.
.. _plugin-hookorder:
@@ -130,11 +133,14 @@ after others, i.e. the position in the ``N``-sized list of functions:
# Plugin 3
@pytest.hookimpl(hookwrapper=True)
@pytest.hookimpl(wrapper=True)
def pytest_collection_modifyitems(items):
# will execute even before the tryfirst one above!
outcome = yield
# will execute after all non-hookwrappers executed
try:
return (yield)
finally:
# will execute after all non-wrappers executed
...
Here is the order of execution:
@@ -149,13 +155,13 @@ Here is the order of execution:
Plugin1).
4. Plugin3's pytest_collection_modifyitems then executing the code after the yield
point. The yield receives a :py:class:`Result <pluggy._Result>` instance which encapsulates
the result from calling the non-wrappers. Wrappers shall not modify the result.
point. The yield receives the result from calling the non-wrappers, or raises
an exception if the non-wrappers raised.
It's possible to use ``tryfirst`` and ``trylast`` also in conjunction with
``hookwrapper=True`` in which case it will influence the ordering of hookwrappers
among each other.
It's possible to use ``tryfirst`` and ``trylast`` also on hook wrappers
in which case it will influence the ordering of hook wrappers among each other.
.. _`declaringhooks`:
Declaring new hooks
------------------------
@@ -165,13 +171,11 @@ Declaring new hooks
This is a quick overview on how to add new hooks and how they work in general, but a more complete
overview can be found in `the pluggy documentation <https://pluggy.readthedocs.io/en/latest/>`__.
.. currentmodule:: _pytest.hookspec
Plugins and ``conftest.py`` files may declare new hooks that can then be
implemented by other plugins in order to alter behaviour or interact with
the new plugin:
.. autofunction:: pytest_addhooks
.. autofunction:: _pytest.hookspec.pytest_addhooks
:noindex:
Hooks are usually declared as do-nothing functions that contain only

View File

@@ -46,24 +46,18 @@ Plugin discovery order at tool startup
5. by loading all plugins specified through the :envvar:`PYTEST_PLUGINS` environment variable.
6. by loading all :file:`conftest.py` files as inferred by the command line
invocation:
6. by loading all "initial ":file:`conftest.py` files:
- if no test paths are specified, use the current dir as a test path
- if exists, load ``conftest.py`` and ``test*/conftest.py`` relative
to the directory part of the first test path. After the ``conftest.py``
file is loaded, load all plugins specified in its
:globalvar:`pytest_plugins` variable if present.
Note that pytest does not find ``conftest.py`` files in deeper nested
sub directories at tool startup. It is usually a good idea to keep
your ``conftest.py`` file in the top level test or project root directory.
7. by recursively loading all plugins specified by the
:globalvar:`pytest_plugins` variable in ``conftest.py`` files.
- determine the test paths: specified on the command line, otherwise in
:confval:`testpaths` if defined and running from the rootdir, otherwise the
current dir
- for each test path, load ``conftest.py`` and ``test*/conftest.py`` relative
to the directory part of the test path, if exist. Before a ``conftest.py``
file is loaded, load ``conftest.py`` files in all of its parent directories.
After a ``conftest.py`` file is loaded, recursively load all plugins specified
in its :globalvar:`pytest_plugins` variable if present.
.. _`pytest/plugin`: http://bitbucket.org/pytest-dev/pytest/src/tip/pytest/plugin/
.. _`conftest.py plugins`:
.. _`localplugin`:
.. _`local conftest plugins`:
@@ -108,9 +102,9 @@ Here is how you might run it::
See also: :ref:`pythonpath`.
.. note::
Some hooks should be implemented only in plugins or conftest.py files situated at the
tests root directory due to how pytest discovers plugins during startup,
see the documentation of each hook for details.
Some hooks cannot be implemented in conftest.py files which are not
:ref:`initial <pluginorder>` due to how pytest discovers plugins during
startup. See the documentation of each hook for details.
Writing your own plugin
-----------------------
@@ -448,7 +442,7 @@ in our ``pytest.ini`` to tell pytest where to look for example files.
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 2 items

View File

@@ -1,9 +1,12 @@
:orphan:
.. sidebar:: Next Open Trainings
.. sidebar:: Next Open Trainings and Events
- `pytest tips and tricks for a better testsuite <https://ep2023.europython.eu/session/pytest-tips-and-tricks-for-a-better-testsuite>`_, at `Europython 2023 <https://ep2023.europython.eu/>`_, July 18th (3h), Prague/Remote
- `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 5th to 7th 2024 (3 day in-depth training), Leipzig/Remote
- `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_ (3 day in-depth training):
* **June 11th to 13th 2024**, Remote
* **March 4th to 6th 2025**, Leipzig, Germany / Remote
- `pytest development sprint <https://github.com/pytest-dev/pytest/discussions/11655>`_, **June 17th -- 22nd 2024**
- pytest tips and tricks for a better testsuite, `Europython 2024 <https://ep2024.europython.eu/>`_, **July 8th -- 14th 2024** (3h), Prague
Also see :doc:`previous talks and blogposts <talks>`.
@@ -18,7 +21,7 @@ The ``pytest`` framework makes it easy to write small, readable tests, and can
scale to support complex functional testing for applications and libraries.
``pytest`` requires: Python 3.7+ or PyPy3.
``pytest`` requires: Python 3.8+ or PyPy3.
**PyPI package name**: :pypi:`pytest`
@@ -43,7 +46,7 @@ To execute it:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
@@ -75,17 +78,17 @@ Features
- :ref:`Modular fixtures <fixture>` for managing small or parametrized long-lived test resources
- Can run :ref:`unittest <unittest>` (including trial) and :ref:`nose <noseintegration>` test suites out of the box
- Can run :ref:`unittest <unittest>` (including trial) test suites out of the box
- Python 3.7+ or PyPy 3
- Python 3.8+ or PyPy 3
- Rich plugin architecture, with over 800+ :ref:`external plugins <plugin-list>` and thriving community
- Rich plugin architecture, with over 1300+ :ref:`external plugins <plugin-list>` and thriving community
Documentation
-------------
* :ref:`Get started <get-started>` - install pytest and grasp its basics just twenty minutes
* :ref:`Get started <get-started>` - install pytest and grasp its basics in just twenty minutes
* :ref:`How-to guides <how-to>` - step-by-step guides, covering a vast range of use-cases and needs
* :ref:`Reference guides <reference>` - includes the complete pytest API reference, lists of plugins and more
* :ref:`Explanation <explanation>` - background, discussion of key topics, answers to higher-level questions

View File

@@ -90,7 +90,7 @@ and can also be used to hold pytest configuration if they have a ``[pytest]`` se
setup.cfg
~~~~~~~~~
``setup.cfg`` files are general purpose configuration files, used originally by :doc:`distutils <python:distutils/configfile>`, and can also be used to hold pytest configuration
``setup.cfg`` files are general purpose configuration files, used originally by ``distutils`` (now deprecated) and `setuptools <https://setuptools.pypa.io/en/latest/userguide/declarative_config.html>`__, and can also be used to hold pytest configuration
if they have a ``[tool:pytest]`` section.
.. code-block:: ini
@@ -177,13 +177,20 @@ Files will only be matched for configuration if:
* ``tox.ini``: contains a ``[pytest]`` section.
* ``setup.cfg``: contains a ``[tool:pytest]`` section.
Finally, a ``pyproject.toml`` file will be considered the ``configfile`` if no other match was found, in this case
even if it does not contain a ``[tool.pytest.ini_options]`` table (this was added in ``8.1``).
The files are considered in the order above. Options from multiple ``configfiles`` candidates
are never merged - the first match wins.
The configuration file also determines the value of the ``rootpath``.
The :class:`Config <pytest.Config>` object (accessible via hooks or through the :fixture:`pytestconfig` fixture)
will subsequently carry these attributes:
- :attr:`config.rootpath <pytest.Config.rootpath>`: the determined root directory, guaranteed to exist.
- :attr:`config.rootpath <pytest.Config.rootpath>`: the determined root directory, guaranteed to exist. It is used as
a reference directory for constructing test addresses ("nodeids") and can be used also by plugins for storing
per-testrun information.
- :attr:`config.inipath <pytest.Config.inipath>`: the determined ``configfile``, may be ``None``
(it is named ``inipath`` for historical reasons).
@@ -193,9 +200,7 @@ will subsequently carry these attributes:
versions of the older ``config.rootdir`` and ``config.inifile``, which have type
``py.path.local``, and still exist for backward compatibility.
The ``rootdir`` is used as a reference directory for constructing test
addresses ("nodeids") and can be used also by plugins for storing
per-testrun information.
Example:

View File

@@ -11,9 +11,6 @@ Fixtures reference
.. seealso:: :ref:`about-fixtures`
.. seealso:: :ref:`how-to-fixtures`
.. currentmodule:: _pytest.python
.. _`Dependency injection`: https://en.wikipedia.org/wiki/Dependency_injection
@@ -76,15 +73,13 @@ Built-in fixtures
:class:`pathlib.Path` objects.
:fixture:`tmpdir`
Provide a :class:`py.path.local` object to a temporary
Provide a `py.path.local <https://py.readthedocs.io/en/latest/path.html>`_ object to a temporary
directory which is unique to each test function;
replaced by :fixture:`tmp_path`.
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
:fixture:`tmpdir_factory`
Make session-scoped temporary directories and return
:class:`py.path.local` objects;
``py.path.local`` objects;
replaced by :fixture:`tmp_path_factory`.
@@ -98,7 +93,7 @@ Fixture availability is determined from the perspective of the test. A fixture
is only available for tests to request if they are in the scope that fixture is
defined in. If a fixture is defined inside a class, it can only be requested by
tests inside that class. But if a fixture is defined inside the global scope of
the module, than every test in that module, even if it's defined inside a class,
the module, then every test in that module, even if it's defined inside a class,
can request it.
Similarly, a test can also only be affected by an autouse fixture if that test

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
:tocdepth: 3
.. _`api-reference`:
API Reference
@@ -77,11 +79,13 @@ pytest.xfail
pytest.exit
~~~~~~~~~~~
.. autofunction:: pytest.exit(reason, [returncode=False, msg=None])
.. autofunction:: pytest.exit(reason, [returncode=None, msg=None])
pytest.main
~~~~~~~~~~~
**Tutorial**: :ref:`pytest.main-usage`
.. autofunction:: pytest.main
pytest.param
@@ -132,7 +136,7 @@ pytest.freeze_includes
Marks
-----
Marks can be used apply meta data to *test functions* (but not fixtures), which can then be accessed by
Marks can be used to apply metadata to *test functions* (but not fixtures), which can then be accessed by
fixtures or plugins.
@@ -160,8 +164,7 @@ Add warning filters to marked test items.
.. code-block:: python
@pytest.mark.filterwarnings("ignore:.*usage will be deprecated.*:DeprecationWarning")
def test_foo():
...
def test_foo(): ...
.. _`pytest.mark.parametrize ref`:
@@ -235,22 +238,23 @@ pytest.mark.xfail
Marks a test function as *expected to fail*.
.. py:function:: pytest.mark.xfail(condition=None, *, reason=None, raises=None, run=True, strict=False)
.. py:function:: pytest.mark.xfail(condition=False, *, reason=None, raises=None, run=True, strict=xfail_strict)
:type condition: bool or str
:param condition:
:keyword Union[bool, str] condition:
Condition for marking the test function as xfail (``True/False`` or a
:ref:`condition string <string conditions>`). If a bool, you also have
:ref:`condition string <string conditions>`). If a ``bool``, you also have
to specify ``reason`` (see :ref:`condition string <string conditions>`).
:keyword str reason:
Reason why the test function is marked as xfail.
:keyword Type[Exception] raises:
Exception subclass (or tuple of subclasses) expected to be raised by the test function; other exceptions will fail the test.
Exception class (or tuple of classes) expected to be raised by the test function; other exceptions will fail the test.
Note that subclasses of the classes passed will also result in a match (similar to how the ``except`` statement works).
:keyword bool run:
If the test function should actually be executed. If ``False``, the function will always xfail and will
Whether the test function should actually be executed. If ``False``, the function will always xfail and will
not be executed (useful if a function is segfaulting).
:keyword bool strict:
* If ``False`` (the default) the function will be shown in the terminal output as ``xfailed`` if it fails
* If ``False`` the function will be shown in the terminal output as ``xfailed`` if it fails
and as ``xpass`` if it passes. In both cases this will not cause the test suite to fail as a whole. This
is particularly useful to mark *flaky* tests (tests that fail at random) to be tackled later.
* If ``True``, the function will be shown in the terminal output as ``xfailed`` if it fails, but if it
@@ -258,6 +262,8 @@ Marks a test function as *expected to fail*.
that are always failing and there should be a clear indication if they unexpectedly start to pass (for example
a new release of a library fixes a known bug).
Defaults to :confval:`xfail_strict`, which is ``False`` by default.
Custom marks
~~~~~~~~~~~~
@@ -269,8 +275,7 @@ For example:
.. code-block:: python
@pytest.mark.timeout(10, "slow", method="thread")
def test_function():
...
def test_function(): ...
Will create and attach a :class:`Mark <pytest.Mark>` object to the collected
:class:`Item <pytest.Item>`, which can then be accessed by fixtures or hooks with
@@ -287,8 +292,7 @@ Example for using multiple custom markers:
@pytest.mark.timeout(10, "slow", method="thread")
@pytest.mark.slow
def test_function():
...
def test_function(): ...
When :meth:`Node.iter_markers <_pytest.nodes.Node.iter_markers>` or :meth:`Node.iter_markers_with_node <_pytest.nodes.Node.iter_markers_with_node>` is used with multiple markers, the marker closest to the function will be iterated over first. The above example will result in ``@pytest.mark.slow`` followed by ``@pytest.mark.timeout(...)``.
@@ -605,10 +609,30 @@ Hooks
**Tutorial**: :ref:`writing-plugins`
.. currentmodule:: _pytest.hookspec
Reference to all hooks which can be implemented by :ref:`conftest.py files <localplugin>` and :ref:`plugins <plugins>`.
@pytest.hookimpl
~~~~~~~~~~~~~~~~
.. function:: pytest.hookimpl
:decorator:
pytest's decorator for marking functions as hook implementations.
See :ref:`writinghooks` and :func:`pluggy.HookimplMarker`.
@pytest.hookspec
~~~~~~~~~~~~~~~~
.. function:: pytest.hookspec
:decorator:
pytest's decorator for marking functions as hook specifications.
See :ref:`declaringhooks` and :func:`pluggy.HookspecMarker`.
.. currentmodule:: _pytest.hookspec
Bootstrapping hooks
~~~~~~~~~~~~~~~~~~~
@@ -616,8 +640,6 @@ Bootstrapping hooks called for plugins registered early enough (internal and set
.. hook:: pytest_load_initial_conftests
.. autofunction:: pytest_load_initial_conftests
.. hook:: pytest_cmdline_preparse
.. autofunction:: pytest_cmdline_preparse
.. hook:: pytest_cmdline_parse
.. autofunction:: pytest_cmdline_parse
.. hook:: pytest_cmdline_main
@@ -655,6 +677,8 @@ Collection hooks
.. autofunction:: pytest_collection
.. hook:: pytest_ignore_collect
.. autofunction:: pytest_ignore_collect
.. hook:: pytest_collect_directory
.. autofunction:: pytest_collect_directory
.. hook:: pytest_collect_file
.. autofunction:: pytest_collect_file
.. hook:: pytest_pycollect_makemodule
@@ -783,23 +807,16 @@ reporting or interaction with exceptions:
.. autofunction:: pytest_leave_pdb
Objects
-------
Collection tree objects
-----------------------
Full reference to objects accessible from :ref:`fixtures <fixture>` or :ref:`hooks <hook-reference>`.
These are the collector and item classes (collectively called "nodes") which
make up the collection tree.
Node
~~~~
CallInfo
~~~~~~~~
.. autoclass:: pytest.CallInfo()
:members:
Class
~~~~~
.. autoclass:: pytest.Class()
.. autoclass:: _pytest.nodes.Node()
:members:
:show-inheritance:
@@ -810,32 +827,12 @@ Collector
:members:
:show-inheritance:
CollectReport
~~~~~~~~~~~~~
Item
~~~~
.. autoclass:: pytest.CollectReport()
.. autoclass:: pytest.Item()
:members:
:show-inheritance:
:inherited-members:
Config
~~~~~~
.. autoclass:: pytest.Config()
:members:
ExceptionInfo
~~~~~~~~~~~~~
.. autoclass:: pytest.ExceptionInfo()
:members:
ExitCode
~~~~~~~~
.. autoclass:: pytest.ExitCode
:members:
File
~~~~
@@ -844,14 +841,6 @@ File
:members:
:show-inheritance:
FixtureDef
~~~~~~~~~~
.. autoclass:: _pytest.fixtures.FixtureDef()
:members:
:show-inheritance:
FSCollector
~~~~~~~~~~~
@@ -859,6 +848,34 @@ FSCollector
:members:
:show-inheritance:
Session
~~~~~~~
.. autoclass:: pytest.Session()
:members:
:show-inheritance:
Package
~~~~~~~
.. autoclass:: pytest.Package()
:members:
:show-inheritance:
Module
~~~~~~
.. autoclass:: pytest.Module()
:members:
:show-inheritance:
Class
~~~~~
.. autoclass:: pytest.Class()
:members:
:show-inheritance:
Function
~~~~~~~~
@@ -873,10 +890,64 @@ FunctionDefinition
:members:
:show-inheritance:
Item
~~~~
.. autoclass:: pytest.Item()
Objects
-------
Objects accessible from :ref:`fixtures <fixture>` or :ref:`hooks <hook-reference>`
or importable from ``pytest``.
CallInfo
~~~~~~~~
.. autoclass:: pytest.CallInfo()
:members:
CollectReport
~~~~~~~~~~~~~
.. autoclass:: pytest.CollectReport()
:members:
:show-inheritance:
:inherited-members:
Config
~~~~~~
.. autoclass:: pytest.Config()
:members:
Dir
~~~
.. autoclass:: pytest.Dir()
:members:
Directory
~~~~~~~~~
.. autoclass:: pytest.Directory()
:members:
ExceptionInfo
~~~~~~~~~~~~~
.. autoclass:: pytest.ExceptionInfo()
:members:
ExitCode
~~~~~~~~
.. autoclass:: pytest.ExitCode
:members:
FixtureDef
~~~~~~~~~~
.. autoclass:: pytest.FixtureDef()
:members:
:show-inheritance:
@@ -907,19 +978,6 @@ Metafunc
.. autoclass:: pytest.Metafunc()
:members:
Module
~~~~~~
.. autoclass:: pytest.Module()
:members:
:show-inheritance:
Node
~~~~
.. autoclass:: _pytest.nodes.Node()
:members:
Parser
~~~~~~
@@ -941,13 +999,6 @@ PytestPluginManager
:inherited-members:
:show-inheritance:
Session
~~~~~~~
.. autoclass:: pytest.Session()
:members:
:show-inheritance:
TestReport
~~~~~~~~~~
@@ -962,10 +1013,10 @@ TestShortLogReport
.. autoclass:: pytest.TestShortLogReport()
:members:
_Result
Result
~~~~~~~
Result object used within :ref:`hook wrappers <hookwrapper>`, see :py:class:`_Result in the pluggy documentation <pluggy._callers._Result>` for more information.
Result object used within :ref:`hook wrappers <hookwrapper>`, see :py:class:`Result in the pluggy documentation <pluggy.Result>` for more information.
Stash
~~~~~
@@ -1066,6 +1117,11 @@ When set (regardless of value), pytest acknowledges that is running in a CI proc
This contains a command-line (parsed by the py:mod:`shlex` module) that will be **prepended** to the command line given
by the user, see :ref:`adding default options` for more information.
.. envvar:: PYTEST_VERSION
This environment variable is defined at the start of the pytest session and is undefined afterwards.
It contains the value of ``pytest.__version__``, and among other things can be used to easily check if a code is running from within a pytest run.
.. envvar:: PYTEST_CURRENT_TEST
This is not meant to be set by users, but is set by pytest internally with the name of the current test so other
@@ -1104,19 +1160,22 @@ When set to ``0``, pytest will not use color.
.. envvar:: NO_COLOR
When set (regardless of value), pytest will not use color in terminal output.
When set to a non-empty string (regardless of value), pytest will not use color in terminal output.
``PY_COLORS`` takes precedence over ``NO_COLOR``, which takes precedence over ``FORCE_COLOR``.
See `no-color.org <https://no-color.org/>`__ for other libraries supporting this community standard.
.. envvar:: FORCE_COLOR
When set (regardless of value), pytest will use color in terminal output.
When set to a non-empty string (regardless of value), pytest will use color in terminal output.
``PY_COLORS`` and ``NO_COLOR`` take precedence over ``FORCE_COLOR``.
Exceptions
----------
.. autoclass:: pytest.UsageError()
.. autoexception:: pytest.UsageError()
:show-inheritance:
.. autoexception:: pytest.FixtureLookupError()
:show-inheritance:
.. _`warnings ref`:
@@ -1150,7 +1209,7 @@ Custom warnings generated in some situations such as improper usage or deprecate
.. autoclass:: pytest.PytestReturnNotNoneWarning
:show-inheritance:
.. autoclass:: pytest.PytestRemovedIn8Warning
.. autoclass:: pytest.PytestRemovedIn9Warning
:show-inheritance:
.. autoclass:: pytest.PytestUnhandledCoroutineWarning
@@ -1220,6 +1279,18 @@ passed multiple times. The expected format is ``name=value``. For example::
variables, that will be expanded. For more information about cache plugin
please refer to :ref:`cache_provider`.
.. confval:: consider_namespace_packages
Controls if pytest should attempt to identify `namespace packages <https://packaging.python.org/en/latest/guides/packaging-namespace-packages>`__
when collecting Python modules. Default is ``False``.
Set to ``True`` if the package you are testing is part of a namespace package.
Only `native namespace packages <https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#native-namespace-packages>`__
are supported, with no plans to support `legacy namespace packages <https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#legacy-namespace-packages>`__.
.. versionadded:: 8.1
.. confval:: console_output_style
Sets the console output style while running tests:
@@ -1619,11 +1690,11 @@ passed multiple times. The expected format is ``name=value``. For example::
Additionally, ``pytest`` will attempt to intelligently identify and ignore a
virtualenv by the presence of an activation script. Any directory deemed to
be the root of a virtual environment will not be considered during test
collection unless ``collectinvirtualenv`` is given. Note also that
``norecursedirs`` takes precedence over ``collectinvirtualenv``; e.g. if
collection unless ``--collect-in-virtualenv`` is given. Note also that
``norecursedirs`` takes precedence over ``--collect-in-virtualenv``; e.g. if
you intend to run tests in a virtualenv with a base directory that matches
``'.*'`` you *must* override ``norecursedirs`` in addition to using the
``collectinvirtualenv`` flag.
``--collect-in-virtualenv`` flag.
.. confval:: python_classes
@@ -1798,6 +1869,32 @@ passed multiple times. The expected format is ``name=value``. For example::
clean_db
.. confval:: verbosity_assertions
Set a verbosity level specifically for assertion related output, overriding the application wide level.
.. code-block:: ini
[pytest]
verbosity_assertions = 2
Defaults to application wide verbosity level (via the ``-v`` command-line option). A special value of
"auto" can be used to explicitly use the global verbosity level.
.. confval:: verbosity_test_cases
Set a verbosity level specifically for test case execution related output, overriding the application wide level.
.. code-block:: ini
[pytest]
verbosity_test_cases = 2
Defaults to application wide verbosity level (via the ``-v`` command-line option). A special value of
"auto" can be used to explicitly use the global verbosity level.
.. confval:: xfail_strict
If set to ``True``, tests marked with ``@pytest.mark.xfail`` that actually succeed will by default fail the
@@ -1871,8 +1968,12 @@ All the command-line flags can be obtained by running ``pytest --help``::
tests. Optional argument: glob (default: '*').
--cache-clear Remove all cache contents at start of test run
--lfnf={all,none}, --last-failed-no-failures={all,none}
Which tests to run with no previously (known)
failures
With ``--lf``, determines whether to execute tests
when there are no previously (known) failures or
when no cached ``lastfailed`` data was found.
``all`` (the default) runs the full test suite
again. ``none`` just emits a message about no known
failures and exits successfully.
--sw, --stepwise Exit on test failure and continue from last failing
test next time
--sw-skip, --stepwise-skip
@@ -1957,7 +2058,7 @@ All the command-line flags can be obtained by running ``pytest --help``::
failure
--doctest-glob=pat Doctests file matching pattern, default: test*.txt
--doctest-ignore-import-errors
Ignore doctest ImportErrors
Ignore doctest collection errors
--doctest-continue-on-failure
For a given doctest, continue to run after the first
failure
@@ -2006,6 +2107,8 @@ All the command-line flags can be obtained by running ``pytest --help``::
--log-cli-date-format=LOG_CLI_DATE_FORMAT
Log date format used by the logging module
--log-file=LOG_FILE Path to a file when logging will be written to
--log-file-mode={w,a}
Log file open mode
--log-file-level=LOG_FILE_LEVEL
Log file logging level
--log-file-format=LOG_FILE_FORMAT
@@ -2021,7 +2124,7 @@ All the command-line flags can be obtained by running ``pytest --help``::
[pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg|pyproject.toml file found:
markers (linelist): Markers for test functions
markers (linelist): Register new markers for test functions
empty_parameter_set_mark (string):
Default marker for empty parametersets
norecursedirs (args): Directory patterns to avoid for recursion
@@ -2031,6 +2134,9 @@ All the command-line flags can be obtained by running ``pytest --help``::
Each line specifies a pattern for
warnings.filterwarnings. Processed after
-W/--pythonwarnings.
consider_namespace_packages (bool):
Consider namespace packages when resolving module
names during import
usefixtures (args): List of default fixtures to be used with this
project
python_files (args): Glob-style file patterns for Python test module
@@ -2049,6 +2155,11 @@ All the command-line flags can be obtained by running ``pytest --help``::
progress information ("progress" (percentage) |
"count" | "progress-even-when-capture-no" (forces
progress even when capture=no)
verbosity_test_cases (string):
Specify a verbosity level for test case execution,
overriding the main level. Higher levels will
provide more detailed information about each test
case executed.
xfail_strict (bool): Default for the strict parameter of xfail markers
when not given explicitly (default: False)
tmp_path_retention_count (string):
@@ -2062,6 +2173,10 @@ All the command-line flags can be obtained by running ``pytest --help``::
enable_assertion_pass_hook (bool):
Enables the pytest_assertion_pass hook. Make sure to
delete any previously generated pyc cache files.
verbosity_assertions (string):
Specify a verbosity level for assertions, overriding
the main level. Higher levels will provide more
detailed explanation when an assertion fails.
junit_suite_name (string):
Test suite name for JUnit report
junit_logging (string):
@@ -2092,6 +2207,8 @@ All the command-line flags can be obtained by running ``pytest --help``::
log_cli_date_format (string):
Default value for --log-cli-date-format
log_file (string): Default value for --log-file
log_file_mode (string):
Default value for --log-file-mode
log_file_level (string):
Default value for --log-file-level
log_file_format (string):

View File

@@ -1,8 +1,8 @@
pallets-sphinx-themes
pluggy>=1.0
pluggy>=1.5.0
pygments-pytest>=2.3.0
sphinx-removed-in>=0.2.0
sphinx>=5,<6
sphinx>=7
sphinxcontrib-trio
sphinxcontrib-svg2pdfconverter
# Pin packaging because it no longer handles 'latest' version, which

View File

@@ -3,6 +3,7 @@ from pathlib import Path
import requests
issues_url = "https://api.github.com/repos/pytest-dev/pytest/issues"

View File

@@ -1,14 +1,291 @@
[build-system]
requires = [
# sync with setup.py until we discard non-pep-517/518
"setuptools>=45.0",
"setuptools-scm[toml]>=6.2.3",
[project]
name = "pytest"
description = "pytest: simple powerful testing with Python"
readme = "README.rst"
keywords = [
"test",
"unittest",
]
license = {text = "MIT"}
authors = [
{name = "Holger Krekel"},
{name = "Bruno Oliveira"},
{name = "Ronny Pfannschmidt"},
{name = "Floris Bruynooghe"},
{name = "Brianna Laugher"},
{name = "Florian Bruhin"},
{name = "Others (See AUTHORS)"},
]
requires-python = ">=3.8"
classifiers = [
"Development Status :: 6 - Mature",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Operating System :: Unix",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Testing",
"Topic :: Utilities",
]
dynamic = [
"version",
]
dependencies = [
'colorama; sys_platform == "win32"',
'exceptiongroup>=1.0.0rc8; python_version < "3.11"',
"iniconfig",
"packaging",
"pluggy<2.0,>=1.5",
'tomli>=1; python_version < "3.11"',
]
[project.optional-dependencies]
dev = [
"argcomplete",
"attrs>=19.2",
"hypothesis>=3.56",
"mock",
"pygments>=2.7.2",
"requests",
"setuptools",
"xmlschema",
]
[project.urls]
Changelog = "https://docs.pytest.org/en/stable/changelog.html"
Homepage = "https://docs.pytest.org/en/latest/"
Source = "https://github.com/pytest-dev/pytest"
Tracker = "https://github.com/pytest-dev/pytest/issues"
Twitter = "https://twitter.com/pytestdotorg"
[project.scripts]
"py.test" = "pytest:console_main"
pytest = "pytest:console_main"
[build-system]
build-backend = "setuptools.build_meta"
requires = [
"setuptools>=61",
"setuptools-scm[toml]>=6.2.3",
]
[tool.setuptools.package-data]
"_pytest" = ["py.typed"]
"pytest" = ["py.typed"]
[tool.setuptools_scm]
write_to = "src/_pytest/_version.py"
[tool.black]
target-version = ['py38']
[tool.ruff]
src = ["src"]
line-length = 88
[tool.ruff.format]
docstring-code-format = true
[tool.ruff.lint]
select = [
"B", # bugbear
"D", # pydocstyle
"E", # pycodestyle
"F", # pyflakes
"I", # isort
"PYI", # flake8-pyi
"UP", # pyupgrade
"RUF", # ruff
"W", # pycodestyle
"PIE", # flake8-pie
"PGH004", # pygrep-hooks - Use specific rule codes when using noqa
"PLE", # pylint error
"PLW", # pylint warning
"PLR1714", # Consider merging multiple comparisons
]
ignore = [
# bugbear ignore
"B004", # Using `hasattr(x, "__call__")` to test if x is callable is unreliable.
"B007", # Loop control variable `i` not used within loop body
"B009", # Do not call `getattr` with a constant attribute value
"B010", # [*] Do not call `setattr` with a constant attribute value.
"B011", # Do not `assert False` (`python -O` removes these calls)
"B028", # No explicit `stacklevel` keyword argument found
# pycodestyle ignore
# pytest can do weird low-level things, and we usually know
# what we're doing when we use type(..) is ...
"E721", # Do not compare types, use `isinstance()`
# pydocstyle ignore
"D100", # Missing docstring in public module
"D101", # Missing docstring in public class
"D102", # Missing docstring in public method
"D103", # Missing docstring in public function
"D104", # Missing docstring in public package
"D105", # Missing docstring in magic method
"D106", # Missing docstring in public nested class
"D107", # Missing docstring in `__init__`
"D209", # [*] Multi-line docstring closing quotes should be on a separate line
"D205", # 1 blank line required between summary line and description
"D400", # First line should end with a period
"D401", # First line of docstring should be in imperative mood
"D402", # First line should not be the function's signature
"D404", # First word of the docstring should not be "This"
"D415", # First line should end with a period, question mark, or exclamation point
# ruff ignore
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
# pylint ignore
"PLW0603", # Using the global statement
"PLW0120", # remove the else and dedent its contents
"PLW2901", # for loop variable overwritten by assignment target
"PLR5501", # Use `elif` instead of `else` then `if`
]
[tool.ruff.lint.pycodestyle]
# In order to be able to format for 88 char in ruff format
max-line-length = 120
[tool.ruff.lint.pydocstyle]
convention = "pep257"
[tool.ruff.lint.isort]
force-single-line = true
combine-as-imports = true
force-sort-within-sections = true
order-by-type = false
known-local-folder = ["pytest", "_pytest"]
lines-after-imports = 2
[tool.ruff.lint.per-file-ignores]
"src/_pytest/_py/**/*.py" = ["B", "PYI"]
"src/_pytest/_version.py" = ["I001"]
"testing/python/approx.py" = ["B015"]
[tool.pylint.main]
# Maximum number of characters on a single line.
max-line-length = 120
disable= [
"abstract-method",
"arguments-differ",
"arguments-renamed",
"assigning-non-slot",
"attribute-defined-outside-init",
"bad-classmethod-argument",
"bad-mcs-method-argument",
"broad-exception-caught",
"broad-exception-raised",
"cell-var-from-loop",
"comparison-of-constants",
"comparison-with-callable",
"comparison-with-itself",
"condition-evals-to-constant",
"consider-using-dict-items",
"consider-using-enumerate",
"consider-using-from-import",
"consider-using-f-string",
"consider-using-in",
"consider-using-sys-exit",
"consider-using-ternary",
"consider-using-with",
"cyclic-import",
"disallowed-name",
"duplicate-code",
"eval-used",
"exec-used",
"expression-not-assigned",
"fixme",
"global-statement",
"implicit-str-concat",
"import-error",
"import-outside-toplevel",
"inconsistent-return-statements",
"invalid-bool-returned",
"invalid-name",
"invalid-repr-returned",
"invalid-str-returned",
"keyword-arg-before-vararg",
"line-too-long",
"method-hidden",
"misplaced-bare-raise",
"missing-docstring",
"missing-timeout",
"multiple-statements",
"no-else-break",
"no-else-continue",
"no-else-raise",
"no-else-return",
"no-member",
"no-name-in-module",
"no-self-argument",
"not-an-iterable",
"not-callable",
"pointless-exception-statement",
"pointless-statement",
"pointless-string-statement",
"protected-access",
"raise-missing-from",
"redefined-argument-from-local",
"redefined-builtin",
"redefined-outer-name",
"reimported",
"simplifiable-condition",
"simplifiable-if-expression",
"singleton-comparison",
"superfluous-parens",
"super-init-not-called",
"too-few-public-methods",
"too-many-ancestors",
"too-many-arguments",
"too-many-branches",
"too-many-function-args",
"too-many-instance-attributes",
"too-many-lines",
"too-many-locals",
"too-many-nested-blocks",
"too-many-public-methods",
"too-many-return-statements",
"too-many-statements",
"try-except-raise",
"typevar-name-incorrect-variance",
"unbalanced-tuple-unpacking",
"undefined-loop-variable",
"undefined-variable",
"unexpected-keyword-arg",
"unidiomatic-typecheck",
"unnecessary-comprehension",
"unnecessary-dunder-call",
"unnecessary-lambda",
"unnecessary-lambda-assignment",
"unpacking-non-sequence",
"unspecified-encoding",
"unsubscriptable-object",
"unused-argument",
"unused-import",
"unused-variable",
"used-before-assignment",
"use-dict-literal",
"use-implicit-booleaness-not-comparison",
"use-implicit-booleaness-not-len",
"useless-else-on-loop",
"useless-import-alias",
"useless-return",
"use-maxsplit-arg",
"using-constant-test",
"wrong-import-order",
]
[tool.check-wheel-contents]
# check-wheel-contents is executed by the build-and-inspect-python-package action.
# W009: Wheel contains multiple toplevel library entries
ignore = "W009"
[tool.pyproject-fmt]
indent = 4
[tool.pytest.ini_options]
minversion = "2.0"
addopts = "-rfEX -p pytester --strict-markers"
@@ -17,7 +294,12 @@ python_classes = ["Test", "Acceptance"]
python_functions = ["test"]
# NOTE: "doc" is not included here, but gets tested explicitly via "doctesting".
testpaths = ["testing"]
norecursedirs = ["testing/example_scripts"]
norecursedirs = [
"testing/example_scripts",
".*",
"build",
"dist",
]
xfail_strict = true
filterwarnings = [
"error",
@@ -63,7 +345,6 @@ markers = [
"uses_pexpect",
]
[tool.towncrier]
package = "pytest"
package_dir = "src"
@@ -112,10 +393,18 @@ template = "changelog/_template.rst"
name = "Trivial/Internal Changes"
showcontent = true
[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"
[tool.mypy]
files = ["src", "testing", "scripts"]
mypy_path = ["src"]
check_untyped_defs = true
disallow_any_generics = true
disallow_untyped_defs = true
ignore_missing_imports = true
show_error_codes = true
strict_equality = true
warn_redundant_casts = true
warn_return_any = true
warn_unreachable = true
warn_unused_configs = true
no_implicit_reexport = true
warn_unused_ignores = true

1
scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
latest-release-notes.md

View File

@@ -0,0 +1,67 @@
# mypy: disallow-untyped-defs
"""
Script used to generate a Markdown file containing only the changelog entries of a specific pytest release, which
is then published as a GitHub Release during deploy (see workflows/deploy.yml).
The script requires ``pandoc`` to be previously installed in the system -- we need to convert from RST (the format of
our CHANGELOG) into Markdown (which is required by GitHub Releases).
Requires Python3.6+.
"""
from pathlib import Path
import re
import sys
from typing import Sequence
import pypandoc
def extract_changelog_entries_for(version: str) -> str:
p = Path(__file__).parent.parent / "doc/en/changelog.rst"
changelog_lines = p.read_text(encoding="UTF-8").splitlines()
title_regex = re.compile(r"pytest (\d\.\d+\.\d+\w*) \(\d{4}-\d{2}-\d{2}\)")
consuming_version = False
version_lines = []
for line in changelog_lines:
m = title_regex.match(line)
if m:
# Found the version we want: start to consume lines until we find the next version title.
if m.group(1) == version:
consuming_version = True
# Found a new version title while parsing the version we want: break out.
elif consuming_version:
break
if consuming_version:
version_lines.append(line)
return "\n".join(version_lines)
def convert_rst_to_md(text: str) -> str:
result = pypandoc.convert_text(
text, "md", format="rst", extra_args=["--wrap=preserve"]
)
assert isinstance(result, str), repr(result)
return result
def main(argv: Sequence[str]) -> int:
if len(argv) != 3:
print("Usage: generate-gh-release-notes VERSION FILE")
return 2
version, filename = argv[1:3]
print(f"Generating GitHub release notes for version {version}")
rst_body = extract_changelog_entries_for(version)
md_body = convert_rst_to_md(rst_body)
Path(filename).write_text(md_body, encoding="UTF-8")
print()
print(f"Done: {filename}")
print()
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))

Some files were not shown because too many files have changed in this diff Show More