Skip to content

Functions

Defining a function

def add(a: int, b: int) -> int:
return a + b
def main() -> None:
print(add(1, 2))

All parameters and return types must be annotated. Functions returning nothing use -> None.

Overloads

Multiple functions with the same name but different parameter types are supported:

import math
def twice(x: int) -> int:
return x + x
def twice(x: float) -> float:
return x + x
def main() -> None:
print(math.abs(-5))
print(math.abs(-3.5))
print(twice(4))
print(twice(1.25))

Overload resolution rules

  • Overloads are resolved at compile time from parameter types only.
  • Exact match wins.
  • int → float widening is allowed when no exact match exists.
  • Ambiguous matches (two equally-valid candidates) are rejected with a diagnostic that lists all candidates.
  • Return type does not participate in resolution.
  • Methods are not overloaded.

Return flow

Non-None functions must return on all paths. py4 checks this statically:

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))

Top-level only

Functions must be declared at module scope. Nested functions and lambdas are not supported.