← Debugging Guides

阅读中文版本

Python IndentationError — Unexpected Indent

Resolve IndentationError unexpected indent by matching block indentation to the preceding colon and eliminating mixed tabs inside a single file.

beginnerdebuggingpythonsyntaxindentation

Symptoms

  • Python raises "IndentationError: unexpected indent" pointing at one line
  • The highlighted line looks aligned in the editor
  • The error appears after pasting code from another source

Possible causes

  • A line is indented although the previous line did not open a block
  • The file mixes tabs and spaces so visual alignment differs from logical indentation
  • An editor auto-indent inserted indentation after a comment or blank line

Diagnosis steps

Show whitespace and offending line

python -c "import sys; [print(i, repr(l)) for i,l in enumerate(open('app.py'),1) if l.startswith(' ')]" | head

Interpretation

repr output makes tabs visible as \t, exposing mixed indentation that looks aligned on screen.

Compile to locate the first bad line

python -m py_compile app.py

Interpretation

The reported line and caret pinpoint the first logical inconsistency; fix it and recompile.

Root cause

Python derives block structure from indentation alone. An unexpected indent is any indentation that does not follow a colon-terminated block opener, and inconsistent tabs/spaces make the parser see indentation that differs from what the editor renders.

Fix

Indent strictly with spaces (four per level), remove tabs from the file, and make sure every indented line belongs to a block opened by a colon on the previous logical line.

Risk note

Some editors silently convert tabs to spaces; configure a single indentation policy and add an editorconfig to enforce it.

Verify the fix

Recompile with python -m py_compile and run the module; the error should be gone. Add a lint step that rejects tabs so it cannot return.

Symptoms

When you hit “Python IndentationError — Unexpected Indent”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.

Observed symptoms include:

  • Python raises “IndentationError: unexpected indent” pointing at one line
  • The highlighted line looks aligned in the editor
  • The error appears after pasting code from another source

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Show whitespace and offending line

python -c "import sys; [print(i, repr(l)) for i,l in enumerate(open('app.py'),1) if l.startswith(' ')]" | head

repr output makes tabs visible as \t, exposing mixed indentation that looks aligned on screen.

Step 2: Compile to locate the first bad line

python -m py_compile app.py

The reported line and caret pinpoint the first logical inconsistency; fix it and recompile.

Likely contributors, in order of frequency:

  • A line is indented although the previous line did not open a block
  • The file mixes tabs and spaces so visual alignment differs from logical indentation
  • An editor auto-indent inserted indentation after a comment or blank line

Root Cause

Python derives block structure from indentation alone. An unexpected indent is any indentation that does not follow a colon-terminated block opener, and inconsistent tabs/spaces make the parser see indentation that differs from what the editor renders.

The Fix

Indent strictly with spaces (four per level), remove tabs from the file, and make sure every indented line belongs to a block opened by a colon on the previous logical line.

Watch out: Some editors silently convert tabs to spaces; configure a single indentation policy and add an editorconfig to enforce it.

def total(items):
    sum_ = 0
    for it in items:
        sum_ += it          # consistent 4-space indent
    return sum_

# Mixed tabs/spaces below triggers: IndentationError: unexpected indent
def bad(items):
    total_ = 0
	for it in items:        # tab instead of spaces
        total_ += it
    return total_

Verify and Prevent

Recompile with python -m py_compile and run the module; the error should be gone. Add a lint step that rejects tabs so it cannot return.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.