docs: def deepgetattr(obj, attr, default=AttributeError):
      """
      Recurses through an attribute chain to get the ultimate value (obj/data/member/value)
      from: http://pingfive.typepad.com/blog/2010/04/deep-getattr-python-function.html
  
      >>> class Universe(object):
      ...     def __init__(self, galaxy):
      ...             self.galaxy = galaxy
      ...
  
      >>> class Galaxy(object):
      ...     def __init__(self, solarsystem):
      ...             self.solarsystem = solarsystem
      ...
  
      >>> class SolarSystem(object):
      ...     def __init__(self, planet):
      ...             self.planet = planet
      ...
  
      >>> class Planet(object):
      ...     def __init__(self, name):
      ...             self.name = name
      ...
  
      >>> universe = Universe(Galaxy(SolarSystem(Planet('Earth'))))
      >>> deepgetattr(universe, 'galaxy.solarsystem.planet.name')
      'Earth'
      >>> deepgetattr(universe, 'solarsystem.planet.name', default=TypeError)
      <class 'TypeError'>
      """
      try:
          return reduce(getattr, attr.split('.'), obj)
      except AttributeError:
          if default is not AttributeError:
              return default
          raise