title: Python typing: How to type a variable in an typed dict which have a default value in the func it is used?
body: <p>I discovered typing in python some time ago and am currently trying to use it in my projects.</p>
  
  <p>I have encountered a problem:</p>
  
  <p>I have two classes. One is an evaluator for machine learning training results. The second one is a comparator, which creates n evaluators and compares their results.</p>
  
  <pre><code>    class Parameters(TypedDict):
          modelname: str
          filename: str
          last_ckpt: str
          project_path: str
          number_of_ckpt: int
  
      class ResultEvaluator(object):
          def __init__(
                 self,
                 parameters: Parameters,
                 evaluation_results_folder: str = &lt;default path&gt;,
                 kitti_native_results_path: str = &lt;default  path&gt;
         ) -&gt; None:
             self.parameters = parameters
             self.evaluation_results_folder = evaluation_results_folder
             self.kitti_native_results_path = kitti_native_results_path
  
  
      class ComparatorFormatParameters(TypedDict):
          parameters: Parameters
          evaluation_results_folder: str
          kitti_native_results_path: str
  
  
  
      class ResultComparator(object):
         def __init__(
                 self,
                 comperator_objectives_params:
                 List[ComparatorFormatParameters]
         ) -&gt; None:
             self.comparator_objectives: List[re.ResultEvaluator] = \
                 [
                     re.ResultEvaluator(**objective_params)
                     for objective_params in comperator_objectives_params
                 ]     
  </code></pre>
  
  <p>An evaluator gets a dictionary and two strings during initialization. The dictionary contains all parameters that must always be specified. The two strings contain paths that never have to be changed during normal operation. However, they must be changed for test purposes.
  Therefore, a default value is assigned to them in the <strong>init</strong> method.
  So you can also simply initialize the evaluator with the dictionary.</p>
  
  <p>So that I can use the comparator with n evaluators I give it a list with the evaluator parameters.
  So that these can be easily unpacked for initializing the evaluator, I have also created a typed dict. It contains the evaluator parameter typed dict and the two strings.
  This all works so far.</p>
  
  <p>Only if I mark the two strings of the typed dict as optional there will be a mypy error during the type checking, because the evaluator <strong>init</strong> method should get one parameter dict and two strings.
  But since default values are available there are no problems when using it.</p>
  
  <p>Do I have to type the two strings in typed dict as string types, even though they are not always included? In the example code above I have done it and I don't get any mypy errors, but somehow it doesn't seem quite right to me.
  Or is there a completely different and nicer solution?
  Thanks for the help!</p>
  
  <p>edit:</p>
  
  <p>At the moment I can initialize a result evaluator like this:</p>
  
  <pre><code>    result_evaluator_instance = ResultEvaluator(
              {
                  "model name": &lt;model name&gt;,
                  "filename": &lt;filename&gt;,
                  "last_ckpt": "120000"
                  "project_path": &lt;path&gt;,
                  "number_of_ckpt": 12
              },
              &lt;path&gt;,
              &lt;path&gt;
     )
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>    result_evaluator_instance = ResultEvaluator(
              {
                  "model name": &lt;model name&gt;,
                  "filename": &lt;filename&gt;,
                  "last_ckpt": "120000"
                  "project_path": &lt;path&gt;,
                  "number_of_ckpt": 12
              }
      )
  </code></pre>
  
  <p>Normally this second variant is used.</p>
  
  <p>When I initialize the comparator this is what happens:</p>
  
  <pre><code>    comparator = ResultComparator(
                  [
                      {
                          "parameters": {
                                           "model name": &lt;model name&gt;,
                                           "filename": &lt;filename&gt;,
                                           "last_ckpt": "120000"
                                           "project_path": &lt;path&gt;,
                                           "number_of_ckpt": 12
                                        }
                      },
                      {
                          "parameters": {
                                           "model name": &lt;model name&gt;,
                                           "filename": &lt;filename&gt;,
                                           "last_ckpt": "120000"
                                           "project_path": &lt;path&gt;,
                                           "number_of_ckpt": 12
                                        }
                      },
                  ]
              )
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>    comparator = ResultComparator(
                  [
                      {
                          "parameters": {
                                           "model name": &lt;model name&gt;,
                                           "filename": &lt;filename&gt;,
                                           "last_ckpt": "120000"
                                           "project_path": &lt;path&gt;,
                                           "number_of_ckpt": 12
                                        },
                          "evaluation_results_folder": &lt;path&gt;,
                          "kitti_native_results_path": &lt;path&gt;
                      },
                      {
                          "parameters": {
                                           "model name": &lt;model name&gt;,
                                           "filename": &lt;filename&gt;,
                                           "last_ckpt": "120000"
                                           "project_path": &lt;path&gt;,
                                           "number_of_ckpt": 12
                                        },
                          "evaluation_results_folder": &lt;path&gt;,
                          "kitti_native_results_path": &lt;path&gt;
                      }
                  ]
          )
  </code></pre>
  
  <p>It also works both in each case. I just think it's misleading if in the ComparatorFormatParameter both paths have the type string, although they don't always have to be present.
  So I have looked for a syntactically correct way to indicate this.</p>
  
  <p>I also tried to assign default values to the two strings in the ComparatorFormatParameters.</p>
  
  <pre><code>    class ComparatorFormatParameters(TypedDict):
          parameters: Parameters
          evaluation_results_folder: str = None
          kitti_native_results_path: str = None
  </code></pre>
  
  <p>Unfortunately these default values then overwrite the default values I assigned in the ResultEvaluator.<strong>init</strong>.</p>
  
  <p>So far I had optionally tried what I think Union[str, None] is.
  But now I have explicitly tested Union[str, None] again and mypy returns errors.</p>