The % inside the string only comes into play once Python has established you're using the % printf-like operator outside the string.
In the first case, you're not, so it doesn't complain. All you're doing in that case is printing a string.
The second case, you are using the % operator so it complains that you haven't provided enough arguments. In that case, you're formatting a string before printing it.
print itself knows nothing of the string formatting functions, it simply prints what you give it. In the string formatting case, something like "Hello, %s"%("Pax") is processed by the % operator to give you "Hello, Pax" and then that is given to print for output:
print "Hello, %s"%("Pax") # ^ \_________________/ <- This bit done first # | # Then the print is done
So basically, it's the % operator that decides you're doing printf-style processing, not the fact you have a string containing the % character. That's confirmed by the fact that:
print "%r %r %r %r %r"
also has no issue with argument count mismatch, printing out the literal %r %r %r %r %r.
print "%r %r"also works no problem