Add remove_finalizer function
This commit is contained in:
parent
eb8b3ad929
commit
791805984b
1
AUTHORS
1
AUTHORS
|
@ -285,6 +285,7 @@ Roberto Polli
|
|||
Roland Puntaier
|
||||
Romain Dorgueil
|
||||
Roman Bolshakov
|
||||
Roni Kishner
|
||||
Ronny Pfannschmidt
|
||||
Ross Lawley
|
||||
Ruaridh Williamson
|
||||
|
|
|
@ -730,6 +730,11 @@ Here's how the previous example would look using the ``addfinalizer`` method:
|
|||
It's a bit longer than yield fixtures and a bit more complex, but it
|
||||
does offer some nuances for when you're in a pinch.
|
||||
|
||||
In addition you can use the remove_finalizer method to remove a finalizer you added
|
||||
to the teardown stage.
|
||||
The remove_finalizer method will remove the first finalizer match it finds and return True,
|
||||
if no match was found the function will return None.
|
||||
|
||||
.. code-block:: pytest
|
||||
|
||||
$ pytest -q test_emaillib.py
|
||||
|
|
|
@ -760,6 +760,11 @@ class SubRequest(FixtureRequest):
|
|||
within the requesting test context finished execution."""
|
||||
self._fixturedef.addfinalizer(finalizer)
|
||||
|
||||
def remove_finalizer(self, finalizer: Callable[[], object]) -> None:
|
||||
"""Remove finalizer/teardown function to be called after the last test
|
||||
within the requesting test context finished execution."""
|
||||
return self._fixturedef.remove_finalizer(finalizer)
|
||||
|
||||
def _schedule_finalizers(
|
||||
self, fixturedef: "FixtureDef[object]", subrequest: "SubRequest"
|
||||
) -> None:
|
||||
|
@ -1003,6 +1008,12 @@ class FixtureDef(Generic[FixtureValue]):
|
|||
def addfinalizer(self, finalizer: Callable[[], object]) -> None:
|
||||
self._finalizers.append(finalizer)
|
||||
|
||||
def remove_finalizer(self, finalizer: Callable[[], object]) -> None:
|
||||
for finalizer_index, finalizer_func in enumerate(self._finalizers):
|
||||
if finalizer_func.__qualname__ == finalizer.__qualname__:
|
||||
del self._finalizers[finalizer_index]
|
||||
return True
|
||||
|
||||
def finish(self, request: SubRequest) -> None:
|
||||
exc = None
|
||||
try:
|
||||
|
|
|
@ -503,6 +503,20 @@ class SetupState:
|
|||
assert node in self.stack, (node, self.stack)
|
||||
self.stack[node][0].append(finalizer)
|
||||
|
||||
def remove_finalizer(self, finalizer: Callable[[], object], node: Node) -> None:
|
||||
"""Remove a finalizer in the given node by name.
|
||||
|
||||
The node must be currently active in the stack.
|
||||
The first finalizer by name will be removed.
|
||||
"""
|
||||
assert node and not isinstance(node, tuple)
|
||||
assert callable(finalizer)
|
||||
assert node in self.stack, (node, self.stack)
|
||||
for finalizer_index, finalizer_func in enumerate(self.stack[node][0]):
|
||||
if finalizer_func.__qualname__ == finalizer.__qualname__:
|
||||
del self.stack[node][0][finalizer_index]
|
||||
return True
|
||||
|
||||
def teardown_exact(self, nextitem: Optional[Item]) -> None:
|
||||
"""Teardown the current stack up until reaching nodes that nextitem
|
||||
also descends from.
|
||||
|
|
|
@ -857,11 +857,33 @@ class TestRequestBasic:
|
|||
parent = item.getparent(pytest.Module)
|
||||
assert parent is not None
|
||||
teardownlist = parent.obj.teardownlist
|
||||
item.session._setupstate.teardown_exact(None)
|
||||
assert teardownlist == [1]
|
||||
|
||||
def test_request_remove_finalizer(self, pytester: Pytester) -> None:
|
||||
item = pytester.getitem(
|
||||
"""
|
||||
import pytest
|
||||
teardownlist = []
|
||||
@pytest.fixture
|
||||
def something(request):
|
||||
request.addfinalizer(lambda: teardownlist.append(1))
|
||||
request.remove_finalizer(lambda: teardownlist.append(1))
|
||||
def test_func(something): pass
|
||||
"""
|
||||
)
|
||||
assert isinstance(item, Function)
|
||||
item.session._setupstate.setup(item)
|
||||
item._request._fillfixtures()
|
||||
# successively check finalization calls
|
||||
parent = item.getparent(pytest.Module)
|
||||
assert parent is not None
|
||||
teardownlist = parent.obj.teardownlist
|
||||
ss = item.session._setupstate
|
||||
assert not teardownlist
|
||||
ss.teardown_exact(None)
|
||||
print(ss.stack)
|
||||
assert teardownlist == [1]
|
||||
assert teardownlist == []
|
||||
|
||||
def test_request_addfinalizer_failing_setup(self, pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
|
|
Loading…
Reference in New Issue