--- /dev/null
+.. change::
+ :tags: bug, tests
+ :tickets: 13392
+
+ Fixed class-scoped pytest fixtures that were defined as instance methods
+ using ``self``, which is deprecated as of pytest 9.1 and will be removed in
+ pytest 10. Fixtures are now decorated with a compatibility ``@classmethod``
+ decorator and use ``cls`` as the first parameter.
yield from self._cachedir()
@config.fixture(scope="class")
- def cachedir(self):
- yield from self._cachedir()
+ @classmethod
+ def cachedir(cls):
+ yield from cls._cachedir()
- def _cachedir(self):
+ @classmethod
+ def _cachedir(cls):
# as of mypy 0.971 i think we need to keep mypy_path empty
mypy_path = ""
classes: Any = None
@config.fixture(autouse=True, scope="class")
- def _setup_tables_test_class(self):
- cls = self.__class__
+ @classmethod
+ def _setup_tables_test_class(cls):
cls._init_class()
if cls.classes is None:
sequences = None
@config.fixture(autouse=True, scope="class")
- def _setup_tables_test_class(self):
- cls = self.__class__
+ @classmethod
+ def _setup_tables_test_class(cls):
cls._init_class()
cls._setup_once_tables()
# now apply wrappers to the function, including fixture itself
def wrap(fn):
+ is_classmethod = isinstance(fn, classmethod)
+ if is_classmethod:
+ fn = fn.__func__
+
if config.any_async:
fn = asyncio._maybe_async_wrapper(fn)
# other wrappers may be added here
+ if is_classmethod:
+ fn = classmethod(fn)
+
# now apply FixtureFunctionMarker
fn = fixture(fn)
__requires__ = ("cpython", "python_profiling_backend")
@testing.fixture(scope="class")
- def mapping_fixture(self):
+ @classmethod
+ def mapping_fixture(cls):
# note in order to work nicely with "fixture" we are emerging
# a whole new model of setup/teardown, since pytest "fixture"
# sort of purposely works badly with setup/teardown
class _MutableNoHashFixture:
@testing.fixture(autouse=True, scope="class")
- def set_class(self):
+ @classmethod
+ def set_class(cls):
global Foo
_replace_foo = Foo