title: Python: Typehints for argparse.Namespace objects
body: <p>Is there a way to have Python static analyzers (e.g. in PyCharm, other IDEs) pick up on Typehints on <code>argparse.Namespace</code> objects?  Example:</p>
  
  <pre><code>parser = argparse.ArgumentParser()
  parser.add_argument('--somearg')
  parsed = parser.parse_args(['--somearg','someval'])  # type: argparse.Namespace
  the_arg = parsed.somearg  # &lt;- Pycharm complains that parsed object has no attribute 'somearg'
  </code></pre>
  
  <p>If I remove the type declaration in the inline comment, PyCharm doesn't complain, but it also doesn't pick up on invalid attributes.  For example:</p>
  
  <pre><code>parser = argparse.ArgumentParser()
  parser.add_argument('--somearg')
  parsed = parser.parse_args(['--somearg','someval'])  # no typehint
  the_arg = parsed.somaerg   # &lt;- typo in attribute, but no complaint in PyCharm.  Raises AttributeError when executed.
  </code></pre>
  
  <p>Any ideas?</p>
  
  <hr>
  
  <h3>Update</h3>
  
  <p>Inspired by <a href="https://stackoverflow.com/a/42279784/7007605">Austin's answer</a> below, the simplest solution I could find is one using <code>namedtuples</code>:</p>
  
  <pre><code>from collections import namedtuple
  ArgNamespace = namedtuple('ArgNamespace', ['some_arg', 'another_arg'])
  
  parser = argparse.ArgumentParser()
  parser.add_argument('--some-arg')
  parser.add_argument('--another-arg')
  parsed = parser.parse_args(['--some-arg', 'val1', '--another-arg', 'val2'])  # type: ArgNamespace
  
  x = parsed.some_arg  # good...
  y = parsed.another_arg  # still good...
  z = parsed.aint_no_arg  # Flagged by PyCharm!
  </code></pre>
  
  <p>While this is satisfactory, I still don't like having to repeat the argument names.  If the argument list grows considerably, it will be tedious updating both locations.  What would be ideal is somehow extracting the arguments from the <code>parser</code> object like the following:</p>
  
  <pre><code>parser = argparse.ArgumentParser()
  parser.add_argument('--some-arg')
  parser.add_argument('--another-arg')
  MagicNamespace = parser.magically_extract_namespace()
  parsed = parser.parse_args(['--some-arg', 'val1', '--another-arg', 'val2'])  # type: MagicNamespace
  </code></pre>
  
  <p>I haven't been able to find anything in the <code>argparse</code> module that could make this possible, and I'm still unsure if <em>any</em> static analysis tool could be clever enough to get those values and not bring the IDE to a grinding halt.</p>
  
  <p>Still searching...</p>
  
  <hr>
  
  <h3>Update 2</h3>
  
  <p>Per hpaulj's comment, the closest thing I could find to the method described above that would "magically" extract the attributes of the parsed object is something that would extract the <code>dest</code> attribute from each of the parser's <code>_action</code>s.:</p>
  
  <pre><code>parser = argparse.ArgumentParser()
  parser.add_argument('--some-arg')
  parser.add_argument('--another-arg')
  MagicNamespace = namedtuple('MagicNamespace', [act.dest for act in parser._actions])
  parsed = parser.parse_args(['--some-arg', 'val1', '--another-arg', 'val2'])  # type: MagicNamespace
  </code></pre>
  
  <p>But this still does not cause attribute errors to get flagged in static analysis.  This is true also true if I pass <code>namespace=MagicNamespace</code> in the <code>parser.parse_args</code> call.</p>