Skip to content

autouse fixtures break scope rules #668

Closed
@pytestbot

Description

@pytestbot

Originally reported by: BitBucket: tgoodlet, GitHub: tgoodlet


I believe this issue is very similar to #660

The problem is easily reproduced.
Say you have the following very simple test mod test_fixture_scopes.py

import pytest


@pytest.fixture
def func_level(request):
    return 'blah'


@pytest.fixture(scope='session')
def sess_level(func_level):
    return func_level


def test_fscopes(sess_level):
    print sess_level

As expected this fixture chain breaks scope rules:

$ py.test --tb=short ./test_fixture_scopes
============================================================================================================= test session starts ==========================
platform linux2 -- Python 2.7.9 -- py-1.4.26 -- pytest-2.6.4 -- /usr/bin/python2
plugins: interactive, ordering, ipdb
collected 1 items 

test_fixture_scopes.py::test_fscopes ERROR

=================================================================================================================== ERRORS ==========================
_______________________________________________________________________________________________________ ERROR at setup of test_fscopes ________________________________________________________________________________________________________
/usr/lib/python2.7/site-packages/_pytest/runner.py:139: in __init__
    self.result = func()
/usr/lib/python2.7/site-packages/_pytest/runner.py:127: in <lambda>
    return CallInfo(lambda: ihook(item=item, **kwds), when=when)
/usr/lib/python2.7/site-packages/_pytest/main.py:167: in call_matching_hooks
    return hookmethod.pcall(plugins, **kwargs)
/usr/lib/python2.7/site-packages/_pytest/core.py:417: in pcall
    return self._docall(methods, kwargs)
/usr/lib/python2.7/site-packages/_pytest/core.py:424: in _docall
    res = mc.execute()
/usr/lib/python2.7/site-packages/_pytest/core.py:315: in execute
    res = method(**kwargs)
/usr/lib/python2.7/site-packages/_pytest/runner.py:86: in pytest_runtest_setup
    item.session._setupstate.prepare(item)
/usr/lib/python2.7/site-packages/_pytest/runner.py:393: in prepare
    col.setup()
/usr/lib/python2.7/site-packages/_pytest/python.py:1141: in setup
    fillfixtures(self)
/usr/lib/python2.7/site-packages/_pytest/python.py:667: in fillfixtures
    request._fillfixtures()
/usr/lib/python2.7/site-packages/_pytest/python.py:1289: in _fillfixtures
    item.funcargs[argname] = self.getfuncargvalue(argname)
/usr/lib/python2.7/site-packages/_pytest/python.py:1337: in getfuncargvalue
    return self._get_active_fixturedef(argname).cached_result[0]
/usr/lib/python2.7/site-packages/_pytest/python.py:1351: in _get_active_fixturedef
    result = self._getfuncargvalue(fixturedef)
/usr/lib/python2.7/site-packages/_pytest/python.py:1403: in _getfuncargvalue
    val = fixturedef.execute(request=subrequest)
/usr/lib/python2.7/site-packages/_pytest/python.py:1825: in execute
    fixturedef = request._get_active_fixturedef(argname)
/usr/lib/python2.7/site-packages/_pytest/python.py:1351: in _get_active_fixturedef
    result = self._getfuncargvalue(fixturedef)
E   ScopeMismatchError: You tried to access the 'function' scoped fixture 'func_level' with a 'session' scoped request object, involved factories
E   test_fixture_scopes.py:3:  def sess_level(func_level)
E   test_fixture_scopes.py:8:  def func_level(request)
=========================================================================================================== 1 error in 0.04 seconds ==========================

But now add a sibling autouse fixture which consumes sess_level to the same file:

@pytest.fixture(autouse=True)
    def always(func_level):
        print func_level

Run again and the scope mismatch error dissappears?

$ py.test --tb=short ./test_fixture_scopes
============================================================================================================= test session starts =================================================================
platform linux2 -- Python 2.7.9 -- py-1.4.26 -- pytest-2.6.4 -- /usr/bin/python2
plugins: interactive, ordering, ipdb
collected 1 items 

test_fixture_scopes.py::test_fscopes blah
blah
PASSED

========================================================================================================== 1 passed in 0.01 seconds ========================

This caused some very unexpected results for me since the scoped sess_level will be retriggered for every consuming test once the autouse sibling is added.
Since there was no error and I am dealing with a large fixture set, I was unaware that I was breaking scope rules and instead saw odd fixture execution orders.


Metadata

Metadata

Assignees

No one assigned

    Labels

    type: 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