nose.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. """Run testsuites written for nose."""
  2. from _pytest.config import hookimpl
  3. from _pytest.fixtures import getfixturemarker
  4. from _pytest.nodes import Item
  5. from _pytest.python import Function
  6. from _pytest.unittest import TestCaseFunction
  7. @hookimpl(trylast=True)
  8. def pytest_runtest_setup(item: Item) -> None:
  9. if not isinstance(item, Function):
  10. return
  11. # Don't do nose style setup/teardown on direct unittest style classes.
  12. if isinstance(item, TestCaseFunction):
  13. return
  14. # Capture the narrowed type of item for the teardown closure,
  15. # see https://github.com/python/mypy/issues/2608
  16. func = item
  17. call_optional(func.obj, "setup")
  18. func.addfinalizer(lambda: call_optional(func.obj, "teardown"))
  19. # NOTE: Module- and class-level fixtures are handled in python.py
  20. # with `pluginmanager.has_plugin("nose")` checks.
  21. # It would have been nicer to implement them outside of core, but
  22. # it's not straightforward.
  23. def call_optional(obj: object, name: str) -> bool:
  24. method = getattr(obj, name, None)
  25. if method is None:
  26. return False
  27. is_fixture = getfixturemarker(method) is not None
  28. if is_fixture:
  29. return False
  30. if not callable(method):
  31. return False
  32. # If there are any problems allow the exception to raise rather than
  33. # silently ignoring it.
  34. method()
  35. return True