title: Type inference for class member
body: <p>Using <code>TypeVar</code> and <code>Generic</code>, I can create classes with methods where types can be <a href="https://mypy.readthedocs.io/en/stable/generics.html#defining-generic-classes" rel="nofollow noreferrer">inferred </a>, e.g.:</p>
  <pre class="lang-py prettyprint-override"><code>from typing import TypeVar, Generic
  
  T = TypeVar('T')
  
  class Box(Generic[T]):
      def __init__(self, content: T) -&gt; None:
          self.content = content
  
  Box(1)  # OK, inferred type is Box[int]
  </code></pre>
  <p>Is it possible to infer types of a class member? Let's say I have different types of athletes' stats:</p>
  <pre><code>from abc import ABC
  from typing import Generic, TypeVar, Type
  
  
  class Stats(ABC):
      pass
  
  
  class BaseballStats(Stats):
      @property
      def batting_average(self) -&gt; float:
          return 0.314
  
  
  class FootballStats(Stats):
      @property
      def yards(self) -&gt; int:
          return 314
  </code></pre>
  <p>And now I want to define an abstract class for an athlete:</p>
  <pre><code>S = TypeVar('S', bound=Stats)
  
  
  class Athlete(ABC, Generic[S]):
      _stats_type: Type[S]
  
      @property
      def stats(self) -&gt; S:
          return self._stats_type()
  </code></pre>
  <p>If I try to make a <code>BaseballPlayer</code> and have it infer the type by assigning to <code>_stats_type</code>, it won't:</p>
  <pre><code>class BaseballPlayer(Athlete):
      _stats_type = BaseballStats
  
  
  bo = BaseballPlayer()
  # reveal_type(bo.stats) --&gt; gives `Any`; type was not inferred
  print(bo.stats.batting_average)  # works.
  </code></pre>
  <p>If I specify the type of <code>Athlete</code> but don't assign <code>_stats_type</code>, it won't run.</p>
  <pre><code>class FootballPlayer(Athlete[FootballStats]):
      pass
  
  
  bo = FootballPlayer()
  # reveal_type(bo.stats) --&gt; gives `FootballStats` because I explcitly called it out
  print(bo.stats.yards)  # AttributeError: 'FootballPlayer' object has no attribute '_stats_type'
  </code></pre>
  <p>Is there an alternative that doesn't require that I put the type of statistics in two places? I.e., can I avoid doing this?</p>
  <pre><code>class FootballPlayer(Athlete[FootballStats]):
      _stats_type = FootballStats
  </code></pre>