Skip to content

Missing entry in metafunc.fixturenames for sub-fixture with same name #3716

Description

@whimboo

Having a sub-fixture overwriting a higher-level fixture (with the same name) an argument setup as marker is lost for the higher-level fixture. This is tested with latest pytest 3.6.3.

Here an example:

# conftest.py
import pytest

@pytest.fixture(name="fish")
def fixture_fish(taste):
    pass

def pytest_generate_tests(metafunc):
    if "taste" in metafunc.fixturenames:
        print("** found taste")
        marker = metafunc.definition.get_closest_marker(name="taste")
        if marker:
            metafunc.parametrize("taste", marker.args, ids=None)
    else:
        print("** didn't find taste")
# test.py
import pytest

@pytest.fixture(name="fish")
def fixture_fish(fish):  # , taste):
    yield fish

@pytest.mark.taste("dry")
def test_fish(fish):
    pass

Workarounds for now are:

  1. Use a different name for the sub-fixture
  2. Also adding the argument for the sub-fixture

I would expect that I can simply overwrite fixtures and markers are still available as arguments for fixtures.

Activity

  1. changed the title [-]Missing marker in fixturenames for sub-fixture with same name[/-] [+]Missing marker in metafunc.fixturenames for sub-fixture with same name[/+] on Jul 25, 2018
  2. pytestbot commented on Jul 25, 2018

    @pytestbot
    Contributor

    GitMate.io thinks possibly related issues are #3655 (several names for fixture), #794 (fixture named "request" fails), #519 (fixture scope is ignored when using metafunc.parametrize()), #354 (tmpdir fixture: 'File name too long'), and #1368 (apply markers based on fixtures/dependent fixtures).

  3. davehunt commented on Jul 25, 2018

    @davehunt
    Contributor

    I can replicate this with the following test:

    def test_extend_fixture_conftest_module_alter_fixtures(self, testdir):
        testdir.makeconftest("""
            import pytest
    
            @pytest.fixture
            def ham(): return 'ham'
    
            @pytest.fixture
            def spam(ham): return ham + 'spam'
        """)
        testfile = testdir.makepyfile("""
            import pytest
    
            @pytest.fixture
            def spam(spam):
                return spam * 2
    
            def test_spam(request, spam):
                assert spam == 'hamspamhamspam'
                assert 'ham' in request.fixturenames
        """)
        result = testdir.runpytest()
        result.stdout.fnmatch_lines(["*1 passed*"])
        result = testdir.runpytest(testfile)
        result.stdout.fnmatch_lines(["*1 passed*"])

    It fails with:

        def test_spam(request, spam):
            assert spam == 'hamspamhamspam'
    >       assert 'ham' in request.fixturenames
    E       AssertionError: assert 'ham' in ['request', 'spam']
    E        +  where ['request', 'spam'] = <FixtureRequest for <Function 'test_spam'>>.fixturenames
    
  4. changed the title [-]Missing marker in metafunc.fixturenames for sub-fixture with same name[/-] [+]Missing entry in metafunc.fixturenames for sub-fixture with same name[/+] on Dec 21, 2018
  5. Zac-HD commented on Jul 21, 2026

    @Zac-HD
    Member

    Closing as resolved: this is the overridden-fixture fixturenames/parametrization pruning bug tracked in #13773 and fixed by #13789 and #14369 (see also #14248); both examples from this thread now behave correctly on current main.

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: fixturesanything involving fixtures directly or indirectly

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions