Flow control¶
This page covers the statements that decide which code runs and how often: if, elif and else; while and for loops with their else clauses; break and continue; comparisons chained together; and, or and not; the one-line conditional expression; and assert. d/Python implements all of it. The compiler generates code tailored to each block, and the tests check evaluation order, short-circuiting and side effects against the reference CPython build (3.9.6) that every d/Python test is compared with.
Branches¶
for n in range(1, 16):
if n % 15 == 0:
print("FizzBuzz")
elif n % 3 == 0:
print("Fizz")
elif n % 5 == 0:
print("Buzz")
else:
print(n)
Loops, with their else¶
count = 0
while True:
count += 1
if count == 3:
break
else:
print("never printed: the loop broke")
print("count", count)
for n in range(3):
pass
else:
print("the for loop finished without break")
for letter in "abc":
if letter == "b":
continue
print(letter, end=" ")
print()
for can loop over a range, a list, a tuple, a string, a bytes value, a dictionary or one of its views, a set, and any of the lazy iterators d/Python supports. The else clause of a loop runs when the loop ended on its own rather than through break.
Comparisons and logic¶
a, b, c = 1, 2, 3
print(a < b < c, a < b > c, 1 == True, 0 == False)
print(True and True, 0 or 5, not [], not "x", None is None)
def loud(value):
print("evaluating", value)
return value
print(loud(0) and loud(1), loud(2) or loud(3))
A chain such as a < b < c evaluates each value once, as in Python. and and or stop as soon as the answer is known and return one of their operands rather than a plain True or False; the loud function above shows which calls actually happen. One limit today: both sides of and or or must have the same type. [] or "fallback" mixes a list and a string, so the compiler stops there and says the result would have mixed types.
Conditional expressions¶
moves = 9
message = "A draw!" if moves == 9 else "Keep playing"
print(message, "even" if moves % 2 == 0 else "odd")
The two branches must produce the same kind of value, because the compiler generates code for one result type.
Assertions¶
assert 1 + 1 == 2
try:
assert 2 + 2 == 5, "arithmetic has failed"
except AssertionError as error:
print("AssertionError:", error)
Cleanup through control flow¶
Leaving a try/finally block or a with block early with return, break or continue still runs the cleanup, in the order Python defines; see Exceptions & Context Managers. A function may call itself up to 128 levels deep, and going past that raises an error you can catch; see Functions & Closures.
What the tests cover¶
Every claim on this page comes from a test program that runs in both d/Python and CPython and must print the same thing. The corpus page lists those programs, with their reviewed output.