Python The pass Statement

Use pass to keep an empty block valid, tell it apart from continue and break, and mark unfinished work clearly.

Lesson 17 of 107Beginner12 min read

pass is a statement that does nothing. Python needs it because every block, the indented code after a line ending in a colon, must contain at least one statement. When you want a block that has no work to do yet, pass fills the gap:

Python
def planned_report():
    pass            # function to be written later

class Tank:
    pass            # an empty class is still a valid class

This lesson shows where pass is useful, why it is not the same as continue, what a function containing only pass returns, and better alternatives for code that should not run silently, such as raising NotImplementedError. The examples come from an aquarium planning its feeding reports.

Empty blocks

Python uses indentation to define blocks, so an empty one would be indistinguishable from no block at all. Writing a colon and then nothing indented is a syntax error:

Text
    def planned_report():

    ^
IndentationError: expected an indented block after function definition on line 1

pass is the smallest valid statement, so it's used anywhere a block is required but there's nothing to do yet: a function you'll write later, a class you'll fill in, an if branch you haven't decided on, or a loop body while you test the loop header.

A docstring also counts as a statement, so a function or class containing only a docstring is valid without pass. The ellipsis literal ... is another common placeholder, especially in type stubs and abstract method definitions; like pass, it does nothing when executed.

Function results

A function whose body is just pass runs, does nothing, and returns None, because every Python function that ends without a return statement returns None:

Python
def feeding_count():
    pass

result = feeding_count()
print(result)          # None
print(result + 1)      # TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

That's the danger of placeholders. The program doesn't fail where the missing code is; it fails later, in whatever code used the None, which can make the bug hard to trace. A placeholder is fine during the first minutes of writing a program. Before anything else depends on the function, replace it with real code or make it fail loudly, as shown in the last section.

Loop behavior

pass doesn't affect the flow of a loop at all. The rest of the iteration still runs:

StatementEffect inside a loop
passNothing; carries on to the next line
continueSkips the rest of this iteration, moves to the next item
breakLeaves the loop completely
Python
for tank in ["reef", "river", "empty"]:
    if tank == "empty":
        pass              # no effect: the print below still runs
    print(tank)

All three names are printed. If the goal was to skip the empty tank, the statement needed is continue. Mixing these up is one of the most common beginner bugs, because the code runs without errors and only the output is wrong.

Explicit incompleteness

When unfinished code might actually be called, prefer to fail clearly instead of silently returning None. Raising NotImplementedError stops the program at the exact line that still needs work, with a message that explains why:

Python
def feeding_report(tank):
    raise NotImplementedError("feeding_report is not written yet")

The same exception is used in base classes to mark methods that subclasses must provide. The abc module enforces this even earlier with @abstractmethod, which prevents the class from being instantiated until the method exists.

Never combine pass with broad exception handling:

Python
try:
    update_feeding_log()
except Exception:
    pass                  # every error, including typos, disappears

This swallows every error without a trace. If an error really can be ignored, catch that specific exception and leave a comment or log message explaining why.

Independent practice and a worked check

Task: replace a feeding report placeholder with a function returning a real count. Start from def feeding_count(schedule): pass and return the number of feedings that are not marked as skipped.

Python
def feeding_count(schedule):
    """Return how many scheduled feedings will actually happen."""
    count = 0
    for tank, status in schedule:
        if status == "skip":
            continue
        count += 1
    return count

schedule = [("reef", "due"), ("river", "skip"), ("lagoon", "due")]
print(feeding_count(schedule))   # 2

Notice that skipping uses continue; replacing it with pass would count all three. For the worked check: does pass skip the rest of a loop iteration? No. It does nothing, so the following statements still run.

Reference and next practice

The language reference describes the pass statement and NotImplementedError. Revisit loops for break and continue, and error handling for raising exceptions. Practise with the Python exercises and Python quiz.

The pass Statement Summary

  • Empty blocks: pass performs no action but supplies the statement required by an otherwise empty block.
  • Function results: A function with no executed value return produces None.
  • Loop behavior: pass does not skip later work in a loop iteration.
  • Explicit incompleteness: NotImplementedError can expose a required behavior that has not been implemented.

The pass Statement Examples

Each example shows the code, the output it produces and what each part does.

Example 1

The pass Statement in a small program

Python
def planned_report():
    pass

print(planned_report())
for tank in ["reef", "river"]:
    pass
    print(tank)
Output
None
reef
river
Line-by-line explanation
  1. Lines 1 to 2A valid function whose body does nothing.
  2. Line 4Calling it returns None, which print() displays.
  3. Lines 6 to 7pass has no effect on the loop; print(tank) runs on every iteration.
Example 2

pass, continue and break side by side

Python
tanks = ["reef", "closed", "river", "drained", "lagoon"]

print("pass:")
for t in tanks:
    if t == "closed":
        pass
    print(" ", t)

print("continue:")
for t in tanks:
    if t == "closed":
        continue
    print(" ", t)

print("break:")
for t in tanks:
    if t == "drained":
        break
    print(" ", t)
Output
pass:
  reef
  closed
  river
  drained
  lagoon
continue:
  reef
  river
  drained
  lagoon
break:
  reef
  closed
  river
Line-by-line explanation
  1. Lines 5 to 6pass changes nothing, so "closed" is still printed.
  2. Lines 11 to 12continue skips only the "closed" iteration.
  3. Lines 17 to 18break stops the loop before "drained", so later tanks are never visited.

Common The pass Statement Mistakes

Using pass when you meant continue

Don't
for tank in tanks:
    if tank == "closed":
        pass               # does not skip
    schedule_feeding(tank)
Do
for tank in tanks:
    if tank == "closed":
        continue
    schedule_feeding(tank)

pass is a no-op; continue is what moves to the next item.

Leaving a placeholder that returns None

Don't
def daily_portions(fish_count):
    pass

total = daily_portions(12) * 3     # TypeError far from the cause
Do
def daily_portions(fish_count):
    raise NotImplementedError("portion rules not decided yet")

A loud failure at the placeholder is easier to fix than a TypeError somewhere else.

The pass Statement in Real Projects

Placeholders in real projects

Developers often sketch a program's structure first: function names, class names and the main loop, each with pass or ... as the body, then fill them in one at a time. Custom exception classes are often just class FeedingError(Exception): pass, because inheriting from Exception is all they need.

Linters help keep placeholders under control. Ruff and Pylint flag unnecessary pass statements and bare except: pass blocks, and many teams search for NotImplementedError and TODO before a release to make sure nothing unfinished ships.

The pass Statement FAQ

What does pass do in Python?

Nothing. It is a placeholder statement that satisfies Python's rule that every block must contain at least one statement. Execution simply moves on to the next line.

What is the difference between pass and continue?

pass does nothing and the rest of the loop body still runs. continue skips the rest of the current iteration and moves to the next item. Outside loops, continue is a SyntaxError, while pass is valid anywhere a statement is.

Should I use pass or ... as a placeholder?

Both do nothing when executed. pass is the traditional choice in normal code. ... (Ellipsis) is common in type stubs, protocols and abstract methods, where it reads as "body intentionally omitted". Pick one style per project.

Why do I get "expected an indented block"?

A line ending with a colon, such as if, for, def or class, must be followed by at least one indented statement. Add the real code, or pass as a temporary placeholder, indented under the header.

Is except: pass bad practice?

Usually, yes. It hides every error, including bugs you didn't anticipate, and leaves no record. Catch only the specific exception you expect and log or comment on why it is safe to ignore.

The pass Statement Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

Does pass skip the rest of a loop iteration?

Multiple choicemedium

Which review concern is valid for the pass statement?

The pass Statement Quiz

2 questions to check what you learned.

  1. Does pass skip the rest of a loop iteration?

    • Yes
    • No
    • Python ignores the distinction
  2. Which statement correctly describes loop behavior?

    • pass does not skip later work in a loop iteration.
    • Only the example output matters, not the rule
    • Every operation has the same behavior