docs: def deprecate_module_with_proxy(module_name, module_dict, deprecated_attributes=None):
      """
      Usage:
          deprecate_module_with_proxy(__name__, locals())  # at bottom of module
      """
      def _ModuleProxy(module, depr):
          """Return a wrapped object that warns about deprecated accesses"""
          # http://stackoverflow.com/a/922693/2127762
          class Wrapper(object):
              def __getattr__(self, attr):
                  if depr is None or attr in depr:
                      warnings.warn("Property %s is deprecated" % attr)
  
                  return getattr(module, attr)
  
              def __setattr__(self, attr, value):
                  if depr is None or attr in depr:
                      warnings.warn("Property %s is deprecated" % attr)
                  return setattr(module, attr, value)
          return Wrapper()
  
      deprecated_import(module_name)
  
      deprs = set()
      for key in deprecated_attributes or module_dict:
          if key.startswith('_'):
              continue
          if callable(module_dict[key]) and not isbuiltin(module_dict[key]):
              module_dict[key] = deprecated(module_dict[key])
          else:
              deprs.add(key)
      sys.modules[module_name] = _ModuleProxy(sys.modules[module_name], deprs or None)