Python equivalent to `as` type assertion in TypeScript

Question:

In TypeScript you can override type inferences with the as keyword

const canvas = document.querySelector('canvas') as HTMLCanvasElement;

Are there similar techniques in Python3.x typing without involving runtime casting? I want to do something like the following:

class SpecificDict(TypedDict):
    foo: str
    bar: str

res = request(url).json() as SpecificDict
Asked By: Michael Moreno

||

Answers:

If I understand you correctly, you’re looking for typing.cast:

from typing import cast
res = cast(dict, request(url))

This will assert to a typechecker that res is assigned to a value that is a dictionary, but it won’t have any effects at runtime.

Answered By: BrokenBenchmark

as allows for explicit casting of a value to a sub- or supertype of the real value. This is relevant for a statically typed language, not so much for a dynamically typed language like Python. The typing module lets you provide static type hints that a third-party tool like mypy can use to look for static-type errors before you run your code, so let’s focus on it.

typing.cast provides a general escape hatch for static typing: you are not restricted to sub- or super types of the actual type. You can claim that a value x has any type you like, and mypy will believe you. For example,

x: str = typing.cast(int, 5)  # Sure, OK, 5 is a string
assert isinstance(x, str)  # Oops, I guess not.

An as-like use of cast might be

x: Optional[int] = 3
y: int = x  # fail, x might be None at runtime
z: int = typing.cast(int, x)  # don't worry, I promise x isn't None

Upcasting is a little easier, as a type annotation will suffice.

x: bool = True
y: int = x  # Ok, bool is a subtype of int

mypy does perform type narrowing in certain contexts. For example, if a certain block of code can only be reached if a certain run-time type check passes, mypy will infer the type implied by the successful check.

x : Optional[int] = 5
x += 1  # static type error, since None doesn't support +=

but

x : Optional[int] = 5
if x is not None:
    x += 1  # OK; if x is not None is true, then we can assume x: int
Answered By: chepner
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.