title: How to type hint a dictionary with values of different types
body: <p>When declaring a dictionary as a literal, is there a way to type-hint what value I am expecting for a specific key?</p>
  <p>And then, for discussion: are there guiding principles around dictionary typing in Python? I'm wondering whether it is considered bad practice to mix types in dictionaries.</p>
  <hr />
  <p>Here's an example:</p>
  <p>Consider the declaration of a dictionary in a class's <code>__init__</code> :</p>
  <p><em>(Disclaimer: I realize in the example, some of the <code>.elements</code> entries would probably be more appropriate as class attributes, but it's for the sake of the example.)</em></p>
  <pre><code>class Rectangle:
      def __init__(self, corners: Tuple[Tuple[float, float]], **kwargs):
          self.x, self.z = corners[0][0], corners[0][1]
          self.elements = {
              'front': Line(corners[0], corners[1]),
              'left': Line(corners[0], corners[2]),
              'right': Line(corners[1], corners[3]),
              'rear': Line(corners[3], corners[2]),
              'cog': calc_cog(corners),
              'area': calc_area(corners),
              'pins': None
          }
  
  
  class Line:
      def __init__(self, p1: Tuple[float, float], p2: Tuple[float, float]):
          self.p1, self.p2 = p1, p2
          self.vertical = p1[0] == p2[0]
          self.horizontal = p1[1] == p2[1]
  </code></pre>
  <p>When I type type the following,</p>
  <pre><code>rec1 = Rectangle(rec1_corners, show=True, name='Nr1')
  rec1.sides['f...
  </code></pre>
  <p>Pycharm will suggest <code>'front'</code>  for me. Better still, when I do</p>
  <pre><code>rec1.sides['front'].ver...
  </code></pre>
  <p>Pycharm will suggest <code>.vertical</code></p>
  <p>So Pycharm remembers the keys from the dictionary literal declaration in the class's <code>__init__</code>, and also their values' expected types. Or rather: it expects any value to have any one of the types that are in the literal declaration - probably the same as if I had done a <code>self.elements = {}  # type: Union[type1, type2]</code> would do. Either way, I find it super helpful.</p>
  <p>If your functions have their outputs type-hinted, then Pycharm will also take that into account.</p>
  <p>So assuming that in the <code>Rectangle</code> example above, I wanted to indicate that <code>pins</code> is a list of <code>Pin</code> objects... if <code>pins</code> was a normal class attribute, it would be:</p>
  <pre><code>    self.pins = None  # type: List[Pin]
  </code></pre>
  <p>(provided the necessary imports were done)</p>
  <p>Is there a way to give the same type hint in the dictionary literal declaration?</p>
  <p>The following does <strong>not</strong> achieve what I am looking for:</p>
  <p>Add a <code>Union[...]</code> type hint at the end of the literal declaration?</p>
  <pre><code>            'area': calc_area(corners),
              'pins': None
          }  # type: Union[Line, Tuple[float, float], float, List[Pin]]
  </code></pre>
  <p>Adding a type-hint to every line:</p>
  <pre><code>            'area': calc_area(corners),  # type: float
              'pins': None  # type: List[Pin]
          }
  </code></pre>
  <p>Is there a best practice for this kind of thing?</p>
  <hr />
  <p>Some more background:</p>
  <p>I work with Python in PyCharm and I make extensive use of typing, since it helps me to predict and validate my work as I go along. When I create new classes, I also sometimes throw some less frequently used properties into a dictionary to avoid cluttering the object with too many attributes (this is helpful in debug mode).</p>