IndentationError
In Python the indentation is the block structure, so a wrong indent is a syntax error — raised at compile time, with TabError as the special case for tabs and spaces that only line up at some tab widths.
Demo
src = 'for i in range(3):\n' + ' ' * 4 + 'n += 1\n' + ' ' * 4 + 'n += 10\n' n = 0 exec(src) n
In Trigger, 4 / 4 gives 33 (line 3 runs three times inside the loop) and 4 / 0 gives 13 (once, after it) — same code, different meaning. 4 / 2 dedents to a column no enclosing block uses. In Handle, a tab and 8 spaces reach the same column, yet Python raises TabError: it also measures every line with a tab counted as 1 column, and the two measurements must agree about which lines line up.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| message | str | no | The error text (e.msg). |
| details | tuple | no | Same as SyntaxError: (filename, lineno, offset, text[, end_lineno, end_offset]). |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| msg | str | The message, e.g. "expected an indented block after 'if' statement on line 1" — note it names the statement and line that needed the block. |
| lineno | int | None | The line with the bad indentation (for a missing block, the line that should have been indented). |
| text | str | None | That source line. |
| offset / filename / end_lineno / end_offset | int | str | None | Inherited from SyntaxError. |
Common patterns
def not_ready_yet(): pass class Placeholder: """Filled in later."""
import textwrap snippet = ''' def f(): return 1 ''' exec(textwrap.dedent(snippet))
with open('legacy.py', encoding='utf-8') as f: fixed = f.read().expandtabs(4)
Examples
Pitfalls
src = 'def todo():\n # later\n' compile(src, 'app.py', 'exec')
src = 'def todo():\n # later\n pass\n' compile(src, 'app.py', 'exec') is not None
code = ''' def f(): return 1 ''' compile(code, 'app.py', 'exec')
import textwrap code = ''' def f(): return 1 ''' compile(textwrap.dedent(code), 'app.py', 'exec') is not None
src = 'def f():\n x = 1\n\treturn x' compile(src, 'app.py', 'exec')
src = 'def f():\n x = 1\n\treturn x' compile(src.expandtabs(4), 'app.py', 'exec') is not None
When to use
- Catching it (or SyntaxError) around compile()/exec() of generated or user-supplied code
- Raising it from a tool that parses an indentation-based format
- Catching it in your own module → it is compiled before any try runs; fix the file
- Fixing TabError line by line → convert the whole file to spaces
Notes
FAQ
The line after a statement ending in a colon (if, for, while, def, class, with, try, except, match …) must be indented deeper. The message names that statement and its line number. If the block is intentionally empty, write pass (or ...) — a comment alone is not a body.