Skip to main content

assert-no-pytest-plugin-declarations

Assert that no conftest declares a pytest plugin.

Why

pytest loads a plugin once. Whether a given pytest_plugins line is doing anything is therefore decided by files other than the one it is written in — by a module in another directory, or by a conftest further up the path that has already asked for the same module. Reading the line tells you nothing about whether it is load-bearing, and no amount of reading the file around it will either.

A fixture has two ways to reach a suite that do not have that problem. It can be inherited, by sitting in a conftest above the suite that wants it. Or it can be imported, by a from ... import ... written in the conftest that needs it. Both are ordinary Python that ordinary tools follow: pylint reports the import nothing uses, mypy resolves it, and the sibling tool assert-pytest-fixture-name-is-needed reads the name it binds. A pytest_plugins line is a second mechanism for the same job that none of the three can see through.

It also holds package dependencies up, silently. A declaration that registers no fixture at all still imports its module, and so keeps that module's own imports load-bearing with nothing anywhere saying so. The line cannot be deleted without a reader first working out, across the whole tree, what would stop being imported if it went.

So the rule is the whole of it. Not a redeclaration, not a duplicate of one further up: any declaration at all.

Installation

pip install assert-no-pytest-plugin-declarations

Usage

# Every test tree this repository publishes
assert-no-pytest-plugin-declarations test

# The same, leaving out tests somebody else wrote
assert-no-pytest-plugin-declarations test \
  --exclude 'test/vendor/*'

Options

Option Effect
--exclude PATTERNS Comma-separated globs to leave out.
--annotate Print each finding as a GitHub Actions ::error annotation.
--quiet Print nothing; report through the exit code.
--count Print only how many findings there were.
--verbose Print the files read, the findings and a summary.
--fail-fast Stop at the first finding.
--warn-only Always exit 0.

Exit codes

Code Meaning
0 No file declares a pytest plugin
1 A file declares a pytest plugin
2 A tree was missing, unreadable, or would not parse

What counts as a declaration

Any assignment to the name pytest_plugins, whatever it is assigned:

Written as Example
A list pytest_plugins = ["fixtures.aws"]
A string pytest_plugins = "fixtures.aws"
An annotation pytest_plugins: list[str] = []
An addition pytest_plugins += ["fixtures.aws"]
One target of several pytest_plugins = names = []

The value is never inspected, because the declaration this tool most wants to refuse is the one whose value cannot be worked out by reading: a name built elsewhere, or a list a loop appends to. An empty list is a finding like any other. It registers nothing today and is an invitation to the next person to add an entry rather than a conftest.

What is walked

A directory argument is read recursively for *.py files. .git, __pycache__ and node_modules are skipped, and everything else you want left out goes in --exclude. Each file is read on its own and needs nothing from any other, so a single file is as valid an argument as a tree.

Every Python file is read, not only files named conftest.py. pytest honours the name in a conftest and in a test module, and a line that sits anywhere else is one that starts working the day the file is renamed or its contents are moved.

GitHub Actions

- name: Assert no conftest declares a pytest plugin
  uses: 10U-Labs/assert-no-pytest-plugin-declarations@latest
  with:
    trees: test

annotate defaults to true there, so each finding lands on the line it names in the diff.

License

Apache-2.0

Metadata

Release files for assert-no-pytest-plugin-declarations 20260902062339

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for assert-no-pytest-plugin-declarations 20260902062339
File Size Uploaded Provenance
assert_no_pytest_plugin_declarations-20260902062339.tar.gz 31.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for assert-no-pytest-plugin-declarations 20260902062339
File Interpreter ABI Platform
assert_no_pytest_plugin_declarations-20260902062339-py3-none-any.whl Python 3 none any Details

Total release size: 45.1 kB

Release files / assert_no_pytest_plugin_declarations-20260902062339.tar.gz

Download URL assert_no_pytest_plugin_declarations-20260902062339.tar.gz
Size 31.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c85114ccaf00107aa051f9ceac462d416bac65535b32b099269339cf8ece706a
BLAKE2b-256 checksum
How to use checksums
68f6984567c9b4bdf376631ae6d3be9638d9d82ba908d933a1ba78a57becb1f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / assert_no_pytest_plugin_declarations-20260902062339-py3-none-any.whl

Download URL assert_no_pytest_plugin_declarations-20260902062339-py3-none-any.whl
Size 13.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17da8858a05fd6cf6a986be5161e627e5dcab839eb3c72019f2e12ab81479818
BLAKE2b-256 checksum
How to use checksums
a9bd7f39cec138301e097eecfa979ab527f6bbffe2b7efd780b2a4eb51bd93b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Security for assert-no-pytest-plugin-declarations 20260902062339

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for assert_no_pytest_plugin_declarations-20260902062339.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page