title: Python 3 type hint for a factory method on a base class returning a child class instance
body: <p>Let's say I have two classes <code>Base</code> and <code>Child</code> with a factory method in <code>Base</code>. The factory method calls another classmethod which may be overriden by <code>Base</code>'s child classes.</p>
  
  <pre><code>class Base(object):
      @classmethod
      def create(cls, *args: Tuple) -&gt; 'Base':
          value = cls._prepare(*args)
          return cls(value)
  
      @classmethod
      def _prepare(cls, *args: Tuple) -&gt; Any:
          return args[0] if args else None
  
      def __init__(self, value: Any) -&gt; None:
          self.value = value
  
  
  class Child(Base):
      @classmethod
      def _prepare(cls, *args: Tuple) -&gt; Any:
          return args[1] if len(args) &gt; 1 else None
  
      def method_not_present_on_base(self) -&gt; None:
          pass
  </code></pre>
  
  <p>Is there a way to annotate <code>Base.create</code> so that a static type checker could infer that <code>Base.create()</code> returned an instance of <code>Base</code> and <code>Child.create()</code> returned an instance of <code>Child</code>, so that the following example would pass static analysis?</p>
  
  <pre><code>base = Base.create(1)
  child = Child.create(2, 3)
  child.method_not_present_on_base()
  </code></pre>
  
  <p>In the above example a static type checker would rightfully complain that the <code>method_not_present_on_base</code> is, well, not present on the <code>Base</code> class.</p>
  
  <hr>
  
  <p>I thought about turning <code>Base</code> into a generic class and having the child classes specify themselves as type arguments, i.e. bringing the <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" rel="noreferrer">CRTP</a> to Python.</p>
  
  <pre><code>T = TypeVar('T')
  
  class Base(Generic[T]):
      @classmethod
      def create(cls, *args: Tuple) -&gt; T: ...
  
  class Child(Base['Child']): ...
  </code></pre>
  
  <p>But this feels rather unpythonic with CRTP coming from C++ and all...</p>