truncate.py
Overview
The `truncate.py` file provides utility functions to manage the truncation of assertion output explanations in test runs, specifically within the Pytest framework. Its main purpose is to control the verbosity of assertion failure explanations by truncating overly long outputs based on configurable limits on lines and characters. This helps keep test output concise and readable during normal test runs, while still allowing full verbosity when desired (e.g., when running tests with higher verbosity flags or in continuous integration environments).
The truncation logic is sensitive to factors such as verbosity level, environment (CI or local), and user-defined configuration parameters. When truncation occurs, a clear usage message guides the user on how to view the full output.
Detailed Description of Functions
truncate_if_required(explanation: list[str], item: Item) -> list[str]
**Purpose:** Truncates an assertion explanation if the given test item meets criteria for truncation, otherwise returns the original explanation unchanged.
**Parameters:**
explanation(list of str): The lines of the assertion explanation to potentially truncate.item(Item): The pytest test item object, used to get configuration and verbosity context.
**Returns:**
list[str]: The possibly truncated explanation lines.
**Usage Example:**
explanation = [
"Assertion failed because x != y",
"x = 5",
"y = 10",
"...",
]
truncated = truncate_if_required(explanation, test_item)
for line in truncated:
print(line)
_get_truncation_parameters(item: Item) -> tuple[bool, int, int]
**Purpose:** Determines whether truncation is needed for the given test item, and retrieves the truncation limits for lines and characters.
**Parameters:**
item(Item): The pytest test item object, used to access config and verbosity.
**Returns:**
Tuple of three elements:
bool: Whether truncation should be applied.int: Maximum number of lines allowed before truncation.int: Maximum number of characters allowed before truncation.
**Important Details:**
Truncation is skipped if:
Verbosity level ≥ 2 (
-vvor higher).Tests are running on a CI system.
Both
truncation_limit_linesandtruncation_limit_charsini config options are set to 0.
Default limits are used if not configured:
DEFAULT_MAX_LINES= 8DEFAULT_MAX_CHARS= 8 * 80 = 640
_truncate_explanation(input_lines: list[str], max_lines: int, max_chars: int) -> list[str]
**Purpose:** Truncates a list of strings representing an assertion explanation to comply with maximum line and character limits. Adds a usage message indicating how to see full output.
**Parameters:**
input_lines(list of str): The full explanation lines to truncate.max_lines(int): The maximum allowed lines before truncation.max_chars(int): The maximum allowed characters before truncation.
**Returns:**
list[str]: The truncated explanation lines with a trailing usage message.
**Algorithm / Implementation Details:**
Calculates whether truncation is necessary by comparing the total lines and concatenated character count against limits plus a tolerance.
Truncates by lines first, then by characters if still over limit.
Adds ellipsis
"..."at the end of the truncated explanation to indicate truncation.Appends a message like:
"...Full output truncated (N lines hidden), use '-vv' to show"
to guide users.
_truncate_by_char_count(input_lines: list[str], max_chars: int) -> list[str]
**Purpose:** Helper function to truncate a list of strings to ensure the total character count does not exceed a specified maximum, truncating the last line if necessary.
**Parameters:**
input_lines(list of str): Lines of text to truncate.max_chars(int): Maximum allowed total character count.
**Returns:**
list[str]: Lines truncated by character count, including a partial last line if needed.
**Implementation Details:**
Iterates through lines accumulating character counts until adding the next line would exceed
max_chars.Truncates the final line at the character limit boundary.
Constants
DEFAULT_MAX_LINES = 8
Default maximum lines when no config is set.DEFAULT_MAX_CHARS = 640
Default maximum characters, calculated asDEFAULT_MAX_LINES * 80.USAGE_MSG = "use '-vv' to show"
Message appended to truncated output indicating how to see full explanation.
Interaction With Other Parts of the System
Pytest Configuration: Uses
item.config.getini()to access ini optionstruncation_limit_linesandtruncation_limit_chars.Verbosity Level: Uses
item.config.get_verbosity()withConfig.VERBOSITY_ASSERTIONSto check verbosity level.CI Detection: Calls
util.running_on_ci()to detect if tests are running in a CI environment, bypassing truncation if so.Test Item: Operates on pytest
Itemobjects representing test cases, which provide context and configuration.
The file is typically invoked during assertion introspection phases in pytest, controlling how assertion failure explanations are displayed based on user preferences and environment.
Visual Diagram
flowchart TD
A[truncate_if_required] --> B[_get_truncation_parameters]
A --> C[_truncate_explanation]
C --> D[_truncate_by_char_count]
subgraph Explanation Flow
B -->|returns truncation flags| A
A -->|if truncate| C
C -->|if needed| D
end
**Diagram Explanation:**
truncate_if_requiredis the main entry point, calling_get_truncation_parametersto decide on truncation.If truncation is needed, it calls
_truncate_explanationto perform the truncation._truncate_explanationmay call_truncate_by_char_countto further truncate by characters.
Summary
The `truncate.py` module in pytest is a utility focused on managing the verbosity of assertion failure outputs by truncating them based on configurable line and character limits. It smartly decides when truncation should occur based on verbosity settings and environment (e.g., CI). The truncation process carefully preserves output readability and provides clear messages to users on how to see full assertion details. This enhances the usability of test output during development and automated runs.
Example Usage in Pytest Context
def test_example(item):
explanation = [
"Assertion failed:",
"x = 1234567890",
"y = 0987654321",
# potentially many more lines...
]
truncated_output = truncate_if_required(explanation, item)
for line in truncated_output:
print(line)
This will print a truncated explanation based on the current test item's verbosity and configuration.