Skip to content

Conversation

@yastcher yastcher force-pushed the fix/14011-10819-correct-class-fixtures branch 3 times, most recently from 6c5967f to 9772d0c Compare December 28, 2025 17:21
@psf-chronographer psf-chronographer bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Dec 28, 2025
@yastcher yastcher force-pushed the fix/14011-10819-correct-class-fixtures branch from 9772d0c to acd357c Compare December 29, 2025 18:41
@yastcher yastcher force-pushed the fix/14011-10819-correct-class-fixtures branch from acd357c to ff1759c Compare January 12, 2026 02:25
pass

@pytest.fixture(scope="class")
def fix(self) -> typing.Generator[None]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminds me that we need to ensure that class scope fixtures do not actually ever get a instance - class scope is above instances and should get a class

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed: added _ClassScopeInstance proxy that redirects attribute writes to the class, so class-scoped fixtures never work with actual test instances

Copy link
Author

@yastcher yastcher Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented _ClassScopeInstance proxy that redirects attribute writes to the class, so class-scoped fixtures work correctly without actual test instances.

However, I noticed your comment in #10819 about deprecating non-classmethod class-scoped fixtures. If that's the preferred direction, this fix might be unnecessary — we could add a deprecation warning instead and guide users toward @ classmethod fixtures.

Should I proceed with the proxy approach, or switch to deprecation warning?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically speaking its a bug to even try to pass a instance to a class scope fixture as no instance is available in that context

that a instance is actually avaliable is a bug an a artifact of how setupstate and scope initially developed

before there where fixtures we had the pytest_funcarg__ARGNAME hooks and no scopes at all

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. So the fix is correct — class-scoped fixtures should never receive an actual instance. The _ClassScopeInstance proxy ensures they work with the class directly, which is the intended behavior

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should error in future and warn right now

Instance methods are always wrong

Class scope requires classmethods

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Will remove the proxy and add deprecation warning instead.

Proposed implementation:

In src/_pytest/deprecated.py:

CLASS_FIXTURE_INSTANCE_METHOD = PytestRemovedIn10Warning(
    "Class-scoped fixture defined as instance method is deprecated.\n"
    "Use @classmethod decorator instead.\n"
    "See https://docs.pytest.org/en/stable/deprecations.html#class-scoped-fixture-as-instance-method"
)

Then warn in resolve_fixture_function when class-scoped fixture is an instance method.

Does this look right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the deprecation message should be very aggressive about the fact that any changes to the instance would in fact not transfer to subsequent instances

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLASS_FIXTURE_INSTANCE_METHOD = PytestRemovedIn10Warning(
    "Class-scoped fixture defined as instance method is deprecated.\n"
    "Instance attributes set in this fixture will NOT be visible to test methods,\n"
    "as each test gets a new instance while the fixture runs only once per class.\n"
    "Use @classmethod decorator and set attributes on cls instead.\n"
    "See https://docs.pytest.org/en/stable/deprecations.html#class-scoped-fixture-as-instance-method"
)

?

@yastcher yastcher force-pushed the fix/14011-10819-correct-class-fixtures branch 4 times, most recently from 86b996f to a79434e Compare January 17, 2026 12:31
@yastcher yastcher force-pushed the fix/14011-10819-correct-class-fixtures branch from a79434e to bea8737 Compare January 18, 2026 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inherit fixture from baseclass with class scope fails Fixture with scope=class and autouse=True is not executed from mother's test class

2 participants