Skip to content

Commit

Permalink
Remove request.cached_setup
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoddemus committed Dec 1, 2018
1 parent 06dc6e3 commit 090f7ff
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 284 deletions.
3 changes: 3 additions & 0 deletions changelog/4489.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Removed ``request.cached_setup``. This was the predecessor mechanism to modern fixtures.

See our `docs <https://docs.pytest.org/en/latest/deprecations.html#cached-setup>`__ on information on how to update your code.
68 changes: 33 additions & 35 deletions doc/en/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,41 +49,6 @@ Becomes:
exec("assert(1, 2)") # exec is used to avoid a top-level warning
``cached_setup``
~~~~~~~~~~~~~~~~

.. deprecated:: 3.9

``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures.

Example:

.. code-block:: python
@pytest.fixture
def db_session():
return request.cached_setup(
setup=Session.create, teardown=lambda session: session.close(), scope="module"
)
This should be updated to make use of standard fixture mechanisms:

.. code-block:: python
@pytest.fixture(scope="module")
def db_session():
session = Session.create()
yield session
session.close()
You can consult `funcarg comparison section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_ for
more information.

This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.


Using ``Class`` in custom Collectors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -309,6 +274,39 @@ Removed Features
As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after
an appropriate period of deprecation has passed.

``cached_setup``
~~~~~~~~~~~~~~~~

*Removed in version 4.0.*

``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures.

Example:

.. code-block:: python
@pytest.fixture
def db_session():
return request.cached_setup(
setup=Session.create, teardown=lambda session: session.close(), scope="module"
)
This should be updated to make use of standard fixture mechanisms:

.. code-block:: python
@pytest.fixture(scope="module")
def db_session():
session = Session.create()
yield session
session.close()
You can consult `funcarg comparison section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_ for
more information.

This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.

``yield`` tests
~~~~~~~~~~~~~~~

Expand Down
5 changes: 0 additions & 5 deletions src/_pytest/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@

YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored"

CACHED_SETUP = RemovedInPytest4Warning(
"cached_setup is deprecated and will be removed in a future release. "
"Use standard fixture functions instead."
)

FUNCARG_PREFIX = UnformattedWarning(
RemovedInPytest4Warning,
'{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated '
Expand Down
37 changes: 0 additions & 37 deletions src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,43 +469,6 @@ def _fillfixtures(self):
if argname not in item.funcargs:
item.funcargs[argname] = self.getfixturevalue(argname)

def cached_setup(self, setup, teardown=None, scope="module", extrakey=None):
""" (deprecated) Return a testing resource managed by ``setup`` &
``teardown`` calls. ``scope`` and ``extrakey`` determine when the
``teardown`` function will be called so that subsequent calls to
``setup`` would recreate the resource. With pytest-2.3 you often
do not need ``cached_setup()`` as you can directly declare a scope
on a fixture function and register a finalizer through
``request.addfinalizer()``.
:arg teardown: function receiving a previously setup resource.
:arg setup: a no-argument function creating a resource.
:arg scope: a string value out of ``function``, ``class``, ``module``
or ``session`` indicating the caching lifecycle of the resource.
:arg extrakey: added to internal caching key of (funcargname, scope).
"""
from _pytest.deprecated import CACHED_SETUP

warnings.warn(CACHED_SETUP, stacklevel=2)
if not hasattr(self.config, "_setupcache"):
self.config._setupcache = {} # XXX weakref?
cachekey = (self.fixturename, self._getscopeitem(scope), extrakey)
cache = self.config._setupcache
try:
val = cache[cachekey]
except KeyError:
self._check_scope(self.fixturename, self.scope, scope)
val = setup()
cache[cachekey] = val
if teardown is not None:

def finalizer():
del cache[cachekey]
teardown(val)

self._addfinalizer(finalizer, scope=scope)
return val

def getfixturevalue(self, argname):
""" Dynamically run a named fixture function.
Expand Down
21 changes: 0 additions & 21 deletions testing/deprecated_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,6 @@
pytestmark = pytest.mark.pytester_example_path("deprecated")


def test_cached_setup_deprecation(testdir):
testdir.makepyfile(
"""
import pytest
@pytest.fixture
def fix(request):
return request.cached_setup(lambda: 1)
def test_foo(fix):
assert fix == 1
"""
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(
[
"*test_cached_setup_deprecation.py:4:*cached_setup is deprecated*",
"*1 passed, 1 warnings in*",
]
)


def test_funcarg_prefix_deprecation(testdir):
testdir.makepyfile(
"""
Expand Down
188 changes: 2 additions & 186 deletions testing/python/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -953,181 +953,6 @@ def test_fun2(keywords):
reprec.assertoutcome(passed=2)


class TestRequestCachedSetup(object):
def test_request_cachedsetup_defaultmodule(self, testdir):
reprec = testdir.inline_runsource(
"""
mysetup = ["hello",].pop
import pytest
@pytest.fixture
def something(request):
return request.cached_setup(mysetup, scope="module")
def test_func1(something):
assert something == "hello"
class TestClass(object):
def test_func1a(self, something):
assert something == "hello"
""",
SHOW_PYTEST_WARNINGS_ARG,
)
reprec.assertoutcome(passed=2)

def test_request_cachedsetup_class(self, testdir):
reprec = testdir.inline_runsource(
"""
mysetup = ["hello", "hello2", "hello3"].pop
import pytest
@pytest.fixture
def something(request):
return request.cached_setup(mysetup, scope="class")
def test_func1(something):
assert something == "hello3"
def test_func2(something):
assert something == "hello2"
class TestClass(object):
def test_func1a(self, something):
assert something == "hello"
def test_func2b(self, something):
assert something == "hello"
""",
SHOW_PYTEST_WARNINGS_ARG,
)
reprec.assertoutcome(passed=4)

@pytest.mark.filterwarnings("ignore:cached_setup is deprecated")
def test_request_cachedsetup_extrakey(self, testdir):
item1 = testdir.getitem("def test_func(): pass")
req1 = fixtures.FixtureRequest(item1)
values = ["hello", "world"]

def setup():
return values.pop()

ret1 = req1.cached_setup(setup, extrakey=1)
ret2 = req1.cached_setup(setup, extrakey=2)
assert ret2 == "hello"
assert ret1 == "world"
ret1b = req1.cached_setup(setup, extrakey=1)
ret2b = req1.cached_setup(setup, extrakey=2)
assert ret1 == ret1b
assert ret2 == ret2b

@pytest.mark.filterwarnings("ignore:cached_setup is deprecated")
def test_request_cachedsetup_cache_deletion(self, testdir):
item1 = testdir.getitem("def test_func(): pass")
req1 = fixtures.FixtureRequest(item1)
values = []

def setup():
values.append("setup")

def teardown(val):
values.append("teardown")

req1.cached_setup(setup, teardown, scope="function")
assert values == ["setup"]
# artificial call of finalizer
setupstate = req1._pyfuncitem.session._setupstate
setupstate._callfinalizers(item1)
assert values == ["setup", "teardown"]
req1.cached_setup(setup, teardown, scope="function")
assert values == ["setup", "teardown", "setup"]
setupstate._callfinalizers(item1)
assert values == ["setup", "teardown", "setup", "teardown"]

def test_request_cached_setup_two_args(self, testdir):
testdir.makepyfile(
"""
import pytest
@pytest.fixture
def arg1(request):
return request.cached_setup(lambda: 42)
@pytest.fixture
def arg2(request):
return request.cached_setup(lambda: 17)
def test_two_different_setups(arg1, arg2):
assert arg1 != arg2
"""
)
result = testdir.runpytest("-v", SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(["*1 passed*"])

def test_request_cached_setup_getfixturevalue(self, testdir):
testdir.makepyfile(
"""
import pytest
@pytest.fixture
def arg1(request):
arg1 = request.getfixturevalue("arg2")
return request.cached_setup(lambda: arg1 + 1)
@pytest.fixture
def arg2(request):
return request.cached_setup(lambda: 10)
def test_two_funcarg(arg1):
assert arg1 == 11
"""
)
result = testdir.runpytest("-v", SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(["*1 passed*"])

def test_request_cached_setup_functional(self, testdir):
testdir.makepyfile(
test_0="""
import pytest
values = []
@pytest.fixture
def something(request):
val = request.cached_setup(fsetup, fteardown)
return val
def fsetup(mycache=[1]):
values.append(mycache.pop())
return values
def fteardown(something):
values.remove(something[0])
values.append(2)
def test_list_once(something):
assert something == [1]
def test_list_twice(something):
assert something == [1]
"""
)
testdir.makepyfile(
test_1="""
import test_0 # should have run already
def test_check_test0_has_teardown_correct():
assert test_0.values == [2]
"""
)
result = testdir.runpytest("-v", SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(["*3 passed*"])

def test_issue117_sessionscopeteardown(self, testdir):
testdir.makepyfile(
"""
import pytest
@pytest.fixture
def app(request):
app = request.cached_setup(
scope='session',
setup=lambda: 0,
teardown=lambda x: 3/x)
return app
def test_func(app):
pass
"""
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
assert result.ret != 0
result.stdout.fnmatch_lines(["*3/x*", "*ZeroDivisionError*"])


class TestFixtureUsages(object):
def test_noargfixturedec(self, testdir):
testdir.makepyfile(
Expand Down Expand Up @@ -2297,15 +2122,7 @@ def test_4(arg, created, finalized):
reprec = testdir.inline_run()
reprec.assertoutcome(passed=4)

@pytest.mark.parametrize(
"method",
[
'request.getfixturevalue("arg")',
'request.cached_setup(lambda: None, scope="function")',
],
ids=["getfixturevalue", "cached_setup"],
)
def test_scope_mismatch_various(self, testdir, method):
def test_scope_mismatch_various(self, testdir):
testdir.makeconftest(
"""
import pytest
Expand All @@ -2321,11 +2138,10 @@ def arg(request):
import pytest
@pytest.fixture(scope="session")
def arg(request):
%s
request.getfixturevalue("arg")
def test_1(arg):
pass
"""
% method
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
assert result.ret != 0
Expand Down

0 comments on commit 090f7ff

Please sign in to comment.