VMware ESXi and vSphere Cluster Management
Python pass Statement: Placeholder Blocks and the Difference from continue
Learn how Python's pass statement works, why empty blocks need it, and how pass differs from continue and break in loops.
The Python pass statement is a null operation: when Python executes it, nothing happens. It does not assign a value, print output, change a variable, move a loop forward, or alter program flow by itself.
Its main purpose is to provide a valid statement where Python requires an indented block, even when you intentionally have no behavior to add yet.
What pass does
Python uses indentation to define a block, also called a suite. A suite is the indented group of statements belonging to constructs such as if, for, def, class, try, or with.
Every such construct needs at least one statement in its body. pass supplies that statement without performing an operation.
if True:
pass
This code is valid. The condition is true, Python enters the indented block, executes pass, and then continues after the block.
By contrast, an empty block is not valid Python:
if True:
# There is no statement here
Depending on the exact whitespace and surrounding code, Python reports a syntax- or indentation-related error because the if statement has no body. Add a real statement when the branch needs behavior, or add pass when the empty branch is intentional.
Basic pass syntax
pass is written on its own line inside an indented block:
if condition:
pass
It can also be used in different conditional branches:
if status == "ready":
print("Start")
elif status == "paused":
pass
else:
print("Unknown status")
Here, the paused branch deliberately has no action. The pass statement makes the branch valid, and execution continues after the entire conditional statement.
pass may appear wherever an ordinary statement is allowed. It is most useful in a block that temporarily needs no behavior or represents an intentionally empty case.
Where pass can be used
The surrounding compound statement requires a body because Python's syntax associates the indented suite with that statement. The typical placeholder purpose differs, but the role of pass is the same: satisfy the syntax without adding behavior.
pass in a conditional inside a loop
Consider a for loop over the numbers 1 through 10. Python's range(1, 11) produces 1 through 10 because the ending value, 11, is excluded.
for number in range(1, 11):
if number == 5:
pass
print("The number is 5")
print(number)
Expected output:
1
2
3
4
The number is 5
5
6
7
8
9
10
When number is 5, Python enters the if block and executes pass. It then continues to the next statement in that same block, so The number is 5 is printed. After leaving the conditional block, the loop prints 5 as well.
This demonstrates two important facts:
passdoes not skip the remaining statements in the currentifblock.passdoes not skip the current loop iteration or move directly to the next number.
pass versus continue
continue is a loop-control statement. When Python executes it, the current iteration ends immediately, and the loop begins its next iteration.
Replacing pass with continue changes the result:
for number in range(1, 11):
if number == 5:
continue
print("The number is 5")
print(number)
In this version, when number is 5, continue skips the rest of that iteration. Therefore neither the special message nor the final print(number) runs for 5.
1
2
3
4
6
7
8
9
10
The two statements can look similar when a branch has no desired action, but they are not substitutes in general. Use pass when the branch should do nothing and then continue normally. Use continue when the rest of the current loop iteration must be skipped.
Counting lowercase l characters in Hello world!
This example iterates over every character in the string Hello world!. The counter starts at zero. When the current character is a lowercase l, the branch contains pass before the counter update and match-specific message.
text = "Hello world!"
count = 0
for character in text:
if character == "l":
pass
count += 1
print("Found a lowercase l")
print(character)
print("Total:", count)
Relevant output is:
H
e
l
Found a lowercase l
l
Found a lowercase l
o
w
o
r
l
Found a lowercase l
d
!
Total: 3
The string contains three lowercase l characters. On each match, pass does nothing and execution continues to count += 1 and the message. The character is also printed by the statement after the conditional.
If you put continue at the same location, the statements below it in the current iteration would be skipped:
for character in text:
if character == "l":
continue
count += 1
print("Found a lowercase l")
print(character)
In this arrangement, the counter would not increase for any lowercase l, and the per-match message would never print. The character print would also be skipped for each matching iteration. To use continue correctly, required updates must occur before it, or the logic must be reorganized.
Legitimate placeholder use cases
Function stubs
A stub is a temporary definition that reserves an interface for code planned later.
def load_settings(filename):
pass
This function can be parsed and imported, but it returns None when called because it has no return statement. A stub should not be mistaken for a finished implementation.
When callers must not use the function yet, an explicit error is often clearer:
def load_settings(filename):
raise NotImplementedError("Settings loading is not implemented yet")
During development, add a comment or TODO when that communicates the plan:
def load_settings(filename):
# TODO: read and validate the settings file
pass
Marker classes and custom exceptions
A class does not need additional methods or attributes to have a useful identity. An empty class can serve as a marker:
class ExperimentalFeature:
pass
It can also define a custom exception type:
class InvalidUserInput(Exception):
pass
The class name now gives code a specific exception type to catch or raise, even though the class body adds no custom behavior.
Temporarily unimplemented branches
if output_format == "json":
write_json(data)
elif output_format == "xml":
# TODO: add XML support
pass
else:
raise ValueError("Unsupported output format")
This is valid while XML support is being developed. Leaving a clear TODO reduces the chance that a silent placeholder will be forgotten.
Intentionally ignored exceptions
A narrow exception handler may use pass when failure is expected and has no useful consequence:
try:
os.remove("temporary-cache.txt")
except FileNotFoundError:
pass
Not finding an optional temporary file may be harmless. However, catch only the specific exception you understand. A broad handler such as except Exception: pass can hide programming errors, configuration problems, and data loss.
Empty loop bodies
An empty loop body can be made syntactically valid with pass:
for item in items:
pass
This is sometimes useful when merely consuming or waiting through an iterable is intentional, but it may be unclear to readers. A comment, a meaningful function call, or a clearer loop structure is often preferable.
pass and the ellipsis placeholder
The literal ... is called an ellipsis. It is another commonly used placeholder, especially in type stubs, protocol declarations, and incomplete APIs.
def parse_record(value: str) -> dict:
...
Both pass and ... can make a function body syntactically nonempty, but they communicate different intentions. pass explicitly says “perform no operation.” An ellipsis is commonly understood as “details are omitted” or “this declaration has no implementation here.” Choose the form that best communicates the code's purpose and conventions.
For production code, consider whether a real implementation, a return value, logging, or an explicit exception is more appropriate than a silent pass. Silent placeholders can make unfinished logic appear successful.
pass, continue, break, and loop else
break exits the nearest enclosing loop. continue skips to the next iteration. pass changes neither the loop nor the statements that follow it.
A loop can also have an else clause. The loop's else block runs when the loop finishes normally, without encountering break.
for number in range(1, 4):
if number == 5:
break
else:
print("The loop completed without break")
Because the loop reaches its natural end, the message is printed. Replacing the condition with one that calls break would prevent the loop else block from running. A pass statement inside the loop would not affect this rule.
Choosing the right statement
- Use
passwhen a required block intentionally has no operation. - Use
continuewhen the rest of the current loop iteration should not run. - Use
breakwhen the nearest loop should end immediately. - Use a real implementation when the path is required for correct behavior.
- Use
raise NotImplementedErrorwhen unfinished code must fail clearly rather than silently doing nothing. - Use logging or an explanatory comment when ignoring an expected condition needs to be visible to maintainers.
Troubleshooting pass-related mistakes
An empty block causes an error
Cause: A compound statement has no body statement.
Fix: Add the intended code, or add pass if the block is deliberately empty.
Code after pass still runs
Cause: pass is a no-operation, not a skip instruction.
Fix: Use continue to skip the rest of a loop iteration, break to exit a loop, or restructure the conditional logic.
A counter stops updating after continue is added
Cause: continue bypasses every statement below it in that iteration.
Fix: Move required updates before continue, or use an if/else structure that separates the cases clearly.
Errors disappear without explanation
Cause: A broad exception handler silently ignores failures.
Fix: Catch only expected exception types, and log, handle, or re-raise unexpected errors.
A placeholder remains in production code
Cause: pass allows unfinished logic to run silently.
Fix: Implement the behavior, add a tracked TODO during development, or raise NotImplementedError when the path must not be used.
Key points
passis a Python statement representing a null operation.- It is mainly used to satisfy Python's requirement that an indented block contain at least one statement.
- It does not change variables, output, loop position, or program flow by itself.
- Unlike
continue, it does not skip later statements in a loop iteration. - Unlike
break, it does not terminate a loop. - Use it deliberately, document unfinished work, and avoid hiding unexpected exceptions.
For a concise reference, return to the pass statement guide.