def _retryable_read(self, func, read_pref, session, address=None,
                        retryable=True, exhaust=False):
        """Execute an operation with at most one consecutive retries

        Returns func()'s return value on success. On error retries the same
        command once.

        Re-raises any exception thrown by func().
        """
        retryable = (retryable and
                     self.retry_reads
                     and not (session and session._in_transaction))
        last_error = None
        retrying = False

        while True:
            try:
                server = self._select_server(
                    read_pref, session, address=address)
                if not server.description.retryable_reads_supported:
                    retryable = False
                with self._slaveok_for_server(read_pref, server, session,
                                              exhaust=exhaust) as (sock_info,
                                                                   slave_ok):
                    if retrying and not retryable:
                        # A retry is not possible because this server does
                        # not support retryable reads, raise the last error.
                        raise last_error
                    return func(session, server, sock_info, slave_ok)
            except ServerSelectionTimeoutError:
                if retrying:
                    # The application may think the write was never attempted
                    # if we raise ServerSelectionTimeoutError on the retry
                    # attempt. Raise the original exception instead.
                    raise last_error
                # A ServerSelectionTimeoutError error indicates that there may
                # be a persistent outage. Attempting to retry in this case will
                # most likely be a waste of time.
                raise
            except ConnectionFailure as exc:
                if not retryable or retrying:
                    raise
                retrying = True
                last_error = exc
            except OperationFailure as exc:
                if not retryable or retrying:
                    raise
                if exc.code not in helpers._RETRYABLE_ERROR_CODES:
                    raise
                retrying = True
                last_error = exc
Execute an operation with at most one consecutive retries

        Returns func()'s return value on success. On error retries the same
        command once.

        Re-raises any exception thrown by func().
        
stackoverflow/venv/lib/python3.6/site-packages/pymongo/mongo_client.py