Set and automatically clear a lock

def gen_lock(self, lock_type='update', timeout=0, poll_interval=0.5):
        '''
        Set and automatically clear a lock
        '''
        if not isinstance(lock_type, six.string_types):
            raise GitLockError(
                errno.EINVAL,
                'Invalid lock_type \'{0}\''.format(lock_type)
            )

        # Make sure that we have a positive integer timeout, otherwise just set
        # it to zero.
        try:
            timeout = int(timeout)
        except ValueError:
            timeout = 0
        else:
            if timeout < 0:
                timeout = 0

        if not isinstance(poll_interval, (six.integer_types, float)) \
                or poll_interval < 0:
            poll_interval = 0.5

        if poll_interval > timeout:
            poll_interval = timeout

        lock_set = False
        try:
            time_start = time.time()
            while True:
                try:
                    self._lock(lock_type=lock_type, failhard=True)
                    lock_set = True
                    yield
                    # Break out of his loop once we've yielded the lock, to
                    # avoid continued attempts to iterate and establish lock
                    break
                except (OSError, IOError, GitLockError) as exc:
                    if not timeout or time.time() - time_start > timeout:
                        raise GitLockError(exc.errno, exc.strerror)
                    else:
                        log.debug(
                            'A %s lock is already present for %s remote '
                            '\'%s\', sleeping %f second(s)',
                            lock_type, self.role, self.id, poll_interval
                        )
                        time.sleep(poll_interval)
                        continue
        finally:
            if lock_set:
                self.clear_lock(lock_type=lock_type)