util.py


Overview

[util.py](/projects/286/67331) is a utility module dedicated to enhancing assertion debugging within the pytest testing framework. Its primary purpose is to provide rich, detailed, and human-readable explanations for assertion failures, especially when comparing complex data types such as sequences, sets, dictionaries, dataclasses, namedtuples, and text strings.

When an assertion fails, pytest's assertion rewriting machinery invokes functions in this module to generate specialized explanations that clarify why two objects did not satisfy the asserted condition. This includes generating diffs for strings, identifying differing elements in collections, and recursively comparing attributes of structured data types.

Key features include:

This module is crucial for improving the developer experience by making assertion failure messages more informative and actionable.


Detailed Explanations

Module-Level Variables

Variable

Type

Description

`_reprcompare`

[Callable[[str, object, object], str

None]

`_assertion_pass`

[Callable[[int, str, str], None]

None](/projects/286/67223)

_config

[Config

None](/projects/286/67332)


Classes and Protocols

_HighlightFunc (Protocol)

Protocol describing a highlighting function interface.

def __call__(self, source: str, lexer: Literal["diff", "python"] = "python") -> str:
    """Apply syntax highlighting to the given source string."""

**Usage:** Used as a type hint for highlighter functions passed to various comparison functions.


Functions

dummy_highlighter(source: str, lexer: Literal["diff", "python"] = "python") -> str

A no-op highlighter that returns the input text unmodified.


format_explanation(explanation: str) -> str

Formats an assertion explanation string applying a minimal mini-formatting language to represent nested or multi-line explanations.

**Example:**

raw_expl = "Mismatch\n{Details\n~More info\n}"
print(format_explanation(raw_expl))

issequence(x: Any) -> bool

Returns `True` if `x` is a non-string sequence.


istext(x: Any) -> bool

Returns `True` if `x` is a string.


isdict(x: Any) -> bool

Returns `True` if `x` is a dictionary.


isset(x: Any) -> bool

Returns `True` if `x` is a set or frozenset.


isnamedtuple(obj: Any) -> bool

Returns `True` if `obj` is a namedtuple instance.


isdatacls(obj: Any) -> bool

Returns `True` if `obj` is a dataclass instance.


isattrs(obj: Any) -> bool

Returns `True` if `obj` is an instance of a class decorated with `@attrs`.


isiterable(obj: Any) -> bool

Returns `True` if `obj` is iterable but not a string.


has_default_eq(obj: object) -> bool

Determines if the object `obj` has the default equality method (`__eq__`) generated by dataclasses or attrs, by inspecting the code object filename or known markers.


assertrepr_compare(config, op: str, left: Any, right: Any, use_ascii: bool = False) -> list[str] | None

Main entry point to generate a human-readable explanation for why a comparison assertion failed.

**Usage Example:**

explanation = assertrepr_compare(config, "==", [1, 2, 3], [1, 2, 4])
if explanation:
    print("\n".join(explanation))

_compare_eq_any(left: Any, right: Any, highlighter: _HighlightFunc, verbose: int = 0) -> list[str]

Helper to compare two objects with `==`, dispatching to specialized comparators based on type.


_diff_text(left: str, right: str, highlighter: _HighlightFunc, verbose: int = 0) -> list[str]

Generates a diff-style explanation between two strings.


_compare_eq_iterable(left: Iterable[Any], right: Iterable[Any], highlighter: _HighlightFunc, verbose: int = 0) -> list[str]

Generates a detailed diff for two iterables.


_compare_eq_sequence(left: Sequence[Any], right: Sequence[Any], highlighter: _HighlightFunc, verbose: int = 0) -> list[str]

Compares two sequences element-wise, reporting the first differing index and any length differences.


_compare_eq_set(left: AbstractSet[Any], right: AbstractSet[Any], highlighter: _HighlightFunc, verbose: int = 0) -> list[str]

Compares two sets, reporting extra items in each set.


_compare_gt_set, _compare_lt_set, _compare_gte_set, _compare_lte_set

Specialized set comparisons for `>`, `<`, `>=`, `<=` operators that report differences or equality.


_set_one_sided_diff(posn: str, set1: AbstractSet[Any], set2: AbstractSet[Any], highlighter: _HighlightFunc) -> list[str]

Helper to report extra items in one set compared to another.


_compare_eq_dict(left: Mapping[Any, Any], right: Mapping[Any, Any], highlighter: _HighlightFunc, verbose: int = 0) -> list[str]

Compares two dictionaries:


_compare_eq_cls(left: Any, right: Any, highlighter: _HighlightFunc, verbose: int) -> list[str]

Compares two instances of dataclasses, attrs classes, or namedtuples field-by-field:


_notin_text(term: str, text: str, verbose: int = 0) -> list[str]

Specialized explanation for `"not in"` operator when both operands are strings.


running_on_ci() -> bool

Utility that returns `True` if the current environment appears to be a Continuous Integration (CI) system.


Important Implementation Details and Algorithms


Interaction with Other Components


Visual Diagram: Function Flowchart

flowchart TD
    A[assertrepr_compare] --> B{Operator?}
    B -->|==| C[_compare_eq_any]
    B -->|not in| D[_notin_text]
    B -->|!=| E[Set equality check]
    B -->|>=| F[_compare_gte_set]
    B -->|<=| G[_compare_lte_set]
    B -->|>| H[_compare_gt_set]
    B -->|<| I[_compare_lt_set]

    C --> J{Type of operands?}
    J -->|Strings| K[_diff_text]
    J -->|Sequences| L[_compare_eq_sequence]
    J -->|Sets| M[_compare_eq_set]
    J -->|Dicts| N[_compare_eq_dict]
    J -->|Dataclasses/Attrs/Namedtuples| O[_compare_eq_cls]
    J -->|Iterable| P[_compare_eq_iterable]

    K --> Q[Format & highlight diff]
    L --> Q
    M --> Q
    N --> Q
    O --> Q
    P --> Q

    Q --> R[Return explanation lines]

Summary

The [util.py](/projects/286/67331) module is a central utility for pytest’s enhanced assertion debugging. By providing detailed, type-aware, and visually formatted explanations of assertion failures, it significantly improves the clarity of test failure reports. It handles a broad variety of data types and operators, leverages pytest’s configuration for verbosity and highlighting, and integrates tightly with pytest’s internal assertion rewriting system.

This file enables pytest users to quickly identify the root cause of assertion failures, especially when dealing with complex or nested data structures, making debugging more efficient and less error-prone.


End of documentation for util.py