Thanks for the clarifications. So casting is the solution to avoid this problem with static type checkers?
Switching back to Literals...
...
...
It is true that a Literal type will generally only be statically known
when it originates from a Python literal expression. But this is just
a specific case of the general limitations of static analysis: that
statically-known types are a wider approximation of the actual runtime
types.
To clarify this point: there are many other situations where the same
symptom you observe (static type checking may fail where runtime
checking would pass) can occur without the involvement of Literal
types. Consider this example:
```
def f(x: object) -> None:
g(x)
def g(x: int) -> None
...
f(1)
```
This code must fail static type checking because the call to g(x) is
invalid since it passes an `object` where an `int` is required. The
statically known type of `x` within `f` is only `object`, since
call-sites of `f` will be allowed to pass any object. And yet in the
specific case of the call `f(1)`, where the argument happens to be an
integer, runtime type checking will be fine.
This is exactly analogous to the case you are describing, if we had
instead `g(x: Literal[1]) -> None` and `f(x: int) -> None` -- this is
statically a type error, because the static type check must consider
that `x` could take on any value that is part of the type `int`, even
though any given specific runtime call might check out fine, if `x`
happens to in fact be `1` for that call.
Carl