outcomes.py
Overview
The [outcomes.py](/projects/286/67331) module is a core utility file designed to handle test outcomes within a testing framework, specifically pytest. It defines exception classes that represent various test results such as skips, failures, and expected failures (xfail). Additionally, it provides imperative functions (`skip()`, `fail()`, `xfail()`, `exit()`) that raise these exceptions to communicate specific test outcomes programmatically during test execution or collection.
A key feature of this module is the `importorskip()` function, which attempts to import a module and skips the current test if the import fails or if the module version is insufficient. This utility aids in writing conditional tests that depend on optional dependencies.
Overall, [outcomes.py](/projects/286/67331) provides a structured, exception-based mechanism for signaling test outcomes and controlling test flow by raising specialized exceptions that the pytest framework interprets to generate reports, skip tests, or stop execution.
Classes
OutcomeException(BaseException)
Base class for exceptions that represent test and collection outcomes. Subclasses of `OutcomeException` encapsulate information about test results like skipping or failing.
Parameters:
msg: str | None— Optional message describing the outcome.pytrace: bool— IfTrue, include Python traceback information for the exception.
Attributes:
msg: Stores the message.pytrace: Indicates whether to show traceback.
Methods:
__init__(msg=None, pytrace=True): Initializes the exception with message and traceback flag. Raises TypeError ifmsgis not a string orNone.__repr__(): Returns the message string if present; otherwise, a generic instance representation.__str__: Alias for__repr__.
Usage Example:
try: raise OutcomeException("Custom outcome message") except OutcomeException as e: print(e) # Output: Custom outcome message
Skipped(OutcomeException)
Exception indicating a test was skipped.
Special behavior:
Fakes its module as
"builtins"to produce cleaner exception output.
Parameters:
msg: str | None— Message explaining the skip reason.pytrace: bool— Whether to display traceback.allow_module_level: bool— Allow skipping at the module level (prevents collection of all tests in the module)._use_item_location: bool(keyword-only) — IfTrue, reports skip location as the test item's location rather than where skip was called.
Usage Example:
raise Skipped("This test is skipped due to missing resource")
Failed(OutcomeException)
Exception indicating a test failure triggered explicitly (e.g., via `pytest.fail()`).
Parameters: Same as
OutcomeException.Usage Example:
raise Failed("Test failed explicitly")
Exit(Exception)
Exception used for immediate program exits without tracebacks or summaries.
Parameters:
msg: str— Reason for exit (default"unknown reason").returncode: int | None— Exit code to return to the system (Nonemeans exit code 0).
Usage Example:
raise Exit("Exiting due to critical error", returncode=1)
XFailed(Failed)
Exception indicating an expected failure (`pytest.xfail()`).
Parameters: Same as
Failed.Usage Example:
raise XFailed("Known bug causes this test to fail")
_Exit
Callable class to raise an `Exit` exception.
Attributes:
Exception: Class variable referencing theExitexception class.
Methods:
__call__(reason: str = "", returncode: int | None = None) -> NoReturn: Raises anExitexception with the provided reason and return code.
Usage Example:
exit("Finished tests early", returncode=0)
_Skip
Callable class to raise a `Skipped` exception.
Attributes:
Exception: Class variable referencing theSkippedexception class.
Methods:
__call__(reason: str = "", allow_module_level: bool = False) -> NoReturn: Raises aSkippedexception with the given reason and module-level allowance.
Usage Example:
skip("Skipping this test because of unmet dependency")
_Fail
Callable class to raise a `Failed` exception.
Attributes:
Exception: Class variable referencing theFailedexception class.
Methods:
__call__(reason: str = "", pytrace: bool = True) -> NoReturn: Raises aFailedexception with the given reason and traceback flag.
Usage Example:
fail("Explicit failure due to assertion")
_XFail
Callable class to raise an `XFailed` exception.
Attributes:
Exception: Class variable referencing theXFailedexception class.
Methods:
__call__(reason: str = "") -> NoReturn: Raises anXFailedexception with the given reason.
Usage Example:
xfail("Expected failure: bug #123")
Functions
importorskip(modname: str, minversion: str | None = None, reason: str | None = None, *, exc_type: type[ImportError] | None = None) -> Any
Attempts to import a module by name. If the module cannot be imported, or if the module's version is less than the specified minimum version, it raises a `Skipped` exception to skip the current test.
Parameters:
modname: The module name to import.minversion: Optional minimal version string. The module's__version__attribute must be greater than or equal to this.reason: Optional custom skip reason if import fails.exc_type: Exception type to catch when importing; defaults toImportError. Useful to suppress warnings or change behavior.
Returns:
The imported module if successful and version requirements are met.
Raises:
Skippedexception if import fails or version is insufficient.
Implementation details:
Compiles the module name to catch syntax errors early.
Uses
warnings.catch_warnings()to silence irrelevant import warnings.Warns users if an
ImportError(notModuleNotFoundError) is caught, which might indicate installation issues.Uses
packaging.version.Versionfor version comparison.The skip exception is raised with
allow_module_level=Trueto allow module-level skipping.
Usage Example:
docutils = importorskip("docutils", minversion="0.17", reason="Docutils >= 0.17 required")
Module-level Variables (Callable Instances)
These variables are instances of the callable classes above, providing a simple API to raise outcome exceptions:
skip: Instance of_Skipfor skipping tests.fail: Instance of_Failfor failing tests.xfail: Instance of_XFailfor expected failures.exit: Instance of_Exitfor exiting pytest immediately.
Important Implementation Details
The exceptions inherit from
BaseException(orException) to integrate cleanly with pytest's exception handling.The
Skippedexception is designed to integrate nicely with Python 3's built-in exceptions by faking its module as"builtins".The
importorskip()function carefully handles import errors and version checks, providing informative warnings and skip reasons.Use of
__tracebackhide__ = Truein callables suppresses tracebacks for these exceptions in pytest output, leading to cleaner test reports.The module uses type annotations extensively for clarity and static checking.
Exception classes carry messages and flags to control the display of Python tracebacks, allowing flexible reporting.
Interactions with Other Parts of the System
The exceptions defined here are used throughout pytest to signal specific outcomes (skipping, failure, xfail) during test collection and execution.
The callable instances (
skip,fail,xfail,exit) are the public API that test code and pytest internals invoke to control test flow.importorskip()is a helper utility often used in test code to conditionally skip tests depending on optional dependencies.The module imports
PytestDeprecationWarningfrom.warning_typesto issue warnings related to deprecation of import error handling.The exceptions raised here are caught by pytest's core runner to generate reports and control test session lifecycle.
Visual Diagram
classDiagram
class OutcomeException {
+msg: str | None
+pytrace: bool
+__init__(msg: str | None, pytrace: bool)
+__repr__() str
}
class Skipped {
+allow_module_level: bool
+_use_item_location: bool
+__init__(msg: str | None, pytrace: bool, allow_module_level: bool, _use_item_location: bool)
}
class Failed {
+__init__(msg: str | None, pytrace: bool)
}
class Exit {
+msg: str
+returncode: int | None
+__init__(msg: str, returncode: int | None)
}
class XFailed {
+__init__(msg: str | None, pytrace: bool)
}
class _Exit {
+Exception: Exit
+__call__(reason: str, returncode: int | None) -> NoReturn
}
class _Skip {
+Exception: Skipped
+__call__(reason: str, allow_module_level: bool) -> NoReturn
}
class _Fail {
+Exception: Failed
+__call__(reason: str, pytrace: bool) -> NoReturn
}
class _XFail {
+Exception: XFailed
+__call__(reason: str) -> NoReturn
}
OutcomeException <|-- Skipped
OutcomeException <|-- Failed
Failed <|-- XFailed
Exception <|-- Exit
_Exit --> Exit : Exception
_Skip --> Skipped : Exception
_Fail --> Failed : Exception
_XFail --> XFailed : Exception
Summary
The [outcomes.py](/projects/286/67331) module provides a clean and extensible exception-based mechanism for signaling test outcomes within pytest. By defining specialized exceptions and callable wrappers, it simplifies the process of skipping, failing, marking expected failures, and exiting tests programmatically. The `importorskip()` utility further enhances test flexibility by enabling conditional imports with graceful skipping and version validation.
This module underpins key control flow decisions during test runs, contributing to pytest's robust and user-friendly testing experience.