Hook wrappers require the function name to start with the name of the hookspec, even when the specname keyword argument is passed to pytest.hookimpl.
Use case
I want to implement the same hook multiple times, once as a tryfirst hook and once as a wrapper. I cannot use the same function name in the same file, otherwise the second function overrides the first. I'm left with either putting the hookimpls into different modules or using the specname keyword argument which didn't work as expected.
The pytest docs about hooks link to pluggy and pytest exposes the pluggy hook interface. However, the pytest docs never mention the use of specname explicitly. Therefore, I'm not sure if this is a bug or if specname is not even intended to work in pytest. If this is the case, it would be helpful to receive an error, for example.
Minimal reproducer
The following setup is expected to print "Before hooks" and "After hooks" a couple of times when run with pytest -s.
It actually prints nothing and the hook implementation is silently ignored.
test_wrapper.py
def test_anything():
pass
conftest.py
import pytest
@pytest.hookimpl(specname="pytest_pycollect_makeitem", hookwrapper=True)
# def pytest_pycollect_makeitem(collector, name, obj): # works
# def pytest_pycollect_makeitem_abcd(collector, name, obj): # works
def my_func_name(collector, name, obj): # fails
print("Before hooks")
hook_result = yield
print("After hooks")
Note that the specname keyword argument is not ignored. It raises and exception, when the specname does not correspond to a valid hookspec. However, the function name cannot be chosen freely even in presence of the specname kwarg. The function must always start with the name of the hookspec for the example to work.
Workaround
- Define hookimpls in different files
- Ensure that function names start with the name of the hook spec, i.e.
pytest_pycollect_makeitemXYZ
Virtual environment
$ pip list
Package Version
---------- -------
iniconfig 2.0.0
packaging 23.1
pip 23.2.1
pluggy 1.2.0
pytest 7.4.0
setuptools 68.0.0
Hook wrappers require the function name to start with the name of the hookspec, even when the
specnamekeyword argument is passed topytest.hookimpl.Use case
I want to implement the same hook multiple times, once as a
tryfirsthook and once as a wrapper. I cannot use the same function name in the same file, otherwise the second function overrides the first. I'm left with either putting the hookimpls into different modules or using thespecnamekeyword argument which didn't work as expected.The pytest docs about hooks link to pluggy and pytest exposes the pluggy hook interface. However, the pytest docs never mention the use of
specnameexplicitly. Therefore, I'm not sure if this is a bug or ifspecnameis not even intended to work in pytest. If this is the case, it would be helpful to receive an error, for example.Minimal reproducer
The following setup is expected to print "Before hooks" and "After hooks" a couple of times when run with
pytest -s.It actually prints nothing and the hook implementation is silently ignored.
test_wrapper.py
conftest.py
Note that the
specnamekeyword argument is not ignored. It raises and exception, when the specname does not correspond to a valid hookspec. However, the function name cannot be chosen freely even in presence of thespecnamekwarg. The function must always start with the name of the hookspec for the example to work.Workaround
pytest_pycollect_makeitemXYZVirtual environment