IndentationError: expected an indented block
1 · The lesson
readWhat this error means
Python opened a block with : (after if, for, def, class, while, try, else, with, etc.) but found no indented lines underneath it. Every header line that ends with a colon needs at least one statement in its body. Python does not allow empty blocks, unlike languages where you can write {}.
When you see it
>>> def greet(name): ... File "<stdin>", line 2 ^ IndentationError: expected an indented block after function definition on line 1
>>> if x > 0: ... print(x) File "<stdin>", line 2 print(x) ^ IndentationError: expected an indented block after 'if' statement on line 1
Why it happens
You wrote a header line and then either left it empty, forgot to indent the body, or deleted the body while refactoring and forgot to add a placeholder. It also happens when you copy and paste code, and the indentation is removed or replaced by characters that Python doesn't recognise as indentation.
How to fix it
1. Add a real body:
def greet(name): print("Hello,", name)
2. Use pass as a no-op placeholder:
def todo(): pass if x > 0: pass # implement later
setup added so this can run · defines x
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) x = _AutoMock('x')
pass is a statement that does nothing. It is useful as a placeholder for code you will write later.
3. Use a docstring. A string on its own line counts as a statement:
def greet(name): """Greet the user by name. Implementation pending."""
This is common in abstract methods, scaffolding, and placeholder classes:
class UserRepository: """Stores and retrieves users.""" def find(self, user_id): """Return the user with the given id, or None."""
4. Use ... (Ellipsis). Three dots on their own line are also a valid statement:
def not_yet_implemented(): ...
This is the usual style in type stubs and abstract method bodies.
When you'd see this in real code
- Writing the outline of a class with several methods you plan to complete later: every method needs
pass,...or a docstring. - Commenting out the only line inside an
ifblock while debugging: the block becomes empty. Comments are not statements, so you still needpass. - Pasting code into a notebook or REPL, where the indentation of the lines was lost.
Related errors
See Also
- All Python errors: the full index, by type and by when it happens.
- Python syntax cheat sheet
- Functions tutorial
Found this useful? Share it with a friend who’s learning Python.