Claude Code for reprlib: Python Abbreviated Object Representations — Claude Skills 360 Blog
Blog / AI / Claude Code for reprlib: Python Abbreviated Object Representations
AI

Claude Code for reprlib: Python Abbreviated Object Representations

Published: August 21, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s reprlib module provides size-limited repr() strings and protection against infinite recursion. import reprlib. reprlib.repr: reprlib.repr(obj) → abbreviated string; long containers are truncated with .... Repr class: r = reprlib.Repr() — configure per-type limits; r.repr(obj). Limits: maxstring=30, maxlist=6, maxdict=4, maxset=6, maxfrozenset=6, maxdeque=6, maxarray=5, maxlong=40, maxother=30, maxlevel=6 (recursion depth). Custom type: subclass Repr and define repr_typename(self, obj, level) -> str. repr1: r.repr1(obj, level) — single dispatch step used internally. recursive_repr: @reprlib.recursive_repr(fillvalue="...") decorator — returns fillvalue instead of recursing when __repr__ is called on an already-active object (prevents RecursionError in linked lists and circular refs). aRepr: reprlib.aRepr — module-level Repr singleton used by reprlib.repr(). Claude Code generates safe debug loggers, structured log formatters, REPL display helpers, and circular-reference-safe repr methods.

CLAUDE.md for reprlib

## reprlib Stack
- Stdlib: import reprlib
- Quick:  reprlib.repr(big_obj)          # auto-abbreviated, safe
- Config: r = reprlib.Repr(); r.maxlist = 3; r.repr(obj)
- Safe:   @reprlib.recursive_repr()      # guards __repr__ from recursion
- Log:    logger.debug("state=%s", reprlib.repr(state))

reprlib Safe Repr Pipeline

# app/reprutil.py — abbreviated repr, custom Repr, safe logging, circular-safe
from __future__ import annotations

import reprlib
import logging
from dataclasses import dataclass, fields
from typing import Any


# ─────────────────────────────────────────────────────────────────────────────
# 1. Quick-use abbreviation helpers
# ─────────────────────────────────────────────────────────────────────────────

def short_repr(obj: Any, max_len: int = 60) -> str:
    """
    Return an abbreviated repr of obj, truncated to max_len characters.

    Example:
        short_repr(list(range(1000)))   # "[0, 1, 2, 3, 4, 5, ...]"
        short_repr("a" * 200)           # "'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...'"
    """
    r = reprlib.repr(obj)
    if len(r) > max_len:
        return r[:max_len - 3] + "..."
    return r


def safe_repr(obj: Any) -> str:
    """
    Return reprlib.repr(obj), falling back to type-name on any exception.

    Example:
        safe_repr(object_with_broken_repr)  # "<BrokenClass instance>"
    """
    try:
        return reprlib.repr(obj)
    except Exception as exc:
        return f"<{type(obj).__name__} repr-error: {exc}>"


def type_and_repr(obj: Any) -> str:
    """
    Return 'TypeName: <abbreviated repr>' for use in debug logs.

    Example:
        type_and_repr([1, 2, 3])    # "list: [1, 2, 3]"
        type_and_repr({"a": 1})     # "dict: {'a': 1}"
    """
    return f"{type(obj).__name__}: {safe_repr(obj)}"


def repr_kwargs(**kwargs: Any) -> str:
    """
    Format keyword args as 'key=short_repr(val), ...' for log messages.

    Example:
        repr_kwargs(data=[1]*100, name="Alice")
        # "data=[0, 1, 2, 3, 4, 5, ...], name='Alice'"
    """
    return ", ".join(f"{k}={safe_repr(v)}" for k, v in kwargs.items())


# ─────────────────────────────────────────────────────────────────────────────
# 2. Configurable Repr instances
# ─────────────────────────────────────────────────────────────────────────────

def make_repr(
    maxlist: int = 6,
    maxdict: int = 4,
    maxstring: int = 40,
    maxset: int = 6,
    maxlevel: int = 4,
    maxother: int = 50,
) -> reprlib.Repr:
    """
    Build a configured Repr instance.

    Example:
        r = make_repr(maxlist=3, maxstring=20)
        r.repr([1, 2, 3, 4, 5])   # '[1, 2, 3, ...]'
    """
    r = reprlib.Repr()
    r.maxlist    = maxlist
    r.maxdict    = maxdict
    r.maxstring  = maxstring
    r.maxset     = maxset
    r.maxfrozenset = maxset
    r.maxlevel   = maxlevel
    r.maxother   = maxother
    return r


# Preconfigured instances for common use cases
COMPACT_REPR = make_repr(maxlist=3, maxdict=2, maxstring=20, maxlevel=2)
VERBOSE_REPR = make_repr(maxlist=20, maxdict=10, maxstring=120, maxlevel=8)
LOG_REPR     = make_repr(maxlist=5, maxdict=3, maxstring=60, maxlevel=3)


# ─────────────────────────────────────────────────────────────────────────────
# 3. Recursive-repr guard for custom classes
# ─────────────────────────────────────────────────────────────────────────────

class Node:
    """
    A linked-list node that uses @recursive_repr to handle circular references.

    Example:
        a = Node(1)
        b = Node(2)
        a.next = b
        b.next = a   # circular!
        repr(a)      # "Node(1, next=Node(2, next=...))"  — no RecursionError
    """

    def __init__(self, value: Any, next_node: "Node | None" = None) -> None:
        self.value = value
        self.next = next_node

    @reprlib.recursive_repr(fillvalue="...")
    def __repr__(self) -> str:
        if self.next is None:
            return f"Node({self.value!r})"
        return f"Node({self.value!r}, next={self.next!r})"


class CircularList:
    """
    A list-like container that uses @recursive_repr to stay safe.

    Example:
        cl = CircularList([1, 2, 3])
        cl.items.append(cl)   # self-reference
        repr(cl)              # "CircularList([1, 2, 3, ...])"
    """

    def __init__(self, items: list[Any] | None = None) -> None:
        self.items: list[Any] = list(items or [])

    @reprlib.recursive_repr(fillvalue="CircularList(...)")
    def __repr__(self) -> str:
        inner = reprlib.repr(self.items)
        return f"CircularList({inner})"


# ─────────────────────────────────────────────────────────────────────────────
# 4. Safe logging helpers
# ─────────────────────────────────────────────────────────────────────────────

class SafeReprLogger:
    """
    A logger wrapper that abbreviates all positional log arguments with reprlib.

    Example:
        logger = SafeReprLogger("myapp")
        logger.debug("Processing: %s", large_object)
        # large_object is passed through LOG_REPR before formatting
    """

    def __init__(self, name: str, repr_instance: reprlib.Repr | None = None) -> None:
        self._log = logging.getLogger(name)
        self._repr = repr_instance or LOG_REPR

    def _safe_args(self, args: tuple[Any, ...]) -> tuple[str, ...]:
        return tuple(self._repr.repr(a) if not isinstance(a, str) else a for a in args)

    def debug(self, msg: str, *args: Any) -> None:
        if self._log.isEnabledFor(logging.DEBUG):
            self._log.debug(msg, *self._safe_args(args))

    def info(self, msg: str, *args: Any) -> None:
        self._log.info(msg, *self._safe_args(args))

    def warning(self, msg: str, *args: Any) -> None:
        self._log.warning(msg, *self._safe_args(args))

    def error(self, msg: str, *args: Any) -> None:
        self._log.error(msg, *self._safe_args(args))


# ─────────────────────────────────────────────────────────────────────────────
# 5. Dataclass and dict summary helpers
# ─────────────────────────────────────────────────────────────────────────────

def dataclass_repr(obj: Any, r: reprlib.Repr | None = None) -> str:
    """
    Generate an abbreviated repr for a dataclass instance.
    Uses LOG_REPR by default to abbreviate large field values.

    Example:
        @dataclass
        class Job:
            name: str
            data: list[int]

        job = Job("process", list(range(1000)))
        dataclass_repr(job)  # "Job(name='process', data=[0, 1, 2, 3, 4, 5, ...])"
    """
    representer = r or LOG_REPR
    try:
        fs = fields(obj)  # type: ignore[arg-type]
    except TypeError:
        return repr(obj)
    parts = ", ".join(f"{f.name}={representer.repr(getattr(obj, f.name))}" for f in fs)
    return f"{type(obj).__name__}({parts})"


def summarize_dict(d: dict[str, Any], max_keys: int = 8, r: reprlib.Repr | None = None) -> str:
    """
    Summarize a dict, showing up to max_keys entries with abbreviated values.

    Example:
        summarize_dict({"a": list(range(100)), "b": "hello " * 50}, max_keys=3)
    """
    representer = r or LOG_REPR
    keys = list(d)[:max_keys]
    truncated = len(d) > max_keys
    parts = [f"{k!r}: {representer.repr(d[k])}" for k in keys]
    if truncated:
        parts.append(f"... ({len(d) - max_keys} more)")
    return "{" + ", ".join(parts) + "}"


def format_call(fn_name: str, *args: Any, **kwargs: Any) -> str:
    """
    Format a function call signature with abbreviated arguments for logging.

    Example:
        format_call("process_data", [1]*1000, limit=50, mode="fast")
        # "process_data([0, 1, 2, 3, 4, 5, ...], limit=50, mode='fast')"
    """
    r = LOG_REPR
    arg_parts = [r.repr(a) for a in args]
    kwarg_parts = [f"{k}={r.repr(v)}" for k, v in kwargs.items()]
    return f"{fn_name}({', '.join(arg_parts + kwarg_parts)})"


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    import dataclasses

    print("=== reprlib demo ===")

    print("\n--- reprlib.repr on large objects ---")
    print(f"  list(range(100)):  {reprlib.repr(list(range(100)))}")
    print(f"  set(range(20)):    {reprlib.repr(set(range(20)))}")
    d100 = {i: chr(65 + i % 26) for i in range(100)}
    print(f"  dict(100 items):   {reprlib.repr(d100)}")
    print(f"  long string:       {reprlib.repr('x' * 200)}")

    print("\n--- short_repr / safe_repr ---")
    print(f"  short_repr(list(range(1000))):  {short_repr(list(range(1000)))}")
    print(f"  type_and_repr({{1: 'a', 2: 'b'}}): {type_and_repr({1: 'a', 2: 'b'})}")

    print("\n--- configured Repr ---")
    r_compact = make_repr(maxlist=2, maxdict=2, maxstring=15)
    print(f"  compact list(range(10)): {r_compact.repr(list(range(10)))}")
    print(f"  verbose list(range(10)): {VERBOSE_REPR.repr(list(range(10)))}")

    print("\n--- recursive_repr on Node ---")
    a = Node(1)
    b = Node(2)
    c = Node(3)
    a.next = b
    b.next = c
    c.next = a   # circular!
    print(f"  circular node list: {a!r}")

    print("\n--- CircularList ---")
    cl = CircularList([10, 20, 30])
    cl.items.append(cl)   # self-reference
    print(f"  self-referencing list: {cl!r}")

    print("\n--- repr_kwargs ---")
    big_data = {"records": list(range(500)), "errors": []}
    print(f"  {repr_kwargs(data=big_data, limit=10, mode='strict')}")

    print("\n--- dataclass_repr ---")
    @dataclasses.dataclass
    class Job:
        name: str
        payload: list[int]
        tags: set[str]

    job = Job("compress", list(range(1000)), {"urgent", "batch", "retry", "nightly"})
    print(f"  {dataclass_repr(job)}")

    print("\n--- summarize_dict ---")
    big = {f"key_{i}": list(range(i * 10)) for i in range(20)}
    print(f"  {summarize_dict(big, max_keys=3)}")

    print("\n--- format_call ---")
    print(f"  {format_call('process', list(range(500)), limit=50, mode='fast')}")

    print("\n=== done ===")

For the pprint alternative — pprint.pformat() produces fully expanded, indented representations of Python objects without truncation, making it ideal for human inspection of small-to-medium structures; reprlib deliberately truncates to prevent log floods and RecursionError in circular structures — use pprint when you want to see the complete structure in development and debugging; use reprlib in production logging, __repr__ methods for data containers, and anywhere that giant objects could swamp log files or cause runaway recursion. For the rich alternative — rich (PyPI) renders syntax-highlighted, colored, and paginated repr output in the terminal with rich.inspect() and rich.pretty.pprint(); it also provides progress bars, tables, and panels; reprlib is stdlib-only with zero dependencies and focuses on safe size-limited strings — use rich for interactive development, REPL sessions, and CLI tools where colorized output adds value; use reprlib for production code where you need dependency-free abbreviation in log statements and __repr__ methods. The Claude Skills 360 bundle includes reprlib skill sets covering short_repr()/safe_repr()/type_and_repr()/repr_kwargs() quick helpers, make_repr()/COMPACT_REPR/LOG_REPR/VERBOSE_REPR configured instances, Node and CircularList classes with @recursive_repr guard, SafeReprLogger wrapper for abbreviating log arguments, and dataclass_repr()/summarize_dict()/format_call() structured summary tools. Start with the free tier to try safe repr patterns and reprlib pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free