def __getattr__(self, attr):
    if attr in self.__dict__:
      return self.__dict__[attr]

    res = getattr(self.wrapped, attr)
    if not hasattr(res, '__call__'):
      return res
    def wrapper(*args, **kwargs):
      tries_left = 3
      while tries_left:
        # clear exception state so our re-raise can't reraise something
        # old. This isn't strictly necessary, but feels safer.
        sys.exc_clear()
        try:
          if not self.transport.isOpen():
            self.transport.open()
          st = time.time()
          logging.debug("Thrift call: %s.%s(args=%s, kwargs=%s)"
            % (str(self.wrapped.__class__), attr, repr(args), repr(kwargs)))
          ret = res(*args, **kwargs)
          log_msg = repr(ret)
          if len(log_msg) > 1000:
            log_msg = log_msg[0:1000] + "..."
          duration = time.time() - st

          # Log the duration at different levels, depending on how long
          # it took.
          logmsg = "Thrift call %s.%s returned in %dms: %s" % (
            str(self.wrapped.__class__), attr, duration*1000, log_msg)
          if duration >= WARN_LEVEL_CALL_DURATION_MS:
            logging.warn(logmsg)
          elif duration >= INFO_LEVEL_CALL_DURATION_MS:
            logging.info(logmsg)
          else:
            logging.debug(logmsg)

          return ret
        except socket.error, e:
          pass
        except TTransportException, e:
          pass
        except Exception, e:
          logging.exception("Thrift saw exception (this may be expected).")
          raise
        self.transport.close()

        if isinstance(e, socket.timeout):
          logging.warn("Not retrying thrift call %s due to socket timeout" % attr)
          raise
        else:
          tries_left -= 1
          if tries_left:
            logging.info("Thrift exception; retrying: " + str(e), exc_info=0)
      logging.warn("Out of retries for thrift call: " + attr)
      raise
    return wrapper
dataset/ETHPy150Open cloudera/hue/desktop/core/src/desktop/lib/thrift_util.py/SuperClient.__getattr__/original