close
Skip to content

Deprecate self in module, package and session scoped fixtures - #14911

Closed
nuemaan wants to merge 1 commit into
pytest-dev:mainfrom
nuemaan:deprecate-self-in-wider-scoped-fixtures
Closed

Deprecate self in module, package and session scoped fixtures#14911
nuemaan wants to merge 1 commit into
pytest-dev:mainfrom
nuemaan:deprecate-self-in-wider-scoped-fixtures

Conversation

@nuemaan

@nuemaan nuemaan commented Aug 19, 2026

Copy link
Copy Markdown

Closes #14765.

#14071 deprecated instance-method fixtures at class scope, since attributes set on self never reach the tests. Each test runs on a fresh instance while the fixture runs once per class. module, package and session scope have exactly the same problem and were still silent, so this extends the deprecation to cover them.

Confirmed the breakage is real before writing the warning. With scope="module" or scope="session", a fixture that sets self.attr leaves the test seeing nothing:

E       AssertionError: assert None == 'set-by-fixture'

The message differs from the class-scoped one. @classmethod is what the class-scoped warning recommends, but for these wider scopes the class body is not a useful place to hang state either, so the new message points at @staticmethod. Worth noting that @classmethod does happen to work at these scopes, so if you would rather the message mention both, that is a one-line change.

Function scope is deliberately untouched. The fixture and the test share an instance there, so self behaves as people expect.

Four fixtures in our own test suite matched the pattern:

  • testing/test_legacypath.py TestFixtureRequestSessionScoped.session_request
  • testing/test_conftest.py TestConftestValueAccessGlobal.basedir
  • testing/test_pathlib.py TestImportPath.path1
  • testing/python/fixtures.py TestRequestSessionScoped.session_request

Every one of them took self without using it, which is some evidence the deprecation catches accidental instance methods rather than deliberate ones. They are now staticmethods. TestImportPath.path1 called self.setuptestfs, which does not use self either, so that helper became a staticmethod as well.

Verification

  • testing/deprecated_test.py, 23 passed, including 7 new
  • Full testing/ suite with -n 8, 3761 passed against 3754 on unmodified main. Same 1 failure and same 5 errors appear on both, all from optional deps missing in my environment, attrs among them
  • ruff check, ruff format --check, and mypy on the changed files, all clean
  • Reverted the two src/ files and re-ran the new tests to confirm they fail without the change, rather than passing regardless

A class-scoped fixture defined as an instance method already warns, because
attributes set on self never reach the tests. Each test runs on a fresh
instance while the fixture runs once per class.

Module, package and session scope have the same problem, and they were still
silent. Extend the deprecation to cover them.

The message differs from the class-scoped one. For those wider scopes the
class body is not a useful place to hang state either, so it points at
@staticmethod rather than @classmethod.

Four fixtures in our own test suite matched the pattern. All of them took
self without using it, so they became staticmethods. TestImportPath.path1
called self.setuptestfs, which does not use self either, so that helper
became a staticmethod too.

Closes pytest-dev#14765
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Aug 19, 2026
@RonnyPfannschmidt

Copy link
Copy Markdown
Member

#14774

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.

Extend self deprecation to module/package/session scoped fixtures inside classes

2 participants