pass
Every def, class, if, loop and except needs an indented body. pass is a body that does nothing — execution just carries on to the next line.
empty function
def todo(): pass
empty class
class MyError(Exception): pass
empty branch
if ready: pass # TODO else: wait()
Use for
stub functions / classes, empty except, a branch you will fill later
Result
a statement — does nothing, has no value
Pairs with
def, class, if, except, ... (Ellipsis)
Watch out
pass is not continue: the code after it still runs
Demo
Live evaluation
Negative numbers hit the pass branch — which does nothing, so they are appended like every other number.
Try:
Inputs
numberslistcomma-separated
Code
out = [] for n in [3, -1, 4, -5]: if n < 0: pass out.append(n) out
Result
[3, -1, 4, -5]
pass has no behaviour of its own, so the demo shows the one question where it matters: what happens after it. With pass, the result is always the input list unchanged — the if branch exists but does nothing. Switch to the second tab and the same input loses its negatives, because continue skips the append. That difference is the whole reason to know which one you wrote.
Syntax slots
| Name | Type | Required | Description |
|---|---|---|---|
| (none) | statement | no | pass takes nothing. It is a complete statement and can appear anywhere a statement can. |
Common patterns
Custom exception class
The class body only needs to exist; everything is inherited. A docstring works as the body too.
class ConfigError(Exception): pass
Stub to fill in later
Lets the module import and run while the function is unwritten. It returns None.
def export_report(data): pass # TODO
Ignore one specific exception
Only for an error you really expect; contextlib.suppress says the same thing more explicitly.
import os def remove_if_exists(path): try: os.remove(path) except FileNotFoundError: pass
Ellipsis in type stubs and protocols
By convention ... marks "body intentionally left out" in .pyi stubs and abstract / Protocol methods.
from typing import Protocol class Closer(Protocol): def close(self) -> None: ...
Examples
1. A stub function returns None
def todo():
pass
print(todo())
Returns
None2. An empty class
class Empty:
pass
Empty.__name__
Returns
'Empty'3. Execution carries on after pass
for n in [1, 2]:
pass
print('after pass', n)
Returns
after pass 1
after pass 24. A body with nothing in it is an error
compile('def f():\n', '<demo>', 'exec')
Returns
IndentationError: expected an indented block after function definition on line 15. A comment is not a statement
compile('if True:\n # later\n', '<demo>', 'exec')
Returns
IndentationError: expected an indented block after 'if' statement on line 16. ... is the Ellipsis object
... is Ellipsis
Returns
True7. ... works as a body too
def later(): ...
print(later())
Returns
None8. pass is not an expression
compile('x = pass', '<demo>', 'exec')
Returns
SyntaxError: invalid syntaxPitfalls
1. pass where continue was meant
pass does not skip anything — the rest of the loop body still runs for that item.
pass
words = ['ok', '', 'fine'] out = [] for w in words: if not w: pass out.append(w.upper()) out
['OK', '', 'FINE']
continue
words = ['ok', '', 'fine'] out = [] for w in words: if not w: continue out.append(w.upper()) out
['OK', 'FINE']
2. except Exception: pass hides real bugs
Swallowing everything also swallows typos and wrong types. Catch only the exception you expect — then the real bug (an int passed in) surfaces instead of turning into None.
swallow everything
def parse(s): try: return int(s.strip()) except Exception: pass print(parse(42))
None
catch what you expect
def parse(s): try: return int(s.strip()) except ValueError: return None parse(42)
AttributeError: 'int' object has no attribute 'strip'
3. A forgotten pass stub that silently returns None
The program runs, but the stub returns None and the failure shows up far away. raise NotImplementedError fails at the call instead.
pass stub
def tax(amount): pass total = 100 + (tax(100) or 0) total
100
loud stub
def tax(amount): raise NotImplementedError('tax') tax(100)
NotImplementedError: tax
When to use
Use it
- Stub functions, classes and branches while sketching code
- Exception subclasses that need no body
- Ignoring one specific, expected exception
Reach for something else
- Skipping the rest of a loop pass → continue
- Placeholders that must not be forgotten → raise NotImplementedError
- Silencing broad exceptions → handle or log them
Notes
CPython impl
pass does no work: at most it compiles to a NOP that keeps its line visible to line tracing (debuggers, coverage)
Ellipsis
... is an expression (the Ellipsis constant) used as a statement; as a body it behaves like pass. Convention: pass in real code, ... in stubs and protocols
Docstring
A docstring alone is a valid body, so a documented function or class needs no pass
FAQ
Nothing. It is a statement you write where the syntax requires one — an empty function, class, if branch, loop or except block — so the code parses. Execution continues with the next line.