Assertion Representation Utilities
Purpose
This component addresses the need for detailed, human-readable explanations of assertion failures in pytest. While the parent topic focuses on rewriting Python assert statements to enhance failure introspection, the Assertion Representation Utilities provide the specialized logic to compare complex objects and format their differences clearly. This makes it easier for users to understand why an assertion failed, especially when comparing complex data types like sequences, sets, dictionaries, dataclasses, and text.
Functionality
The utilities implement a set of helper functions that generate descriptive explanations for why two objects do not satisfy a comparison operation (e.g., `==`, `!=`, `in`, `not in`). Key workflows include:
Type-Directed Comparison: Depending on the types of operands (strings, sets, sequences, dictionaries, dataclasses, namedtuples), the utilities select the appropriate comparison logic to expose the root cause of inequality or unexpected results.
Diff Generation for Text: When comparing strings, a minimal diff highlighting the differing parts is created, optionally skipping identical leading or trailing content to keep the output concise.
Structured Explanation for Containers: For sequences, sets, and dictionaries, the utilities identify extra, missing, or differing elements or keys, presenting this information in a user-friendly way.
Class Attribute Comparison: For dataclasses, attrs classes, and namedtuples, fields or attributes are compared individually, showing which ones differ and drilling down into their values recursively.
Output Formatting: Explanations are formatted with indentation and optional syntax highlighting to improve readability. They are returned as lists of strings that can be rendered in pytest’s output streams.
Handling Verbosity Levels: The level of detail in explanations adjusts according to pytest’s verbosity settings, providing concise summaries by default and more detailed diffs or attribute lists when verbosity is increased.
Critical Interaction Example
The main entry point is the `assertrepr_compare` function, which pytest’s assertion rewriting infrastructure calls to generate a detailed explanation for an assertion failure:
def assertrepr_compare(config, op: str, left: Any, right: Any, use_ascii: bool = False) -> list[str] | None:
# Determines the appropriate comparison based on operand types and operator
if op == "==":
explanation = _compare_eq_any(left, right, highlighter, verbose)
elif op == "not in":
if istext(left) and istext(right):
explanation = _notin_text(left, right, verbose)
# ... other operators and types handled similarly
return [summary, *explanation] if explanation else None
This function delegates to specialized helpers like `_compare_eq_sequence`, `_compare_eq_dict`, `_diff_text`, and `_compare_eq_cls` to generate tailored explanations depending on the input types.
Relationship
Assertion Representation Utilities are a vital complement to the Assertion Rewriting system. While the rewriting transforms and instruments assert statements to capture expression internals, the representation utilities interpret the captured data to produce meaningful, detailed failure messages.
Together, they form a two-part mechanism:
Assertion Rewriting: Modifies assert bytecode to intercept failures and collect comparison data.
Representation Utilities: Analyzes the data to produce rich, context-aware explanations for diverse data types.
This subtopic also integrates with pytest’s terminal output and verbosity controls, enabling users to customize how much detail they see in assertion failure reports. It is distinct from the AST Transformations subtopic by focusing on explaining differences rather than altering the code’s abstract syntax.
Diagram
flowchart TD
A[Assertion Failure Detected]
B[Assert Statement Rewritten]
C[Capture Left & Right Values]
D[assertrepr_compare Called]
E{Operand Types?}
F[Compare Strings & Generate Diff]
G[Compare Sequences]
H[Compare Sets]
I[Compare Dicts]
J[Compare Dataclasses/Attrs/Namedtuples]
K[Format Explanation & Highlight]
L[Return Explanation Lines]
M[Display to User]
A --> B --> C --> D --> E
E -->|Strings| F --> K
E -->|Sequences| G --> K
E -->|Sets| H --> K
E -->|Dicts| I --> K
E -->|Dataclasses etc.| J --> K
K --> L --> M
This flowchart illustrates the core process of how assertion differences are analyzed and formatted into detailed explanations delivered to the user.
This focused utility layer enriches pytest’s assertion introspection by providing clear, type-aware explanations that help users quickly diagnose test failures involving complex data comparisons.