Merge pull request #3249 from a-feld/request-fixture-reference-cycle
Fix PseudoFixtureDef reference cycle.
This commit is contained in:
commit
bedceaacc4
1
AUTHORS
1
AUTHORS
|
@ -197,3 +197,4 @@ Xuan Luong
|
||||||
Xuecong Liao
|
Xuecong Liao
|
||||||
Zoltán Máté
|
Zoltán Máté
|
||||||
Roland Puntaier
|
Roland Puntaier
|
||||||
|
Allan Feldman
|
||||||
|
|
|
@ -24,6 +24,12 @@ from _pytest.compat import (
|
||||||
from _pytest.outcomes import fail, TEST_OUTCOME
|
from _pytest.outcomes import fail, TEST_OUTCOME
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s(frozen=True)
|
||||||
|
class PseudoFixtureDef(object):
|
||||||
|
cached_result = attr.ib()
|
||||||
|
scope = attr.ib()
|
||||||
|
|
||||||
|
|
||||||
def pytest_sessionstart(session):
|
def pytest_sessionstart(session):
|
||||||
import _pytest.python
|
import _pytest.python
|
||||||
import _pytest.nodes
|
import _pytest.nodes
|
||||||
|
@ -440,10 +446,9 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
fixturedef = self._getnextfixturedef(argname)
|
fixturedef = self._getnextfixturedef(argname)
|
||||||
except FixtureLookupError:
|
except FixtureLookupError:
|
||||||
if argname == "request":
|
if argname == "request":
|
||||||
class PseudoFixtureDef(object):
|
cached_result = (self, [0], None)
|
||||||
cached_result = (self, [0], None)
|
scope = "function"
|
||||||
scope = "function"
|
return PseudoFixtureDef(cached_result, scope)
|
||||||
return PseudoFixtureDef
|
|
||||||
raise
|
raise
|
||||||
# remove indent to prevent the python3 exception
|
# remove indent to prevent the python3 exception
|
||||||
# from leaking into the call
|
# from leaking into the call
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix reference cycle generated when using the ``request`` fixture.
|
|
@ -519,6 +519,41 @@ class TestRequestBasic(object):
|
||||||
assert len(arg2fixturedefs) == 1
|
assert len(arg2fixturedefs) == 1
|
||||||
assert arg2fixturedefs['something'][0].argname == "something"
|
assert arg2fixturedefs['something'][0].argname == "something"
|
||||||
|
|
||||||
|
def test_request_garbage(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import sys
|
||||||
|
import pytest
|
||||||
|
import gc
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def something(request):
|
||||||
|
# this method of test doesn't work on pypy
|
||||||
|
if hasattr(sys, "pypy_version_info"):
|
||||||
|
yield
|
||||||
|
else:
|
||||||
|
original = gc.get_debug()
|
||||||
|
gc.set_debug(gc.DEBUG_SAVEALL)
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
gc.collect()
|
||||||
|
leaked_types = sum(1 for _ in gc.garbage
|
||||||
|
if 'PseudoFixtureDef' in str(_))
|
||||||
|
|
||||||
|
gc.garbage[:] = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
assert leaked_types == 0
|
||||||
|
finally:
|
||||||
|
gc.set_debug(original)
|
||||||
|
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
def test_getfixturevalue_recursive(self, testdir):
|
def test_getfixturevalue_recursive(self, testdir):
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
Loading…
Reference in New Issue