Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A type-annotated attribute is a class, instance, or module-level variable explicitly bound to a type hint using the colon (:) syntax defined in PEP 526. These annotations provide static type metadata for static analysis tools (such as mypy or pyright) and are evaluated at runtime to populate the __annotations__ dictionary of the enclosing scope, though the Python interpreter does not enforce these types during execution.

Syntax


# Uninitialized type annotation
attribute_name: type_expression


# Initialized type annotation
attribute_name: type_expression = default_value

Runtime Mechanics

When the Python interpreter encounters a type-annotated attribute within a class body, it updates the class’s __annotations__ dunder attribute. The instantiation of the actual variable in memory depends on whether a default value is assigned:
  • Uninitialized Annotations: If no default value is provided, the attribute’s type is recorded in __annotations__, but the variable is not added to the class or instance __dict__. Attempting to access the attribute at runtime before explicitly assigning a value to it will raise an AttributeError.
  • Initialized Annotations: If a default value is provided, the attribute is added to both __annotations__ and the class __dict__.
class Node:
    # Added to __annotations__, but not to __dict__
    parent: 'Node' 
    
    # Added to both __annotations__ and __dict__
    value: int = 0 

print(Node.__annotations__)

# Output: {'parent': 'Node', 'value': <class 'int'>}

print(hasattr(Node, 'parent')) 

# Output: False

print(hasattr(Node, 'value'))  

# Output: True

ClassVar vs. Instance Attributes

By default, static type checkers interpret standard type-annotated attributes within a class body as instance attributes. To explicitly define an attribute as a class variable (indicating it is shared across all instances and should not be shadowed by an instance variable), the typing.ClassVar generic type is required.
from typing import ClassVar

class Configuration:
    # Interpreted as an instance attribute by type checkers
    timeout: int = 30 
    
    # Strictly interpreted as a class attribute by type checkers
    max_retries: ClassVar[int] = 5 
At runtime, ClassVar does not alter the behavior or memory layout of the attribute; it is purely a static typing construct. The __annotations__ dictionary will store the type as typing.ClassVar[int].

Stringified Annotations (PEP 563)

If from __future__ import annotations is declared at the top of a module, Python defers the runtime evaluation of type-annotated attributes. Instead of storing the evaluated type objects (e.g., <class 'int'>), the __annotations__ dictionary stores the string representation of the type hint (e.g., 'int').
from __future__ import annotations

class Tree:
    # 'Tree' is stored as a string, preventing a NameError 
    # even though the Tree class is not yet fully defined.
    left_node: Tree 
This mechanism resolves forward references and reduces module initialization time by bypassing the immediate evaluation of the type expressions. Tools requiring the actual type objects at runtime must resolve these strings using typing.get_type_hints().
Master Python with Deep Grasping Methodology!Learn More