title: How can I type hint a dynamically set class attribute in a metaclass?
body: <p>When I dynamically set the attribute of a class:</p>
  
  <pre><code>from typing import TypeVar, Generic, Optional, ClassVar, Any
  
  class IntField:
      type = int
  
  class PersonBase(type):
      def __new__(cls):
          for attr, value in cls.__dict__.items():
              if not isinstance(value, IntField):
                  continue
              setattr(cls, attr, value.type())
          return cls
  
  class Person(PersonBase):
      age = IntField()
  
  person = Person()
  
  print(type(Person.age)) # &lt;class 'int'&gt;
  print(type(person.age)) # &lt;class 'int'&gt;
  person.age = 25 # Incompatible types in assignment (expression has type "int", variable has type "IntField")
  </code></pre>
  
  <p>The type of the <code>age</code> attribute will be of type <code>int</code>, but MyPy cannot follow that.</p>
  
  <p>Is there a way I can make MyPy understand?</p>
  
  <p>Django has it implemented:</p>
  
  <pre><code>from django.db import models
  
  class Person(models.Model):
      age = models.IntegerField()
  
  person = Person()
  print(type(Person.age)) # &lt;class 'django.db.models.query_utils.DeferredAttribute'&gt;
  print(type(person.age)) # &lt;class 'int'&gt;
  person.age = 25  # No error
  </code></pre>
  
  <p>How does Django do this?</p>