title: Python type hints - better syntax for cast()?
body: <p>I recently started using <a href="https://docs.python.org/3/library/typing.html" rel="noreferrer">type hints</a> in my code, and have so far found them to be (mostly) very helpful.</p>
  
  <p>However, one thing that I really do not like is the syntax to force the type checker to assume that a variable is of a certain type.  Given this example:</p>
  
  <pre><code>import itertools
  from typing import Iterable, Tuple
  x: Iterable[Tuple[str, str]] = itertools.combinations('abc', 2)
  # error: Incompatible types in assignment (expression has type "Iterable[Tuple[str, ...]]", variable has type "List[Tuple[str, str]]")
  </code></pre>
  
  <p>As far as I can tell, the recommended way to work around this is to explicitly <a href="https://docs.python.org/3/library/typing.html#typing.cast" rel="noreferrer"><code>cast</code></a> the object to force the type checker to use the specified type, e.g.:</p>
  
  <pre><code>import itertools
  from typing import Iterable, Tuple, cast
  x = cast(Iterable[Tuple[str, str]], itertools.combinations('abc', 2))
  </code></pre>
  
  <p>I personally find this solution to be a bit gross.  My primary concern is that, to the inexperienced reader, it is not clear that the <code>cast</code> is purely there to help the static analyzer.  (If I didn't already know, I would assume based on the name and context that it is converting and doing a copy into an object of the specified type, when really there is no runtime cost.)</p>
  
  <p><code>cast</code> looks like any old function call.  When I see that a function is being called on a value, I expect the value to be mutated and/or some other side-effects to occur, but in this case the only side effect is that <code>mypy</code> stops complaining.  Type hints themselves have a distinct syntax, but I feel that this blurs the lines with a mixture of the new typing syntax and traditional python syntax.  (It's already a bit blurry since you have to <code>import</code> the types and can compose them, but that's another discussion.)</p>
  
  <p>Is there an alternative syntax for <code>cast</code>-like behavior?  I haven't found anything, but I was hoping for something like:</p>
  
  <pre><code>x1 = itertools.combinations('abc', 2)) # cast: Iterable[Tuple[str, str]] 
  
  x2: Iterable[Tuple[str, str]] = itertools.combinations('abc', 2)) # type: cast
  
  x3: Cast[Iterable[Tuple[str, str]]] = itertools.combinations('abc', 2))
  </code></pre>