How textwrap.dedent Strips Whitespace in Python

Python's textwrap.dedent() function provides a clean, automated way to remove unwanted leading indentation from multiline strings, such as docstrings or embedded templates. This article explains the internal mechanics of textwrap.dedent(), how it identifies the common indentation level across lines, and how it strips that uniform whitespace while maintaining relative formatting.

The Multiline Indentation Problem

When defining multiline strings inside indented blocks such as functions, classes, or conditional statements, the string typically inherits the indentation of the surrounding code:

def generate_message():
    message = """
        Hello, World!
        This is an indented string.
            This line has extra indentation.
    """
    return message

Printing message directly preserves all the leading spaces on each line, which often breaks formatting requirements for terminal output, emails, or generated files.

How textwrap.dedent() Works

The textwrap.dedent() function standardizes this behavior by locating and stripping the shared "margin" from the multiline text. The process follows three distinct steps:

  1. Splits the String into Lines: The function processes the string line by line.
  2. Calculates the Minimum Common Prefix: It examines all non-empty lines (lines containing at least one non-whitespace character) to find the longest sequence of leading whitespace characters shared by every line. Lines consisting entirely of whitespace are ignored during this calculation to prevent a blank line from resetting the common indentation to zero.
  3. Removes the Common Prefix: It removes that exact character sequence from the start of every line in the string. Any extra indentation beyond that common prefix remains untouched.

Example

import textwrap

sample = """
    First line.
    Second line.
        Nested line.
"""

cleaned = textwrap.dedent(sample)
print(repr(cleaned))

Output:

'\nFirst line.\nSecond line.\n    Nested line.\n'

In this example, the minimum common indentation was four spaces. The function stripped four spaces from each line, leaving First line. and Second line. flush to the left, while Nested line. preserved its two relative levels of indentation (four remaining spaces).

Important Nuances

Character-Level Matching (Tabs vs. Spaces)

textwrap.dedent() treats tabs and spaces as distinct characters. It does not expand tabs into spaces before calculating the common prefix. If some lines use four spaces and others use a single tab character, dedent() will only remove the whitespace prefix that strictly matches character-for-character across all lines. To prevent unexpected results, ensure consistent indentation or call str.expandtabs() before dedenting.

The First Line Trap

A common pitfall occurs when placing text immediately after the opening triple quotes:

sample = """First line.
    Second line.
    Third line."""

Because the first line has zero leading spaces, the common whitespace prefix across all lines is an empty string. As a result, dedent() will not remove any indentation from the subsequent lines. To ensure proper dedenting, start multiline strings with a newline right after the opening quotes.