Generates and returns a callable suitable for passing as the
        ``protocol_factory`` parameter of the ``create_connection()``
        or ``create_server()`` loop methods.  This class method
        performs some sanity checks on the arguments, and is preferred
        over using a manually constructed ``lambda``.

        The first argument must be a protocol factory for a
        ``FramedProtocol`` object.  Subsequent positional and keyword
        arguments are interpreted as for the ``set_framer()`` method,
        which the proviso that both send and receive framers must be
        set after argument interpretation.

        :returns: A callable that returns an instance of
                  ``FramerProtocol``.

def factory(cls, client, *args, **kwargs):
        """
        Generates and returns a callable suitable for passing as the
        ``protocol_factory`` parameter of the ``create_connection()``
        or ``create_server()`` loop methods.  This class method
        performs some sanity checks on the arguments, and is preferred
        over using a manually constructed ``lambda``.

        The first argument must be a protocol factory for a
        ``FramedProtocol`` object.  Subsequent positional and keyword
        arguments are interpreted as for the ``set_framer()`` method,
        which the proviso that both send and receive framers must be
        set after argument interpretation.

        :returns: A callable that returns an instance of
                  ``FramerProtocol``.
        """

        # Some basic sanity checks
        if not six.callable(client):
            raise exc.FramerException("Protocol factory is not a factory")

        # Cannot specify both positional and keyword arguments, but
        # must provide one or the other
        if not args and not kwargs:
            raise exc.InvalidFramerSpecification(
                "No framers specified")
        elif args and kwargs:
            raise exc.InvalidFramerSpecification(
                "Cannot mix positional and keyword framer specifications")

        # And a final, basic sanity check on the argument structure
        if not args and ('send' not in kwargs or 'recv' not in kwargs):
            raise exc.InvalidFramerSpecification(
                "Both send and receive framers must be specified")

        return lambda: cls(client, *args, **kwargs)