From 3dde519f53b4480a3b30d58a1c71ca4505ae5ff7 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Thu, 14 Jan 2021 17:42:38 +0200 Subject: nose: type annotate with some resulting refactoring --- src/_pytest/nose.py | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/_pytest/nose.py b/src/_pytest/nose.py index 5bba030a5..16d5224e9 100644 --- a/src/_pytest/nose.py +++ b/src/_pytest/nose.py @@ -1,33 +1,35 @@ """Run testsuites written for nose.""" -from _pytest import python -from _pytest import unittest from _pytest.config import hookimpl from _pytest.fixtures import getfixturemarker from _pytest.nodes import Item +from _pytest.python import Function +from _pytest.unittest import TestCaseFunction @hookimpl(trylast=True) -def pytest_runtest_setup(item) -> None: - if is_potential_nosetest(item): - if not call_optional(item.obj, "setup"): - # Call module level setup if there is no object level one. - call_optional(item.parent.obj, "setup") - # XXX This implies we only call teardown when setup worked. - item.addfinalizer(lambda: teardown_nose(item)) - - -def teardown_nose(item) -> None: - if is_potential_nosetest(item): - if not call_optional(item.obj, "teardown"): - call_optional(item.parent.obj, "teardown") - - -def is_potential_nosetest(item: Item) -> bool: - # Extra check needed since we do not do nose style setup/teardown - # on direct unittest style classes. - return isinstance(item, python.Function) and not isinstance( - item, unittest.TestCaseFunction - ) +def pytest_runtest_setup(item: Item) -> None: + if not isinstance(item, Function): + return + # Don't do nose style setup/teardown on direct unittest style classes. + if isinstance(item, TestCaseFunction): + return + + # Capture the narrowed type of item for the teardown closure, + # see https://github.com/python/mypy/issues/2608 + func = item + + if not call_optional(func.obj, "setup"): + # Call module level setup if there is no object level one. + assert func.parent is not None + call_optional(func.parent.obj, "setup") # type: ignore[attr-defined] + + def teardown_nose() -> None: + if not call_optional(func.obj, "teardown"): + assert func.parent is not None + call_optional(func.parent.obj, "teardown") # type: ignore[attr-defined] + + # XXX This implies we only call teardown when setup worked. + func.addfinalizer(teardown_nose) def call_optional(obj: object, name: str) -> bool: -- cgit v1.2.3