Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python TypeGuard: a static narrowing claim is not lasting ownership

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

TypeGuard lets a predicate describe a narrower type to a static checker when that predicate returns true.

Download Python source kit

Operation contract

The predicate checks that a bounded list contains exact nonnegative integers. A successful check proves the current contents only. Another alias can append a string afterward, invalidating the runtime assumption. Copying the accepted values into an immutable tuple gives the subsequent calculation owned membership instead of relying on a mutable shared list.

Failure and ownership boundary

TypeGuard does not perform validation by itself and a checker generally trusts the predicate’s annotation. The runtime implementation must establish the declared condition. A copied tuple can still alias nested mutable objects; this fixture permits only immutable integers. Python Protocol: structural intent without runtime validation, Mypy static checks: annotations do not validate runtime payloads and Python shallow and deep copies: preserve aliases deliberately are separate concerns.

Working program

python
from typing import TypeGuard

def accepted_amounts(value: object) -> TypeGuard[list[int]]:
    return isinstance(value, list) and len(value) <= 64 and all(type(amount) is int and 0 <= amount <= 1000000 for amount in value)

received = [125, 250]
print("accepted:", accepted_amounts(received))
owned = tuple(received) if accepted_amounts(received) else ()
alias = received
alias.append("rejected")
print("shared still accepted:", accepted_amounts(received))
print("owned total:", sum(owned))
print("boolean accepted:", accepted_amounts([True]))

Output

Output
accepted: True
shared still accepted: False
owned total: 375
boolean accepted: False

Costs and limits

Validation and tuple construction cost O(n) work and retained references for n values. The maximum batch is 64. An annotation cannot stop another owner from changing the original list after a check.

Common Mistakes

  • A narrowing predicate’s annotation is a promise its implementation must satisfy.
  • A mutable alias can invalidate a previously checked condition.

Connected lessons

Python type hints: annotations do not enforce runtime arguments, Python Protocol: structural intent without runtime validation, Python shallow and deep copies: preserve aliases deliberately.

python
typing-narrowing
Storage details