Skip to main content
A Python return annotation is a syntactic construct used to specify the expected data type of the value returned by a function or method. Introduced in PEP 3107 and standardized for type hinting in PEP 484, it attaches metadata to the function signature without altering its runtime execution behavior.

Syntax and Mechanics

The annotation is defined using the right arrow token (->) placed immediately after the closing parenthesis of the parameter list and before the colon that initiates the function block. The return_type can be any valid Python expression, though it is conventionally a class, a string (for forward references), or a construct from the typing module. Runtime Behavior The Python interpreter evaluates the return annotation expression at function definition time. However, Python is dynamically typed; the interpreter does not enforce type compliance during execution. Returning a value that contradicts the annotation will not raise a TypeError or RuntimeError. Enforcement is strictly the domain of static type checkers (e.g., mypy, pyright). Internal Storage When the Python interpreter constructs the function object, it stores the evaluated return annotation in the function’s __annotations__ dunder attribute. This attribute is a dictionary where the reserved key 'return' maps to the specified type object.

Annotation Variants

Void Returns Functions that do not explicitly return a value (implicitly returning None) are annotated with the None literal.
Complex and Compound Types Return annotations support complex type definitions using built-in generics (PEP 585) and the union operator (| via PEP 604), or their legacy equivalents from the typing module.
NoReturn For functions that are guaranteed to never return control to the caller (e.g., functions that unconditionally raise an exception or terminate the process), the return annotation utilizes typing.NoReturn.
Forward References If the return type is a class that has not yet been defined in the current scope, the annotation must be provided as a string literal to prevent a NameError during definition-time evaluation. Alternatively, from __future__ import annotations (PEP 563) can be used to defer the evaluation of all annotations in the module.
Tired of Poor Python Skills? Fix That With Deep Grasping!Learn More