Type annotations describe intended values to readers and static tools but do not automatically validate values passed at runtime.
Python typing reference: annotations, structural checks and runtime validation differ
Operation contract
The receipt function annotates an integer amount yet still accepts a string at call time until its implementation explicitly checks the type and bounds. The accepted constructor then returns a TypedDict-shaped mapping. TypedDict supplies a static key/value contract; it does not create a validating runtime wrapper around that ordinary dictionary.
Failure and ownership boundary
Protocols describe usable operations, while TypeGuard predicates make narrowing claims. Neither removes aliasing or verifies every method’s domain behavior. Keep validation at received-data boundaries and use static tools to check internal call paths. Python type hints: annotations do not enforce runtime arguments, Python TypeGuard: a static narrowing claim is not lasting ownership, Python Protocol: structural intent without runtime validation and Mypy static checks: annotations do not validate runtime payloads cover the individual mechanisms.
Working program
from typing import TypedDict
class AcceptedReceipt(TypedDict):
receipt_id: str
amount: int
def receipt_amount(amount: int) -> AcceptedReceipt:
if type(amount) is not int or not 0 <= amount <= 1000000:
raise ValueError("runtime amount rejected")
return {"receipt_id": "R-0041", "amount": amount}
print(receipt_amount(125))
try: receipt_amount("125")
except ValueError: print("annotated call rejected by runtime check")
received: AcceptedReceipt = {"receipt_id": "R-0041", "amount": "unchecked"}
print("ordinary dictionary:", type(received) is dict)
print("annotation alone corrected value:", type(received["amount"]) is int)Output
{'receipt_id': 'R-0041', 'amount': 125}
annotated call rejected by runtime check
ordinary dictionary: True
annotation alone corrected value: FalseCosts and limits
The explicit scalar check has bounded work. Annotation processing and whole-project checker cost depend on tool configuration and imported types. The intentionally wrong annotated assignment is a runtime teaching trace; a static checker should flag it rather than treating this file as a passing typing project.
Common Mistakes
- TypedDict is not a runtime schema parser.
- Mark intentionally wrong typing traces rather than claiming the checker accepts them.
Connected lessons
Python type hints: annotations do not enforce runtime arguments, Python TypeGuard: a static narrowing claim is not lasting ownership, Python Protocol: structural intent without runtime validation, Mypy static checks: annotations do not validate runtime payloads.
