---
title: "pytest Breaking Changes on PyPI | Since.dev"
description: "What each pytest release removed, renamed or changed: 25 breaking changes in 3 versions on PyPI, each with its source."
canonical_url: https://since.dev/packages/pypi/pytest
last_updated: 2025-12-06
---

# pytest breaking changes

Every breaking API change we have recorded in pytest on PyPI: 25 breaking changes in 3 versions. Below are its newest 3 versions, removals and renames first, each with its source.

Newest change December 6, 2025

## 9.0.2

2 breaking changes, first published December 6, 2025.

- **Behavior changed**  

When the TERM environment variable is dumb, pytest no longer emits terminal escape codes, even if the terminal progress plugin is enabled. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.2)
- **Default changed**  

The terminal progress feature added in 9.0.0 is off by default, except on Windows. Pass -p terminalprogress to enable it again. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.2)

## 9.0.0

9 breaking changes, first published November 8, 2025.

- **Removed**  

Python 3.9 is no longer supported following its end of life. Users on Python 3.9 must upgrade their interpreter. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed**  

CI mode is only enabled when CI or BUILD_NUMBER is defined and non-empty. Empty values no longer trigger CI mode. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed**  

Passing overlapping paths such as a/ and a/b now runs only the prefix, and repeated file arguments run once. Use --keep-duplicates to keep the old behavior. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed**  

Deprecated features that emit PytestRemovedIn9Warning now fail instead of warning. Update code that uses these features, or ignore the warning category during 9.0.x. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed**  

An empty hidden .pytest.ini file is now used as the configuration file, which can change which config applies. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed** `--override-ini`  

The -o and --override-ini overrides are now applied during startup rather than during config.getini. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed** `--version`  

A single --version is processed early and only takes effect when passed on the command line. Settings from PYTEST_ADDOPTS or addopts no longer apply to it. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Behavior changed** `pytester.plugins`  

Non-string entries in pytester.plugins now raise an error in subprocess mode instead of being ignored. Specify plugins by name or use in-process runs. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)
- **Configuration changed**  

The minimum required versions of iniconfig and packaging were increased. Installations with older versions must upgrade them. [github.com](https://github.com/pytest-dev/pytest/releases/tag/9.0.0)

## 8.4.0

14 breaking changes, first published June 2, 2025.

- **Removed**  

Python 3.8 is no longer supported following its end of life. Users on Python 3.8 must upgrade their interpreter to keep using this pytest release. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Removed** `pytest.PytestReturnNotNoneWarning`  

pytest.PytestReturnNotNoneWarning was removed in pytest 8.4.0 [pypi.org](https://pypi.org/project/pytest/8.4.0/)
- **Removed** `pytest.PytestUnhandledCoroutineWarning`  

pytest.PytestUnhandledCoroutineWarning was removed in pytest 8.4.0 [pypi.org](https://pypi.org/project/pytest/8.4.0/)
- **Behavior changed**  

Async tests without a suitable plugin now fail rather than warning and skipping. Install an async plugin such as pytest-asyncio to run them. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Behavior changed**  

Yield-based test functions now raise an explicit error; they were previously marked as expected failures. Convert them to regular test functions. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Behavior changed**  

Test functions that return any value other than None now fail instead of issuing a warning. Remove return values from tests. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Behavior changed** `--stepwise`  

Stepwise mode no longer forgets the last failed test when pytest runs later without the flag; state resets only when the suite changes. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Behavior changed** `pytest.approx`  

The repr of pytest.approx now shows tolerances between 0.001 and 1000 as decimals instead of scientific notation. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Behavior changed** `pytest.mark.usefixtures`  

Using pytest.mark.usefixtures on pytest.param now produces an error instead of silently doing nothing. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)
- **Behavior changed** `pytest.mark.xfail`  

Tests xfailed via the marker no longer have a "reason: " prefix in the report message, matching pytest.fail xfails. [github.com](https://github.com/pytest-dev/pytest/releases/tag/8.4.0)

And 4 more in this version.

## Check your code

These are the changes. To see which of them reach your code, [scan a public repository](https://since.dev/scan.md), or have your coding agent call `check_code` with your manifest or lockfile over [MCP](https://since.dev/docs.md#mcp). [The API](https://since.dev/docs.md#api) reads every change in every version, not only the newest. On Team and up, a fix pull request opens for the changes that reach a connected repository. Nothing merges or deploys.

## Put your code on continuous management.

Scan a public repository now, or give your agent one line.

### See how out of date your code is.

[Scan a repository](https://since.dev/scan.md). Any public GitHub repository. No sign-in.

### Tell your agent what changed since it was trained.

`claude mcp add --transport http since https://api.since.dev/mcp`

---

Every page on this site as Markdown: https://since.dev/sitemap.md. For agents: https://since.dev/llms.txt.
