title: How to fallback to default when using module __getattr__
body: <p>TL;DR: Is <code>globals()[name]</code> the CORRECT way to fall back to the "default"?</p>
  
  <p>I have a large set of dynamically created classes that are defined from a YML file.</p>
  
  <p>Dynamic class creation is accomplished via a combination of <a href="http://pyyaml.org/wiki/PyYAMLDocumentation" rel="nofollow noreferrer">PyYAML <code>yaml.safe_load_all</code></a> and the <a href="https://www.python.org/dev/peps/pep-0557/" rel="nofollow noreferrer"><code>dataclasses.make_dataclass</code></a> (<a href="https://docs.python.org/dev/whatsnew/3.7.html" rel="nofollow noreferrer">new in 3.7</a>). I expect the specifications for these classes to occasionally change over time, which is why I chose YML as an easily understood format to describe them.</p>
  
  <p>Python 3.7 is introducing new functionality (<a href="https://www.python.org/dev/peps/pep-0562/" rel="nofollow noreferrer">see PEP 562</a>): a module-level <code>__getattr__</code> function for managing module attribute access (there is also a module-level <code>__dir__</code> function). It would be convenient to utilize this new function to allow importing of each dynamically created <code>dataclass</code> class from the module namespace, like so:</p>
  
  <pre><code># some_module.py
  from package_name import DataClassName1, DataClassName2
  </code></pre>
  
  <p>...and like so:</p>
  
  <pre><code># package_name/__init__
  from .my_dataclasses import DynamicDataClassesDict
  
  def __getattr__(name):
      try:
          return DynamicDataClassesDict[name]
      except KeyError:
          # fall back on default module attribute lookup
  </code></pre>
  
  <p>In reading PEP 562 it isn't immediately clear to me how to fall back to default functionality for module attribute access. For a class, one would just call <code>super().__getattr__(*args)</code>. I do see this line in one of the examples:</p>
  
  <pre><code>return globals()[f"_deprecated_{name}"]
  </code></pre>
  
  <p>This approach seems to work. Is <code>globals()[name]</code> the CORRECT way to fall back to the "default"? It doesn't seem to be, given that <code>globals()[name]</code> will raise a <code>KeyError</code> rather than the expected <code>AttributeError</code>.</p>