warning_types.py
Overview
The [warning_types.py](/projects/286/67431) file defines a structured hierarchy of custom warning classes used throughout the pytest testing framework. These warnings categorize various issues and informational signals encountered during pytest’s operation, such as configuration problems, deprecated features, experimental APIs, and runtime anomalies like unhandled exceptions or resource leaks.
Additionally, this file provides utility constructs to handle warnings that require dynamic message formatting at runtime and a helper function to emit warnings explicitly tied to specific function definitions with accurate source location information.
The main goals of this file are:
To centralize pytest-specific warning categories with clear semantics.
To enable flexible, informative warning messages.
To facilitate accurate and contextual warning issuance that integrates cleanly with Python’s built-in
warningsmodule.
Classes
PytestWarning
class PytestWarning(UserWarning)
Purpose: Base class for all warnings emitted by pytest.
Details: Inherits from Python’s built-in
UserWarning. Serves as the common ancestor to all pytest warning types, enabling users to filter pytest warnings collectively.Usage Example:
import warnings
warnings.warn("This is a generic pytest warning", PytestWarning)
PytestAssertRewriteWarning
@final
class PytestAssertRewriteWarning(PytestWarning)
Purpose: Warning emitted by the pytest assert rewrite module.
Details: Marked
finalto prevent subclassing; signals issues related to pytest’s assertion rewriting mechanism.Usage Example:
warnings.warn("Assert rewrite issue detected", PytestAssertRewriteWarning)
PytestCacheWarning
@final
class PytestCacheWarning(PytestWarning)
Purpose: Warning emitted by the cache plugin in various situations.
Details: Indicates problems or noteworthy events related to pytest’s caching system.
PytestConfigWarning
@final
class PytestConfigWarning(PytestWarning)
Purpose: Warning emitted for configuration issues.
Details: Useful for highlighting problems or inconsistencies in pytest configuration files or settings.
PytestCollectionWarning
@final
class PytestCollectionWarning(PytestWarning)
Purpose: Warning emitted when pytest is unable to collect a file or symbol in a module.
Details: Helps users diagnose why tests or modules might not be discovered during test collection.
PytestDeprecationWarning
class PytestDeprecationWarning(PytestWarning, DeprecationWarning)
Purpose: Indicates usage of features that will be removed in a future pytest version.
Details: Multiple inheritance from both
PytestWarningand Python’s built-inDeprecationWarningto integrate with both pytest and Python deprecation mechanisms.
PytestRemovedIn9Warning
class PytestRemovedIn9Warning(PytestDeprecationWarning)
Purpose: Specific deprecation warning for features planned to be removed in pytest 9.
Details: A specialized subclass for deprecations tied to a major future version.
PytestExperimentalApiWarning
@final
class PytestExperimentalApiWarning(PytestWarning, FutureWarning)
Purpose: Denotes experimental API features that may change or be removed.
Details: Inherits from
FutureWarningto align with Python’s conventions for experimental features.Methods:
simple(apiname: str) -> PytestExperimentalApiWarning
Creates a warning instance with a formatted message indicating the experimental nature of an API.
Usage Example:
warnings.warn(PytestExperimentalApiWarning.simple("my_new_feature"))
PytestReturnNotNoneWarning
@final
class PytestReturnNotNoneWarning(PytestWarning)
Purpose: Warns when a test function returns a non-
Nonevalue.Details: Helps enforce best practices by discouraging tests that return values.
Reference: See pytest documentation under
return-not-none.
PytestUnknownMarkWarning
@final
class PytestUnknownMarkWarning(PytestWarning)
Purpose: Warns on usage of unknown test markers.
Details: Assists users in identifying typos or deprecated marker usage.
Reference: See pytest documentation under
mark.
PytestUnraisableExceptionWarning
@final
class PytestUnraisableExceptionWarning(PytestWarning)
Purpose: Warns when an unraisable exception occurs (e.g., in
__del__methods).Details: Highlights exceptions that happen in contexts where they cannot be propagated normally.
PytestUnhandledThreadExceptionWarning
@final
class PytestUnhandledThreadExceptionWarning(PytestWarning)
Purpose: Warns when an unhandled exception occurs inside a
threading.Thread.Details: Since exceptions in threads do not propagate to the main thread, this warns users to ensure thread errors aren’t silently lost.
PytestFDWarning
@final
class PytestFDWarning(PytestWarning)
Purpose: Warns about leaked file descriptors detected by the
lsofplugin.Details: Useful for resource leak detection during tests.
UnformattedWarning
@final
@dataclasses.dataclass
class UnformattedWarning(Generic[_W]):
Purpose: Holds warnings with messages that require runtime formatting.
Generics: Parameterized by
_W, which is a subtype ofPytestWarning.Fields:
category: type[_W]— The warning class to instantiate.template: str— Message template string with placeholders.
Methods:
format(**kwargs: Any) -> _W
Formats the template string with the provided keyword arguments and returns an instance of the warning category with the formatted message.
Usage Example:
uw = UnformattedWarning(PytestExperimentalApiWarning, "{} is experimental")
warn_instance = uw.format(apiname="my_api")
warnings.warn(warn_instance)
Implementation detail: Uses Python’s
str.format()for message construction, enabling deferred interpolation.
Functions
warn_explicit_for
def warn_explicit_for(method: FunctionType, message: PytestWarning) -> None:
Purpose: Emits a warning explicitly tied to the definition location of a given function or method.
Parameters:
method: FunctionType— The function object for which the warning applies.message: PytestWarning— The warning instance to emit.
Behavior:
Extracts the source filename, line number, and module from the function object.
Uses
warnings.warn_explicit()to emit the warning with accurate source location.If warnings are treated as errors (e.g.,
-Werror), and location data is lost, it appends the location info to the exception message before raising.
Usage Example:
def my_hook():
pass
warn_explicit_for(my_hook, PytestConfigWarning("Deprecated hook signature"))
Implementation details:
Uses
inspect.getfile()and function code attributes for location info.Accesses the function’s global namespace to manage the warning registry.
Implementation Details and Algorithms
Use of
@final: Many warning classes are marked as@final(fromtyping) to prevent subclassing, indicating these are intended as concrete warning types.Multiple Inheritance for Deprecations:
PytestDeprecationWarninginherits both fromPytestWarningand Python’s built-inDeprecationWarningto be compatible with Python’s warning filtering.Dynamic Message Formatting:
UnformattedWarningenables deferred message interpolation, allowing warnings to be constructed with context-dependent data at runtime.Explicit Warning Emission: The
warn_explicit_forfunction ensures warnings can be emitted with precise source code references, improving diagnostics especially for legacy or dynamically defined functions.
Interaction with Other Parts of the System
These warning classes are imported and used across pytest’s core and plugins to signal specific conditions to users.
The warnings integrate with Python’s standard
warningsmodule, allowing users to filter, suppress, or escalate pytest warnings as needed.The
warn_explicit_forfunction is likely used internally during pytest’s hook or plugin processing to associate warnings with the exact function definitions.The
UnformattedWarningclass supports plugins or internal components that generate warnings with variable content, enabling consistent formatting.
Visual Diagram
classDiagram
class PytestWarning {
<<UserWarning>>
}
class PytestAssertRewriteWarning {
<<final>>
}
class PytestCacheWarning {
<<final>>
}
class PytestConfigWarning {
<<final>>
}
class PytestCollectionWarning {
<<final>>
}
class PytestDeprecationWarning {
}
class PytestRemovedIn9Warning {
}
class PytestExperimentalApiWarning {
+classmethod simple(apiname: str) PytestExperimentalApiWarning
<<final>>
}
class PytestReturnNotNoneWarning {
<<final>>
}
class PytestUnknownMarkWarning {
<<final>>
}
class PytestUnraisableExceptionWarning {
<<final>>
}
class PytestUnhandledThreadExceptionWarning {
<<final>>
}
class PytestFDWarning {
<<final>>
}
class UnformattedWarning~_W~ {
-category: type[_W]
-template: str
+format(**kwargs) _W
<<final>>
}
PytestAssertRewriteWarning --|> PytestWarning
PytestCacheWarning --|> PytestWarning
PytestConfigWarning --|> PytestWarning
PytestCollectionWarning --|> PytestWarning
PytestDeprecationWarning --|> PytestWarning
PytestRemovedIn9Warning --|> PytestDeprecationWarning
PytestExperimentalApiWarning --|> PytestWarning
PytestReturnNotNoneWarning --|> PytestWarning
PytestUnknownMarkWarning --|> PytestWarning
PytestUnraisableExceptionWarning --|> PytestWarning
PytestUnhandledThreadExceptionWarning --|> PytestWarning
PytestFDWarning --|> PytestWarning
Summary
The [warning_types.py](/projects/286/67431) module is a foundational part of pytest’s infrastructure for communicating issues, deprecations, and informational signals to users via Python’s warning system. Its well-organized class hierarchy, support for runtime message formatting, and explicit warning emission facilitate clear, contextual, and maintainable warning handling throughout the pytest ecosystem.