Skip to content

Session fixture keeps frames of other fixtures alive #2981

@nicoddemus

Description

@nicoddemus

Consider this test file:

import pytest
import weakref

class SomeObj:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return '<SomeObj "{}">'.format(self.name)

ref = None
session_ref = None

@pytest.fixture(scope='session')
def session_fix():
    global session_ref
    session_obj = SomeObj('session')
    session_ref = weakref.ref(session_obj)
    return session_obj

@pytest.fixture
def fix(session_fix):
    global ref
    obj = SomeObj('local')
    ref = weakref.ref(obj)
    return obj

def test1(fix):
    assert ref() is fix

def test2():
    assert ref() is None

This fails with:

============================= test session starts =============================
platform win32 -- Python 3.6.3, pytest-3.3.1.dev26+gfdfc194, py-1.5.2, pluggy-0.6.0 -- c:\sybil\.env36\scripts\python.exe
cachedir: .cache
rootdir: C:\pytest\.tmp, inifile: pytest.ini
collected 2 items

test_leak.py::test1 PASSED                                               [ 50%]
test_leak.py::test2 FAILED                                               [100%]

================================== FAILURES ===================================
____________________________________ test2 ____________________________________

    def test2():
>       assert ref() is None
E       assert <SomeObj "local"> is None
E        +  where <SomeObj "local"> = ref()

test_leak.py:31: AssertionError
===================== 1 failed, 1 passed in 0.04 seconds ======================

So for some reason the object created in fix is being kept alive after test1 has finished. This is caused by session_fix and can be verified by changing test1 to no longer require session_fix in which case both tests pass.

This seems to reproduce the errors reported in #2968 and #2970 because both tests pass in 3.2.5. 😓

Metadata

Metadata

Assignees

Labels

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