The best and most accurate way to think of pass is as a way to explicitly tell the interpreter to do nothing. In the same way the following code:
def foo(x,y): return x+y
means "if I call the function foo(x, y), sum the two numbers the labels x and y represent and hand back the result",
def bar(): pass
means "If I call the function bar(), do absolutely nothing."
The other answers are quite correct, but it's also useful for a few things that don't involve place-holding.
For example, in a bit of code I worked on just recently, it was necessary to divide two variables, and it was possible for the divisor to be zero.
c = a / b
will, obviously, produce a ZeroDivisionError if b is zero. In this particular situation, leaving c as zero was the desired behavior in the case that b was zero, so I used the following code:
try: c = a / b except ZeroDivisionError: pass
Another, less standard usage is as a handy place to put a breakpoint for your debugger. For example, I wanted a bit of code to break into the debugger on the 20th iteration of a for... in statement. So:
for t in range(25): do_a_thing(t) if t == 20: pass
with the breakpoint on pass.
passwould be useful when you want to override a method in a subclass to do nothing.passin theexceptblock comes in very handy.