Skip to main content

assert-pytest-fixture-name-is-needed

Assert that every pytest fixture filed under a name of its own needs one.

Why

A name argument on a fixture decorator files that fixture under a name other than its function's, and there is one reason to write it. pylint objects when a name defined at the top of a module is bound again inside a function in it, and a test asks for a fixture by taking a parameter of the fixture's name, so renaming the function ends the clash.

Where nothing in the file binds that name there is no clash, and the argument costs twice over. Whoever has one file open copies it into the next, so the shape spreads. And it hides the fixture from every check that reads for the name of a function, which is how a fixture nothing calls any more stays in the tree: the check searches for the name of the function and never for the name a test asks for.

So this tool reads the argument as a claim about the file it sits in and checks it. A file whose fixtures all need their names passes silently.

Installation

pip install assert-pytest-fixture-name-is-needed

Usage

# Every test tree this repository publishes
assert-pytest-fixture-name-is-needed test

# The same, leaving out tests somebody else wrote
assert-pytest-fixture-name-is-needed 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 Every filed name is needed
1 A filed name is needed by nothing
2 A tree was missing, unreadable, or would not parse

What counts as a fixture

A decorator that calls something named fixture, so @pytest.fixture, a plain @fixture imported from pytest, and the same factory a plugin re-exports are all read. A bare decorator with no call carries no argument to be needless and is left alone, as is a name computed rather than written out, which cannot be checked against anything.

A fixture filed under the name it already has is left alone too. The argument there is redundant whatever the file binds, so it says nothing about the bindings and this tool has nothing to report about it.

What counts as a binding

Every name bound anywhere below the top level of the file, because pylint objects to all of them alike:

Bound by Example
A parameter def test_x(config):
An assignment config = build()
A loop variable for config in rows:
A context manager target with open(p) as config:
A comprehension variable [config for config in rows]
A caught exception except KeyError as config:
An import from etc import config
A match capture case {"a": config}:
A nested definition def config():

The set has to be that wide. Narrowing it to parameters is the mistake this tool exists to stop somebody making: two helpers assigning a local named config beside a fixture filed as config are a real clash, and a tool that asked only about parameters would tell the next reader to rename the function and take two new pylint findings for it.

A comprehension and a lambda are scopes wherever they are written, so what they bind counts even at the top level of the file. Everything else written at the top level is the fixture's own neighbourhood rather than an inner scope, and binds nothing this tool counts.

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.

GitHub Actions

- name: Assert every fixture name is needed
  uses: 10U-Labs/assert-pytest-fixture-name-is-needed@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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file assert_pytest_fixture_name_is_needed-20260830060105.tar.gz.

File metadata

File hashes

Hashes for assert_pytest_fixture_name_is_needed-20260830060105.tar.gz
Algorithm Hash digest
SHA256 69589958db9cce6157b0674891ba040c61ff02f3d9706a069e3e2056a9a02580
MD5 682483d2efc1e50a0c6ec4bebc6a7870
BLAKE2b-256 a488db6bf425f46298f8183a919f08cf646705557ec9aa5156adfe7afdac5014

See more details on using hashes here.

Provenance

The following attestation bundles were made for assert_pytest_fixture_name_is_needed-20260830060105.tar.gz:

Publisher: release.yml on 10U-Labs/assert-pytest-fixture-name-is-needed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file assert_pytest_fixture_name_is_needed-20260830060105-py3-none-any.whl.

File metadata

File hashes

Hashes for assert_pytest_fixture_name_is_needed-20260830060105-py3-none-any.whl
Algorithm Hash digest
SHA256 84d4128129a704923f8449381023657946b125da4ffa82e047fcac04509c65ce
MD5 687c0e8efca84f5f30d4215c0cb03abd
BLAKE2b-256 e8ddf0ae96f73a1dabbe5cd60107bb616dc7fb4419e97469ded6867bd752850b

See more details on using hashes here.

Provenance

The following attestation bundles were made for assert_pytest_fixture_name_is_needed-20260830060105-py3-none-any.whl:

Publisher: release.yml on 10U-Labs/assert-pytest-fixture-name-is-needed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

20260830060105 This release

2 files

20260825093937

2 files

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