pprint.py
Overview
The `pprint.py` module provides a flexible and extensible system for **pretty-printing Python data structures**. It formats complex and nested Python objects into readable, indented, and well-structured string representations. This module is particularly useful for debugging, logging, or displaying data structures that are deeply nested or contain mixed types, making them easier to understand at a glance.
Modeled after Lisp/Scheme-style pretty-printing, this module was originally created to aid in visualizing heavily nested tuples and other collections with non-descriptive content.
Main Components
Class: PrettyPrinter
This is the core class responsible for formatting Python objects into human-readable strings with configurable indentation and width settings.
Initialization
PrettyPrinter(indent: int = 4, width: int = 80, depth: int | None = None) -> None
Parameters:
indent(int): Number of spaces to indent for each level of nesting (default: 4).width(int): Maximum number of columns in the output (default: 80).depth(int | None): Maximum depth to print nested structures;Nonemeans unlimited (default: None).
Raises:
ValueErrorifindentis negative,widthis zero, ordepthis non-positive (if specified).
Description:
Creates aPrettyPrinterinstance that formats objects according to these parameters.
Methods
pformat(object: Any) -> str
Description:
Returns a pretty-printed string representation of the given object.Parameters:
object(Any): The Python object to pretty-print.
Returns:
str: The formatted string representation.
Usage Example:
printer = PrettyPrinter(indent=2, width=60) nested_list = [[1, 2], [3, 4, [5, 6]]] print(printer.pformat(nested_list))
_format(object: Any, stream: IO[str], indent: int, allowance: int, context: set[int], level: int) -> None
Description:
Internal recursive method that writes a pretty-printed representation ofobjectto thestream.Parameters:
object(Any): Object to format.stream(IO[str]): Output stream to write the formatted string.indent(int): Current indentation level (spaces).allowance(int): Space allowance for closing delimiters.context(set[int]): Set of object IDs to detect recursion.level(int): Current recursion depth.
Details:
Detects recursion and dispatches to appropriate formatting methods based on the object's type and class.
_repr(object: Any, context: set[int], level: int) -> str
Description:
Returns a safe string representation ofobject, limiting recursion and depth.Parameters:
object(Any): Object to represent.context(set[int]): Set of object IDs to detect recursive references.level(int): Current recursion depth.
Returns:
str: The string representation.
_safe_repr(object: Any, context: set[int], maxlevels: int | None, level: int) -> str
Description:
Provides a recursive and safe representation of objects, respectingmaxlevelsdepth and avoiding infinite recursion by detecting cycles.Parameters:
object(Any): Object to represent.context(set[int]): Tracking set for recursion detection.maxlevels(int | None): Maximum depth allowed.level(int): Current recursion level.
Returns:
A string representation that safely handles nested containers (dicts, lists, tuples) and built-in scalar types.
Formatting Methods for Built-in and Special Types
The class maintains a `_dispatch` dictionary mapping specific `__repr__` methods to custom formatting functions that handle types like:
dict(_pprint_dict)collections.OrderedDict(_pprint_ordered_dict)list(_pprint_list)tuple(_pprint_tuple)setandfrozenset(_pprint_set)str(_pprint_str)bytes(_pprint_bytes)bytearray(_pprint_bytearray)types.MappingProxyType(_pprint_mappingproxy)types.SimpleNamespace(_pprint_simplenamespace)collections.defaultdict(_pprint_default_dict)collections.Counter(_pprint_counter)collections.ChainMap(_pprint_chain_map)collections.deque(_pprint_deque)collections.UserDict(_pprint_user_dict)collections.UserList(_pprint_user_list)collections.UserString(_pprint_user_string)
Each method formats the object type with indentation and recursively formats contained items, handling empty containers and special cases gracefully.
Helper Formatting Functions
_format_dict_items: Formats key-value pairs in dictionaries._format_namespace_items: Formats attributes of dataclass-like or namespace objects._format_items: Formats items in sequences (list, tuple, set)._pprint_dataclass: Special pretty-printing of dataclasses with field inspection._recursion: Returns a string indicating recursion detected on an object._wrap_bytes_repr: Helps format long bytes sequences by wrapping lines for readability.
Supporting Classes and Functions
Class: _safe_key
Purpose:
Wraps objects to provide a fallback comparison method for sorting unorderable types, to avoidTypeErrorduring sorting.Usage:
Used primarily in sorting dictionary items and sets where element types may not be directly comparable.Key Method:
__lt__(other): Tries normal comparison; onTypeError, falls back to comparing the type names and ids.
Function: _safe_tuple(t)
Purpose:
Helper function for safely comparing 2-tuples by wrapping each element using_safe_key.
Important Implementation Details
Recursion Detection:
Uses a set of object IDs (context) to detect cycles and prevent infinite recursion during formatting.Dispatch Mechanism:
The_dispatchdictionary maps types’__repr__methods to specialized pretty-print functions, allowing extensibility and clean separation of formatting logic per type.Dataclass Support:
Automatically detects and pretty-prints Python dataclasses by inspecting fields and their repr inclusion.Sorting of Items:
Dictionary and set items are sorted using_safe_tupleand_safe_keyto ensure consistent and error-free ordering, even with mixed or unorderable types.Width and Indentation Management:
The formatting methods respect the configured width and indent to produce visually appealing output that wraps long lines intelligently (e.g.,_pprint_strsplits long strings across lines).
Interaction with Other Modules
Uses Python standard library modules:
collectionsandcollections.abcfor container types and abstract base classes.dataclassesfor dataclass detection and field introspection.io.StringIOfor in-memory string buffering during formatting.refor regex splitting of strings when wrapping.typesfor identifying special types likeMappingProxyTypeandSimpleNamespace.typingfor type annotations.
This module is self-contained but designed to format objects from these standard modules elegantly.
The module has roots in the Python standard library (
cpython), making it a reliable and canonical pretty-printing solution.
Usage Example
from pprint import PrettyPrinter
data = {
"users": [
{"name": "Alice", "age": 30, "tags": {"python", "developer"}},
{"name": "Bob", "age": 25, "tags": {"java", "tester"}},
],
"count": 2,
}
printer = PrettyPrinter(indent=2, width=50)
print(printer.pformat(data))
Output:
{
'count': 2,
'users': [
{
'age': 30,
'name': 'Alice',
'tags': {'developer', 'python'},
},
{
'age': 25,
'name': 'Bob',
'tags': {'java', 'tester'},
},
],
}
Mermaid Diagram: Structure of pprint.py
classDiagram
class PrettyPrinter {
-_depth: int | None
-_indent_per_level: int
-_width: int
-_dispatch: dict
+__init__(indent: int, width: int, depth: int | None)
+pformat(object: Any) str
-_format(object: Any, stream: IO[str], indent: int, allowance: int, context: set[int], level: int) void
-_repr(object: Any, context: set[int], level: int) str
-_safe_repr(object: Any, context: set[int], maxlevels: int | None, level: int) str
-_pprint_dict(...)
-_pprint_list(...)
-_pprint_tuple(...)
-_pprint_set(...)
-_pprint_str(...)
-_pprint_bytes(...)
-_pprint_bytearray(...)
-_pprint_default_dict(...)
-_pprint_counter(...)
-_pprint_ordered_dict(...)
-_pprint_mappingproxy(...)
-_pprint_simplenamespace(...)
-_pprint_chain_map(...)
-_pprint_deque(...)
-_pprint_user_dict(...)
-_pprint_user_list(...)
-_pprint_user_string(...)
-_format_dict_items(...)
-_format_namespace_items(...)
-_format_items(...)
}
class _safe_key {
-obj: Any
+__init__(obj: Any)
+__lt__(other: _safe_key) bool
}
PrettyPrinter --> "_safe_key" : uses for sorting
PrettyPrinter ..> "collections.*" : formats various types
PrettyPrinter ..> "dataclasses.*" : formats dataclasses
PrettyPrinter ..> "types.*" : formats special types
Summary
The `pprint.py` module is a robust and extensible pretty-printing utility for Python. It supports a wide variety of built-in and user-defined types, detects recursion to prevent infinite loops, and provides nicely formatted, readable string representations of complex nested data structures.
Its design centers around the `PrettyPrinter` class, which can be configured for indentation, line width, and depth, and uses a dispatch mechanism to handle different data types gracefully.
This module is a foundational tool for debugging and presenting data clearly in Python applications.