title: Can mypy generics express passing the return sequence type as an argument?
body: <p>I'd like to write the following generic Python code:</p>
  
  <pre class="lang-python prettyprint-override"><code>from itertools import chain
  from typing import Sequence, Hashable, List, Tuple, Type, TypeVar
  
  
  SequenceT = TypeVar('SequenceT', bound=Sequence)
  HashableT = TypeVar('HashableT', bound=Hashable)
  
  
  def merge_and_sort_into(seq_type, *iterables):
      # type: (Type[SequenceT], *Iterable[HashableT]) -&gt; SequenceT[HashableT]
      return seq_type(sorted(set(chain(*iterables))))
  
  
  def merge_and_sort_into_list(*iterables):
      # type: (*Iterable[HashableT]) -&gt; List[HashableT]
      return merge_and_sort_into(list, *iterables)
  
  
  def merge_and_sort_into_tuple(*iterables):
      # type: (*Iterable[HashableT]) -&gt; Tuple[HashableT]
      return merge_and_sort_into(tuple, *iterables)
  </code></pre>
  
  <p>The code is fine, but mypy doesn't like the return type of <code>merge_and_sort_into()</code> saying <code>error: Type variable "SequenceT" used with arguments</code>. How can I pass a Sequence type into a function and also use that type as the return type?  (note: I'm not capturing the fact that the value type for the sequence also needs to be comparable/sortable, but let's just ignore that).</p>
  
  <p>Here is a version that mypy will accept, but it doesn't capture the constraint that type passed into <code>merge_and_sort_into()</code> is its return type, hence the casts.</p>
  
  <pre class="lang-python prettyprint-override"><code>def merge_and_sort_into(seq_type, *iterables):
      # type: (Callable[[Iterable[HashableT]], Sequence[HashableT]], *Iterable[HashableT]) -&gt; Sequence[HashableT]
      return seq_type(sorted(set(chain(*iterables))))
  
  
  def merge_and_sort_into_list(*iterables):
      # type: (*Iterable[HashableT]) -&gt; List[HashableT]
      return cast(List[HashableT], merge_and_sort_into(list, *iterables))
  
  
  def merge_and_sort_into_tuple(*iterables):
      # type: (*Iterable[HashableT]) -&gt; Tuple[HashableT]
      return cast(Tuple[HashableT], merge_and_sort_into(tuple, *iterables))
  </code></pre>