def _select_server(self, server_selector, session, address=None):
        """Select a server to run an operation on this client.

        :Parameters:
          - `server_selector`: The server selector to use if the session is
            not pinned and no address is given.
          - `session`: The ClientSession for the next operation, or None. May
            be pinned to a mongos server address.
          - `address` (optional): Address when sending a message
            to a specific server, used for getMore.
        """
        try:
            topology = self._get_topology()
            address = address or (session and session._pinned_address)
            if address:
                # We're running a getMore or this session is pinned to a mongos.
                server = topology.select_server_by_address(address)
                if not server:
                    raise AutoReconnect('server %s:%d no longer available'
                                        % address)
            else:
                server = topology.select_server(server_selector)
                # Pin this session to the selected server if it's performing a
                # sharded transaction.
                if server.description.mongos and (session and
                                                  session._in_transaction):
                    session._pin_mongos(server)
            return server
        except PyMongoError as exc:
            if session and exc.has_error_label("TransientTransactionError"):
                session._unpin_mongos()
            raise
Select a server to run an operation on this client.

        :Parameters:
          - `server_selector`: The server selector to use if the session is
            not pinned and no address is given.
          - `session`: The ClientSession for the next operation, or None. May
            be pinned to a mongos server address.
          - `address` (optional): Address when sending a message
            to a specific server, used for getMore.