Send a canned reply to all matching client requests.
        
        ``matcher`` is a `Matcher` or a command name, or an instance of
        `OpInsert`, `OpQuery`, etc.

        >>> s = MockupDB()
        >>> port = s.run()
        >>>
        >>> from pymongo import MongoClient
        >>> client = MongoClient(s.uri)
        >>> responder = s.autoresponds('ismaster', maxWireVersion=6)
        >>> client.admin.command('ismaster') == {'ok': 1, 'maxWireVersion': 6}
        True

        The remaining arguments are a :ref:`message spec <message spec>`:

        >>> # ok
        >>> responder = s.autoresponds('bar', ok=0, errmsg='err')
        >>> client.db.command('bar')
        Traceback (most recent call last):
        ...
        OperationFailure: command SON([('bar', 1)]) on namespace db.$cmd failed: err
        >>> responder = s.autoresponds(OpMsg('find', 'collection'),
        ...                            {'cursor': {'id': 0, 'firstBatch': [{'_id': 1}, {'_id': 2}]}})
        >>> # ok
        >>> list(client.db.collection.find()) == [{'_id': 1}, {'_id': 2}]
        True
        >>> responder = s.autoresponds(OpMsg('find', 'collection'),
        ...                            {'cursor': {'id': 0, 'firstBatch': [{'a': 1}, {'a': 2}]}})
        >>> # bad
        >>> list(client.db.collection.find()) == [{'a': 1}, {'a': 2}]
        True

        Remove an autoresponder like:

        >>> responder.cancel()

        If the request currently at the head of the queue matches, it is popped
        and replied to. Future matching requests skip the queue.

        >>> future = go(client.db.command, 'baz')
        >>> # bad
        >>> responder = s.autoresponds('baz', {'key': 'value'})
        >>> future() == {'ok': 1, 'key': 'value'}
        True

        Responders are applied in order, most recently added first, until one
        matches:

        >>> responder = s.autoresponds('baz')
        >>> client.db.command('baz') == {'ok': 1}
        True
        >>> responder.cancel()
        >>> # The previous responder takes over again.
        >>> client.db.command('baz') == {'ok': 1, 'key': 'value'}
        True

        You can pass a request handler in place of the message spec. Return
        True if you handled the request:

        >>> responder = s.autoresponds('baz', lambda r: r.ok(a=2))

        The standard `Request.ok`, `~Request.replies`, `~Request.fail`,
        `~Request.hangup` and so on all return True to make them suitable
        as handler functions.

        >>> client.db.command('baz') == {'ok': 1, 'a': 2}
        True

        If the request is not handled, it is checked against the remaining
        responders, or enqueued if none match.

        You can pass the handler as the only argument so it receives *all*
        requests. For example you could log them, then return None to allow
        other handlers to run:

        >>> def logger(request):
        ...     if not request.matches('ismaster'):
        ...         print('logging: %r' % request)
        >>> responder = s.autoresponds(logger)
        >>> client.db.command('baz') == {'ok': 1, 'a': 2}
        logging: OpMsg({"baz": 1, "$db": "db", "$readPreference": {"mode": "primaryPreferred"}}, namespace="db")
        True

        The synonym `subscribe` better expresses your intent if your handler
        never returns True:

        >>> subscriber = s.subscribe(logger)

        .. doctest:
            :hide:

            >>> client.close()
            >>> s.stop()

def autoresponds(self, matcher, *args, **kwargs):
        """Send a canned reply to all matching client requests.
        
        ``matcher`` is a `Matcher` or a command name, or an instance of
        `OpInsert`, `OpQuery`, etc.

        >>> s = MockupDB()
        >>> port = s.run()
        >>>
        >>> from pymongo import MongoClient
        >>> client = MongoClient(s.uri)
        >>> responder = s.autoresponds('ismaster', maxWireVersion=6)
        >>> client.admin.command('ismaster') == {'ok': 1, 'maxWireVersion': 6}
        True

        The remaining arguments are a :ref:`message spec <message spec>`:

        >>> # ok
        >>> responder = s.autoresponds('bar', ok=0, errmsg='err')
        >>> client.db.command('bar')
        Traceback (most recent call last):
        ...
        OperationFailure: command SON([('bar', 1)]) on namespace db.$cmd failed: err
        >>> responder = s.autoresponds(OpMsg('find', 'collection'),
        ...                            {'cursor': {'id': 0, 'firstBatch': [{'_id': 1}, {'_id': 2}]}})
        >>> # ok
        >>> list(client.db.collection.find()) == [{'_id': 1}, {'_id': 2}]
        True
        >>> responder = s.autoresponds(OpMsg('find', 'collection'),
        ...                            {'cursor': {'id': 0, 'firstBatch': [{'a': 1}, {'a': 2}]}})
        >>> # bad
        >>> list(client.db.collection.find()) == [{'a': 1}, {'a': 2}]
        True

        Remove an autoresponder like:

        >>> responder.cancel()

        If the request currently at the head of the queue matches, it is popped
        and replied to. Future matching requests skip the queue.

        >>> future = go(client.db.command, 'baz')
        >>> # bad
        >>> responder = s.autoresponds('baz', {'key': 'value'})
        >>> future() == {'ok': 1, 'key': 'value'}
        True

        Responders are applied in order, most recently added first, until one
        matches:

        >>> responder = s.autoresponds('baz')
        >>> client.db.command('baz') == {'ok': 1}
        True
        >>> responder.cancel()
        >>> # The previous responder takes over again.
        >>> client.db.command('baz') == {'ok': 1, 'key': 'value'}
        True

        You can pass a request handler in place of the message spec. Return
        True if you handled the request:

        >>> responder = s.autoresponds('baz', lambda r: r.ok(a=2))

        The standard `Request.ok`, `~Request.replies`, `~Request.fail`,
        `~Request.hangup` and so on all return True to make them suitable
        as handler functions.

        >>> client.db.command('baz') == {'ok': 1, 'a': 2}
        True

        If the request is not handled, it is checked against the remaining
        responders, or enqueued if none match.

        You can pass the handler as the only argument so it receives *all*
        requests. For example you could log them, then return None to allow
        other handlers to run:

        >>> def logger(request):
        ...     if not request.matches('ismaster'):
        ...         print('logging: %r' % request)
        >>> responder = s.autoresponds(logger)
        >>> client.db.command('baz') == {'ok': 1, 'a': 2}
        logging: OpMsg({"baz": 1, "$db": "db", "$readPreference": {"mode": "primaryPreferred"}}, namespace="db")
        True

        The synonym `subscribe` better expresses your intent if your handler
        never returns True:

        >>> subscriber = s.subscribe(logger)

        .. doctest:
            :hide:

            >>> client.close()
            >>> s.stop()
        """
        return self._insert_responder("top", matcher, *args, **kwargs)