pytest-dev / pytest

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing
https://pytest.org
MIT License
12.07k stars 2.67k forks source link

Getting `AttributeError: 'FixtureDef' object has no attribute 'unittest'` in pytest 8.2.0 #12269

Closed dariofaccin closed 6 months ago

dariofaccin commented 6 months ago

Maintainer note: To fix compatibility with pytest>=8.2.0, update pytest-asyncio to >=0.23.6, or >=v0.21.2 if you're on 0.21.x.


After upgrading from pytest 8.1.2 to pytest 8.2.0 I am getting the following error during tests setup:

Traceback (most recent call last):
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/runner.py", line 341, in from_call
    result: Optional[TResult] = func()
                                ^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/runner.py", line 241, in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 139, in _multicall
    raise exception.with_traceback(exception.__traceback__)
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/unraisableexception.py", line 85, in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/unraisableexception.py", line 65, in unraisable_exception_runtest_hook
    yield
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/logging.py", line 844, in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/logging.py", line 833, in _runtest_for
    yield
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/capture.py", line 873, in pytest_runtest_setup
    return (yield)
            ^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/threadexception.py", line 82, in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/threadexception.py", line 63, in thread_exception_runtest_hook
    yield
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/runner.py", line 159, in pytest_runtest_setup
    item.session._setupstate.setup(item)
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/runner.py", line 515, in setup
    raise exc
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/runner.py", line 512, in setup
    col.setup()
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/python.py", line 1630, in setup
    self._request._fillfixtures()
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/fixtures.py", line 683, in _fillfixtures
    item.funcargs[argname] = self.getfixturevalue(argname)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/fixtures.py", line 518, in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/fixtures.py", line 603, in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/fixtures.py", line 1073, in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 182, in _multicall
    return outcome.get_result()
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_result.py", line 100, in get_result
    raise exc.with_traceback(exc.__traceback__)
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 167, in _multicall
    teardown.throw(outcome._exception)
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/setuponly.py", line 36, in pytest_fixture_setup
    return (yield)
            ^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/fixtures.py", line 1122, in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/_pytest/fixtures.py", line 884, in call_fixture_func
    fixture_result = fixturefunc(**kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^
  File "/home/dario/projects/Telco/sdcore-upf-operator/.tox/integration/lib/python3.11/site-packages/pytest_asyncio/plugin.py", line 319, in _async_fixture_wrapper
    fixture, request.instance, fixturedef.unittest
                               ^^^^^^^^^^^^^^^^^^^
AttributeError: 'FixtureDef' object has no attribute 'unittest'

Python version (if relevant): 3.11.6

s-bose commented 6 months ago

Happening to me as well. Reverting to 8.1.2 fixed it.

bluetech commented 6 months ago

Which version of pytest-asyncio are you using?

wxtim commented 6 months ago

Noddy case:

import pytest

@pytest.fixture
async def myfixture():
    yield 1

def test_noddy(myfixture):
    assert 1 == myfixture

I think this issue may have been introduced at #12096

bluetech commented 6 months ago

This issue was already fixed in the latest version of pytest-asyncio, if you can please upgrade. If you're still on pytest-asyncio 0.21, a user made a proposal for a backport https://github.com/pytest-dev/pytest-asyncio/pull/823 but I can't tell if it will be merged.

nicoddemus commented 6 months ago

This issue was already fixed in the latest version of pytest-asyncio, if you can please upgrade

Anything else actionable by pytest, given this is fixed by pytest-asyncio?

wxtim commented 6 months ago

This issue was already fixed in the latest version of pytest-asyncio, if you can please upgrade. If you're still on pytest-asyncio 0.21, a user made a proposal for a backport pytest-dev/pytest-asyncio#823 but I can't tell if it will be merged.

Unfortunately we can't use 0.23 yet.

GChampagne1 commented 6 months ago

This issue was already fixed in the latest version of pytest-asyncio, if you can please upgrade

I can't upgrade (and it seems like I'm not the only one) higher than v21 because of a known issue with v23 that is still being fixed:

As of v0.23, pytest-asyncio attaches an asyncio event loop to each item of the test suite (i.e. session, packages, modules, classes, functions) and allows tests to be run in those loops when marked accordingly. Pytest-asyncio currently assumes that async fixture scope is correlated with the new event loop scope. This prevents fixtures from being evaluated independently from the event loop scope and breaks some existing test suites (see #706). For example, a test suite may require all fixtures and tests to run in the same event loop, but have async fixtures that are set up and torn down for each module. If you’re affected by this issue, please continue using the v0.21 release, until it is resolved.

https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html

ffissore commented 6 months ago

0.21.2 has been released and it works with pytest 8.2.0

bluetech commented 6 months ago

The issue is resolved, I will edit the top post with information and pin for visibility for a few days.