← Debugging Guides

阅读中文版本

Python TabError — Inconsistent Use of Tabs and Spaces

Fix TabError inconsistent use of tabs and spaces by normalizing one file to spaces and configuring your editor to never emit tabs.

beginnerdebuggingpythonsyntaxtabs

Symptoms

  • Python raises "TabError: inconsistent use of tabs and spaces in indentation"
  • The file runs on one machine but errors on another
  • Errors cluster around code copied from a different editor

Possible causes

  • Some lines use tabs and others use spaces for the same indentation level
  • Editor tabstop differs from Python tab expansion (8 columns)
  • A patch or merge introduced one style into a file that used the other

Diagnosis steps

Detect tabs in the file

grep -nP "\t" app.py | head

Interpretation

Any hit inside indentation indicates mixed styles; Python 3 refuses to guess.

Expand tabs and recompile

expand -t 4 app.py > app_fixed.py && python -m py_compile app_fixed.py

Interpretation

Expanding to the intended width then compiling confirms the fix before you commit.

Root cause

Python 3 rejects mixing tabs and spaces within the same block because the two have no unambiguous common width. TabError is raised during tokenization as soon as inconsistent indentation is detected.

Fix

Convert the whole file to spaces with expand or a formatter, then add an .editorconfig with indent_style = space and a pre-commit hook that rejects tabs.

Risk note

Converting tabs to spaces changes byte offsets; avoid doing it in the same commit as functional changes to keep diffs reviewable.

Verify the fix

Recompile and run; grep for tabs returns nothing. Run the same file on a second OS to confirm portability.

Symptoms

This debugging guide addresses “Python TabError — Inconsistent Use of Tabs and Spaces”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.

Observed symptoms include:

  • Python raises “TabError: inconsistent use of tabs and spaces in indentation”
  • The file runs on one machine but errors on another
  • Errors cluster around code copied from a different editor

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: Detect tabs in the file

grep -nP "\t" app.py | head

Any hit inside indentation indicates mixed styles; Python 3 refuses to guess.

Step 2: Expand tabs and recompile

expand -t 4 app.py > app_fixed.py && python -m py_compile app_fixed.py

Expanding to the intended width then compiling confirms the fix before you commit.

Likely contributors, in order of frequency:

  • Some lines use tabs and others use spaces for the same indentation level
  • Editor tabstop differs from Python tab expansion (8 columns)
  • A patch or merge introduced one style into a file that used the other

Root Cause

Python 3 rejects mixing tabs and spaces within the same block because the two have no unambiguous common width. TabError is raised during tokenization as soon as inconsistent indentation is detected.

The Fix

Convert the whole file to spaces with expand or a formatter, then add an .editorconfig with indent_style = space and a pre-commit hook that rejects tabs.

Watch out: Converting tabs to spaces changes byte offsets; avoid doing it in the same commit as functional changes to keep diffs reviewable.

def process(rows):
    out = []
    for row in rows:
        out.append(row.strip())
    return out

# One tab-indented line among space-indented lines -> TabError
def broken(rows):
    out = []
    for row in rows:
	    out.append(row)  # tab here
    return out

Verify and Prevent

Recompile and run; grep for tabs returns nothing. Run the same file on a second OS to confirm portability.

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.