pytest-dev / pytest-dev/pytest
`FixtureLookupError.formatrepr` uses `_pyfuncitem.obj`, which is not part of the `pytest.Item` interface
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
Sybil's pytest integration allows users to request pytest fixtures.
Currently, if you typo a fixture name, you get this horrible internal error:
E ============================= test session starts ==============================
E platform darwin -- Python 3.10.7, pytest-8.0.0, pluggy-1.4.0 -- /Users/chris/virtualenvs/sybil_310/bin/python
E cachedir: .pytest_cache
E rootdir: /private/var/folders/m6/tsd59qsj7pd_lldh4mhwh6kh0000gn/T/pytest-of-chris/pytest-71/test_request_missing_fixtures0
E plugins: cov-4.0.0
E collecting ... collected 1 item
E
E ../../../../../private/var/folders/m6/tsd59qsj7pd_lldh4mhwh6kh0000gn/T/pytest-of-chris/pytest-71/test_request_missing_fixtures0/test.rst::line:1,column:1
E INTERNALERROR> Traceback (most recent call last):
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/main.py", line 272, in wrap_session
E INTERNALERROR> session.exitstatus = doit(config, session) or 0
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/main.py", line 326, in _main
E INTERNALERROR> config.hook.pytest_runtestloop(session=session)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_hooks.py", line 501, in __call__
E INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_manager.py", line 119, in _hookexec
E INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 138, in _multicall
E INTERNALERROR> raise exception.with_traceback(exception.__traceback__)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/logging.py", line 796, in pytest_runtestloop
E INTERNALERROR> return (yield) # Run all the tests.
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 102, in _multicall
E INTERNALERROR> res = hook_impl.function(*args)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/main.py", line 351, in pytest_runtestloop
E INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_hooks.py", line 501, in __call__
E INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_manager.py", line 119, in _hookexec
E INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 138, in _multicall
E INTERNALERROR> raise exception.with_traceback(exception.__traceback__)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/warnings.py", line 109, in pytest_runtest_protocol
E INTERNALERROR> return (yield)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/assertion/__init__.py", line 174, in pytest_runtest_protocol
E INTERNALERROR> return (yield)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/unittest.py", line 408, in pytest_runtest_protocol
E INTERNALERROR> res = yield
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/faulthandler.py", line 85, in pytest_runtest_protocol
E INTERNALERROR> return (yield)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 102, in _multicall
E INTERNALERROR> res = hook_impl.function(*args)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/runner.py", line 114, in pytest_runtest_protocol
E INTERNALERROR> runtestprotocol(item, nextitem=nextitem)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/runner.py", line 127, in runtestprotocol
E INTERNALERROR> rep = call_and_report(item, "setup", log)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/runner.py", line 228, in call_and_report
E INTERNALERROR> report: TestReport = hook.pytest_runtest_makereport(item=item, call=call)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_hooks.py", line 501, in __call__
E INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_manager.py", line 119, in _hookexec
E INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 138, in _multicall
E INTERNALERROR> raise exception.with_traceback(exception.__traceback__)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/tmpdir.py", line 316, in pytest_runtest_makereport
E INTERNALERROR> rep = yield
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 121, in _multicall
E INTERNALERROR> teardown.throw(exception) # type: ignore[union-attr]
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/skipping.py", line 269, in pytest_runtest_makereport
E INTERNALERROR> rep = yield
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/pluggy/_callers.py", line 102, in _multicall
E INTERNALERROR> res = hook_impl.function(*args)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/runner.py", line 372, in pytest_runtest_makereport
E INTERNALERROR> return TestReport.from_item_and_call(item, call)
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/reports.py", line 366, in from_item_and_call
E INTERNALERROR> longrepr = item._repr_failure_py(
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/nodes.py", line 464, in _repr_failure_py
E INTERNALERROR> return excinfo.value.formatrepr()
E INTERNALERROR> File "/Users/chris/virtualenvs/sybil_310/lib/python3.10/site-packages/_pytest/fixtures.py", line 822, in formatrepr
E INTERNALERROR> stack = [self.request._pyfuncitem.obj]
E INTERNALERROR> AttributeError: 'SybilItem' object has no attribute 'obj'
E
E ============================ no tests ran in 0.01s =============================
This is because FixtureLookupError.formatrepr uses _pyfuncitem.obj, which is not part of the pytest.Item interface.
It's been years now, and I really wish pytest could sort out a stable API for things that provided other types of item to request fixtures :-/
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read src/_pytest/fixtures.py at FixtureLookupError.formatrepr and review the pytest.Item interface. Reproduce the missing-fixture case through Sybil's pytest integration, then verify that a typo produces a useful fixture error instead of an AttributeError while remaining compatible with pytest.Item implementations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100