title: How to correctly wrap a dict in Python 3?
body: <p>Sometimes it's nice to be able to use a dictionary like an object (so that you don't have to always write <code>mydict['blah']</code>.  Instead, you can write <code>mydict.blah</code></p>
  
  <p>In Python 3, there are new rules about overriding/wrapping a python dictionary.  In Python2, it was enough to wrap the <code>__getattr__</code> and <code>__setattr__</code> methods. When you wrap these things, you get some nice capabilities to add some special handling when a certain attribute was added (e.g. you could clean/filter data in/out of a dict).  </p>
  
  <p>A situation where this is helpful is in a Flask template (an HTML template).  Using a <code>__getattr__</code> filter, you can format data as it leaves the <code>dict</code>.  This way, in the template (where Python expressions can look a little complex) you can keep things simple in there by just writing <code>mymodel.blah</code> and knowing that the text coming out of <code>blah</code> is already the way you want it.</p>
  
  <p>In Python3 wrapping a <code>dict</code> is a little messy.  I"m not sure how to make it work now.  Here are two rough implementations that are not working well:</p>
  
  <pre><code># messed up Python3 wrapped dictionary (sets work, but gets do not)
  class AttrDict(dict):
      def __init__(self, *args, **kwargs):
          super(AttrDict, self).__init__(*args, **kwargs)
          self.__dict__ = self
          self.clean_strings()
      def clean_strings(self):
          for key, value in self.items():
              self[key] = string_empty_to_none(value)
      def __getattr__(self, name):
          #this never gets called in Python 3
          return self[name]
  </code></pre>
  
  <p>Here's another one:</p>
  
  <pre><code># sets don't work - Always throws: TypeError: 'AttrDict' object does not support item assignment
  class AttrDict():
      def __init__(self, *args, **kwargs):
          self.data = dict()
          self.data.__init__(*args, **kwargs)
          self.clean_strings()
      def clean_strings(self):
          for key, value in self.data.items():
              self.data[key] = string_empty_to_none(value)
      def __getattr__(self, attr):
          if attr in self.data:
              return self.data[attr]
          else:
              raise AttributeError("--%r object has no attribute %r" % (type(self).__name__, attr)) 
      def __setattr__(self, name, value):
          if name == 'data':
              super(AttrDict, self).__setattr__(name, value)
          else:
              self.data[name] = value
  </code></pre>
  
  <p>Here's what my little utility method looks like:</p>
  
  <pre><code>def string_empty_to_none(s):
      if type(s) == str:
              return None if (s.strip() == '') else s
  
      return s
  </code></pre>
  
  <p>I know that in Python3, you are supposed to use <code>__getattribute__</code> instead of <code>__getattr__</code>  But that always seems to end up in an infinite loop when I do this.</p>
  
  <p>NOTE: that the final syntax that I'm looking for is like this:</p>
  
  <pre><code>&gt;&gt;&gt; x = AttrDict({'some': 'value'})
  &gt;&gt;&gt; x['blah'] = 'hello world'
  &gt;&gt;&gt; print(x.blah)
  hello world
  &gt;&gt;&gt; print(x.some)
  value
  </code></pre>