The reprlib module creates size-limited string representations of objects. Essential when debugging code with large data structures that would otherwise flood your output.

Basic Usage

import reprlib
 
# Large list
big_list = list(range(1000))
 
# Standard repr (all 1000 items!)
print(repr(big_list))
# [0, 1, 2, 3, 4, ...(truncated manually)
 
# reprlib.repr (truncated automatically)
print(reprlib.repr(big_list))
# [0, 1, 2, 3, 4, 5, ...] 

Truncation Examples

import reprlib
 
# Long string
text = "a" * 100
print(reprlib.repr(text))
# 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...'
 
# Deep nesting
nested = [[[[1, 2, 3]]]]
print(reprlib.repr(nested))
# [[[[1, 2, 3]]]]
 
# Large dict
big_dict = {i: i*2 for i in range(100)}
print(reprlib.repr(big_dict))
# {0: 0, 1: 2, 2: 4, 3: 6, ...}
 
# Large set
big_set = set(range(100))
print(reprlib.repr(big_set))
# {0, 1, 2, 3, 4, 5, ...}

Custom Repr Object

Configure your own limits:

import reprlib
 
# Create custom repr with larger limits
r = reprlib.Repr()
r.maxlist = 10      # Show 10 list items
r.maxstring = 50    # Show 50 chars for strings
r.maxdict = 5       # Show 5 dict entries
r.maxset = 8        # Show 8 set members
r.maxother = 40     # Other objects
 
big_list = list(range(100))
print(r.repr(big_list))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]

All Configuration Options

import reprlib
 
r = reprlib.Repr()
 
# Limits for specific types
r.maxlevel = 6      # Max recursion depth
r.maxtuple = 6      # Max tuple items
r.maxlist = 6       # Max list items
r.maxarray = 5      # Max array.array items
r.maxdict = 4       # Max dict items
r.maxset = 6        # Max set items
r.maxfrozenset = 6  # Max frozenset items
r.maxdeque = 6      # Max deque items
r.maxstring = 30    # Max string length
r.maxlong = 40      # Max int digits
r.maxother = 30     # Max for other types

Custom Object Representation

import reprlib
 
class DataStore:
    def __init__(self, items):
        self.items = items
    
    def __repr__(self):
        return f"DataStore({reprlib.repr(self.items)})"
 
store = DataStore(list(range(1000)))
print(store)
# DataStore([0, 1, 2, 3, 4, 5, ...])

@reprlib.recursive_repr Decorator

Handle self-referential structures:

import reprlib
 
class Node:
    def __init__(self, value):
        self.value = value
        self.children = []
    
    @reprlib.recursive_repr()
    def __repr__(self):
        return f"Node({self.value}, children={self.children})"
 
# Create circular reference
node = Node(1)
node.children.append(node)
 
print(node)
# Node(1, children=[...])  # Handles recursion safely!

Custom Repr for Type

import reprlib
 
class MyRepr(reprlib.Repr):
    def repr_DataFrame(self, obj, level):
        """Custom repr for pandas DataFrame."""
        return f"DataFrame({obj.shape[0]}x{obj.shape[1]})"
    
    def repr_ndarray(self, obj, level):
        """Custom repr for numpy array."""
        return f"ndarray(shape={obj.shape}, dtype={obj.dtype})"
 
r = MyRepr()
 
# Usage with pandas/numpy
# df = pd.DataFrame(...)
# print(r.repr(df))  # DataFrame(1000x50)

Debugging Integration

import reprlib
import logging
 
class TruncatedFormatter(logging.Formatter):
    """Formatter that truncates large data structures."""
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.repr = reprlib.Repr()
        self.repr.maxstring = 100
        self.repr.maxlist = 10
    
    def format(self, record):
        # Truncate any large objects in args
        if record.args:
            record.args = tuple(
                self.repr.repr(arg) if not isinstance(arg, str) else arg
                for arg in record.args
            )
        return super().format(record)
 
# Setup
handler = logging.StreamHandler()
handler.setFormatter(TruncatedFormatter('%(message)s'))
logger = logging.getLogger()
logger.addHandler(handler)

Error Messages

import reprlib
 
def process_items(items):
    if not items:
        raise ValueError(
            f"Expected items, got: {reprlib.repr(items)}"
        )
    
    if len(items) > 1000:
        raise ValueError(
            f"Too many items ({len(items)}): {reprlib.repr(items)}"
        )
 
# Clean error messages even with large data
try:
    process_items(list(range(10000)))
except ValueError as e:
    print(e)
# Too many items (10000): [0, 1, 2, 3, 4, 5, ...]

Comparison with pprint

import reprlib
from pprint import pformat
 
data = {'key': list(range(100))}
 
# reprlib: Single line, truncated
print(reprlib.repr(data))
# {'key': [0, 1, 2, 3, 4, 5, ...]}
 
# pprint: Multi-line, formatted but not truncated
print(pformat(data, width=40))
# {'key': [0,
#          1,
#          2,
#          ...all 100 items...

aRepr for Async-Safe Repr

import reprlib
 
# Thread-safe singleton
print(reprlib.aRepr.repr([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
# [1, 2, 3, 4, 5, 6, ...]
 
# Modify global defaults
reprlib.aRepr.maxlist = 20

Practical Patterns

Safe repr

import reprlib
 
class APIResponse:
    def __init__(self, data):
        self.data = data
    
    def __repr__(self):
        # Never overflow console with response data
        return f"APIResponse(data={reprlib.repr(self.data)})"

Test Assertions

import reprlib
 
def assert_contains(container, item):
    if item not in container:
        raise AssertionError(
            f"{reprlib.repr(item)} not found in {reprlib.repr(container)}"
        )
 
# Clear failure messages even with huge containers
assert_contains(range(1000000), -1)

Interactive Debugger

import reprlib
 
class DebugHelper:
    """Helper for debugging with large objects."""
    
    def __init__(self, maxitems=10):
        self.r = reprlib.Repr()
        self.r.maxlist = maxitems
        self.r.maxdict = maxitems
    
    def show(self, obj, label=None):
        prefix = f"{label}: " if label else ""
        print(f"{prefix}{self.r.repr(obj)}")
 
debug = DebugHelper(maxitems=5)
debug.show(list(range(100)), "my_list")
# my_list: [0, 1, 2, 3, 4, ...]

When to Use reprlib

ScenarioTool
Logging large objectsreprlib.repr()
Error messagesreprlib.repr()
repr for containersreprlib.repr()
Pretty debugging outputpprint
Full serializationjson or repr()

The reprlib module keeps your debug output readable by automatically truncating large structures. Use it wherever repr() might produce overwhelming output.

React to this post: