pytest-autofixture
Use pytest fixtures by bare name. Tests and fixtures can reference any fixture without declaring it as a function parameter.
Install
pip install pytest-autofixture
Requires Python 3.11+ and pytest 8.4+. The plugin is active once installed; turn it off for a run with -p no:autofixture.
Usage
Any name in a test or fixture body that would otherwise raise NameError is looked up as a fixture. Lookup is lazy, so a fixture is set up only if the code reaches it, and scope, overrides and teardown work as they do for declared fixtures. Declared parameters still work and mix freely with bare names.
Fixtures resolve their dependencies from where the test is, so an inner class can override one value and outer fixtures pick it up, like a nested let in RSpec:
@pytest.fixture
def role():
return "member"
@pytest.fixture
def user():
return User(role=role)
def test_member():
assert not user.can_delete()
class TestAdmin:
@pytest.fixture
def role(self):
return "admin"
def test_admin(self):
assert user.can_delete()
parametrize needs no declaration either:
@pytest.mark.parametrize("role", ["admin", "owner"])
def test_can_delete():
assert user.can_delete()
A parametrized name belongs to the test, like an argument, so in the test body it beats a builtin or module global of the same name: parametrize("input", ...) is fine. Fixture bodies keep the real builtin or global.
let
let defines a one-line fixture where it's written, at module level or in a test class, like RSpec's let(:role) { "member" }:
from pytest_autofixture import let
let.role = "member"
let.user = lambda: User(role=role)
class TestAdmin:
let.role = "admin"
def test_admin(self):
assert user.can_delete()
What you assign decides how it behaves:
- A
lambdais called on first use, at most once per test, and can use other fixtures by bare name. - Anything else is deep-copied for each test, so
let.items = []orlet.user = User()starts fresh every time. Strings, numbers, classes and functions pass through as-is (let.model = Useris the class itself). If a value can't be copied, or must stay one shared object, use a lambda.
A let in a class overrides a fixture of the same name from outside it or from a base class, and can build on the value it replaces, like RSpec's super(): let.role = lambda: role.upper() gets the outer role.
let raises TypeError on the spot for a lambda with parameters, a value that can't be copied, or a name already taken by a builtin or module global, such as let.id or let.json after import json (the other name would always win).
Use a regular fixture when you need more than one expression, a scope, params or teardown. There's no special subject: let.subject = lambda: Order(items=items) is just a fixture named subject.
Coming from RSpec
| RSpec | pytest-autofixture |
|---|---|
let(:user) { User.new(role:) } |
let.user = lambda: User(role=role) |
let! / before |
@pytest.fixture(autouse=True) (not setup_method, which can't see bare names) |
after |
a yield fixture |
subject |
let.subject = lambda: ... |
describe / context |
a nested class, named Test... so pytest collects it |
shared_examples |
a base test class |
same examples with a different let |
@pytest.mark.parametrize("role", [...]) |
Limitations
Declare the fixture as a parameter instead when:
- the test is wrapped by a decorator such as
@mock.patchor hypothesis's@given, or by a plugin (the test fails with an error saying so) - the fixture is parametrized
- an async test uses an async fixture
- a yield fixture first uses the name after its
yield(pytest 9.1+ refuses fixture lookups during teardown)
Only test and fixture bodies see bare names; a module-level helper raises NameError, so pass the value in. Inside a test, globals() isn't the module's dict (use sys.modules[__name__]), a global write reaches the module only when the test returns, and del of a global fails.
Linters flag bare fixture names as undefined (ruff F821, pyright). Silence that for test files, e.g. in pyproject.toml:
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["F821"]
Metadata
Release files for pytest-autofixture 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pytest_autofixture-0.3.1.tar.gz | 12.4 kB | With provenance | Details for pytest_autofixture-0.3.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pytest_autofixture-0.3.1-py3-none-any.whl | Python 3 | none | any | Details for pytest_autofixture-0.3.1-py3-none-any.whl |
Total release size: 21.3 kB
Release files / pytest_autofixture-0.3.1.tar.gz
| Download URL | pytest_autofixture-0.3.1.tar.gz |
|---|---|
| Size | 12.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
71dc07773ebbf9eb029fa8725d829b2e26cf179e039777b66ade01e93cadf107
|
|
BLAKE2b-256 checksum How to use checksums |
ed201e9b4e89a285c4714588f2ba96a597538405b64eb74d5a51ba733804f590
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 27, 2026.
Transparency logRelease files / pytest_autofixture-0.3.1-py3-none-any.whl
| Download URL | pytest_autofixture-0.3.1-py3-none-any.whl |
|---|---|
| Size | 8.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
615d9d6b1eae19c02b901cc3375ba624798197aff97c7c22a8ecadf8106a026b
|
|
BLAKE2b-256 checksum How to use checksums |
35efa08a0679d47b67132b0a7aaa7bf7f4cff4382481f8adce29a59845cccf8e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 27, 2026.
Transparency logSecurity for pytest-autofixture 0.3.1
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
Both files in this release have been uploaded with provenance metadata.
Attestation for pytest_autofixture-0.3.1.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 Oct 27, 2026.
Transparency logA 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.