Skip to content

Inconsistent support for staticmethod/classmethod #10525

Description

@Jasha10

Pytest discovery & running of staticmethods/classmethods is inconsistent. Here's an example:

import pytest

class TestFoo:
    # passes:
    @staticmethod
    def test_staticmethod() -> None:
        foo = 0
        assert foo < 3

    # warning: cannot collect 'test_staticmethod_inner' because it is not a function.
    @pytest.mark.parametrize("foo", [1, 2])
    @staticmethod
    def test_staticmethod_inner(foo: int) -> None:
        assert foo < 3

    # passes:
    @staticmethod
    @pytest.mark.parametrize("foo", [1, 2])
    def test_staticmethod_outer(foo: int) -> None:
        assert foo < 3

    # silently fails to run
    @classmethod
    def test_classmethod(cls) -> None:
        foo = 0
        assert foo < 3

    # warning: cannot collect 'test_classmethod_inner' because it is not a function.
    @pytest.mark.parametrize("foo", [1, 2])
    @classmethod
    def test_classmethod_inner(cls, foo: int) -> None:
        assert foo < 3

    # silently fails to run
    @classmethod
    @pytest.mark.parametrize("foo", [1, 2])
    def test_classmethod_outer(cls, foo: int) -> None:
        assert foo < 3

The most worrysome cases are test_classmethod and test_classmethod_outer, which are not discovered by pytest. I think that there should at least be a warning or error to alert the user that their test code cannot be run.

Here's the full output from running `pytest -v`:
$ pytest tmp.py -v
======================== test session starts =========================
platform linux -- Python 3.9.15, pytest-7.2.0, pluggy-1.0.0 -- /home/homestar/tmp2/tmp_venv/bin/python3
cachedir: .pytest_cache
rootdir: /home/homestar/tmp2
collected 3 items

tmp.py::TestFoo::test_staticmethod PASSED                      [ 33%]
tmp.py::TestFoo::test_staticmethod_outer[1] PASSED             [ 66%]
tmp.py::TestFoo::test_staticmethod_outer[2] PASSED             [100%]

========================== warnings summary ==========================
tmp_venv/lib/python3.9/site-packages/_pytest/mark/structures.py:347
  /home/homestar/tmp2/tmp_venv/lib/python3.9/site-packages/_pytest/mark/structures.py:347: PytestCollectionWarning: cannot collect 'test_staticmethod_inner' because it is not a function.
    def __call__(self, *args: object, **kwargs: object):

tmp_venv/lib/python3.9/site-packages/_pytest/mark/structures.py:347
  /home/homestar/tmp2/tmp_venv/lib/python3.9/site-packages/_pytest/mark/structures.py:347: PytestCollectionWarning: cannot collect 'test_classmethod_inner' because it is not a function.
    def __call__(self, *args: object, **kwargs: object):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================== 3 passed, 2 warnings in 0.00s ====================

python v3.9.15, pytest v7.2.0, ubuntu 20.04

Output of `pip list`:
$ pip list
Package        Version
-------------- -------
attrs          22.1.0
exceptiongroup 1.0.4
iniconfig      1.1.1
packaging      21.3
pip            22.0.4
pluggy         1.0.0
pyparsing      3.0.9
pytest         7.2.0
setuptools     58.1.0
tomli          2.0.1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: collectionrelated to the collection phasetype: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions