Skip to content

Control Flow

if / elif / else

def classify(x: int) -> str:
if x > 5:
return "big"
elif x == 5:
return "mid"
else:
return "small"
def main() -> None:
print(classify(3))
print(classify(5))
print(classify(8))

while

def main() -> None:
i: int = 0
total: int = 0
while i < 4:
total = total + i
i = i + 1
print(total)

for with range

def main() -> None:
total: int = 0
for i in range(5):
total = total + i
print(total)
for j in range(2, 6):
print(j)
for k in range(6, 0, -2):
print(k)

range is loop-oriented, not a first-class runtime object.

for over a list

def main() -> None:
xs: list[int] = [1, 2, 3]
for x in xs:
print(x)

for over a dict

def main() -> None:
colors: dict[str, str] = {"apple": "red", "sky": "blue"}
for key in colors:
print(key)
print(colors[key])
counts: dict[str, int] = {"a": 1, "b": 2}
for (key, value) in counts.items():
print(key)
print(value)

Tuple destructuring works in for targets when the iterable yields tuples.

break and continue

def main() -> None:
i: int = 0
while i < 6:
i = i + 1
if i == 2:
continue
if i == 5:
break
print(i)
total: int = 0
for x in range(6):
if x == 1:
continue
if x == 4:
break
total = total + x
print(total)

Cleanup for managed locals is preserved across break and continue.

with (io.File)

with is supported only for io.File. It ensures the file is closed at block exit.

import io
def main() -> None:
path: str = "/tmp/example.txt"
writer: io.File = io.open(path, "w")
with writer as file:
io.write(file, "first\n")
io.write(file, "second\n")
io.flush(file)
io.close(writer) # writer is still valid after the block
with io.open(path, "r") as file:
print(io.read_line(file))
print(io.read_line(file))

with is not a general context manager protocol — there is no __enter__ or __exit__.

assert

def main() -> None:
nums: list[int] = [1, 2, 3]
assert len(nums) == 3
assert nums[1] == 2, "middle element changed"
print("ok")

A failed assertion writes to stderr and exits the process. It is not an exception.